我试图在R中使用optim得到函数最小值,问题是方法返回的par解决方案不正确,如果我引入了不同的初始点则会改变。我将向您展示一些代码和输出。我错过了什么?
> funx = function(vx) (vx[1] -2)^4 + (vx[1]-2*vx[2])^2 + -10/(vx[1]^2-vx[2])
> optim(c(0,1), funx)
$par
[1] 0.7080021 1.5315815
$value
[1] 18.03898
$counts
function gradient
61 NA
$convergence
[1] 0
$message
NULL
> optim(c(0,3), funx)
$par
[1] 1.271924 1.617791
$value
[1] -4.5036e+16
$counts
function gradient
237 NA
$convergence
[1] 0
$message
NULL
> funx(c(1.271924, 1.617791))
[1] 29566209
实际上,这是一个四舍五入的问题。如果你将确切的值反馈回funx()
,你会得到一个小的(即非常负的)值:如果你舍入到六位数,你得到一个很大的值。
oo <-optim(c(0,3), funx)
funx(oo$par)
## [1] -4.5036e+16
funx(round(oo$par,6))
## [1] 29566209
这确实是一种不良行为,您可能需要在使用它时考虑到这一点。 (我也强烈建议使用基于导数的优化,自己计算衍生物或使用deriv()
。)
例如,您可以在optim中添加method =“L-BFGS-B”,并根据函数的定义定义参数的上限和下限。它可能会产生原始间隔的值。