NMinimize似乎正在破裂

dre*_*ves 12 wolfram-mathematica mathematical-optimization

假设我有一个疯狂的功能f,定义如下:

util[x_, y_, c_] := 0.5*Log[c-x] + 0.5*Log[c-y]
cost[x_, y_, l_] := c /. First[NSolve[util[x, y, c+l] == Log[10+l], c]]
prof[x_, y_]   := 0.01*Norm[{x,y}, 2]
liquid[x_, y_] := 0.01*Norm[{x,y}, 2]
f[x_, y_, a_, b_] := cost[a, b, liquid[x,y] + liquid[a-x, b-y]] - Max[a,b] 
      - cost[0,0,0] + prof[x,y] + liquid[x,y] + prof[a-x, b-y] + liquid[a-x, b-y]
Run Code Online (Sandbox Code Playgroud)

现在我这样打电话NMinimize:

NMinimize[{f[50, 50, k, j], k >= 49, k <= 51, j >= 49, j <= 51}, {j, k}]
Run Code Online (Sandbox Code Playgroud)

这告诉我这个:

{-21.0465, {j -> 51., k -> 49.}}
Run Code Online (Sandbox Code Playgroud)

但是如果我真的检查是什么f[50,50,49,51],那就是:

0.489033
Run Code Online (Sandbox Code Playgroud)

这与NMinimize所说的-21.0465有很大的不同.这与NMinimize的课程相提并论吗?浮点错误复合或诸如此类?将NMinimize(或某些此类功能)击败提交的任何想法?

Leo*_*rin 17

它当然似乎与您的函数f不仅限于数字参数,以及由...执行的符号预处理有关NMinimize.将签名更改为

f[x_?NumericQ, y_?NumericQ, a_?NumericQ, b_?NumericQ]:=...
Run Code Online (Sandbox Code Playgroud)

结果如预期,虽然它需要相当长的时间.

编辑

我们可以深入挖掘,揭示真正的原因.首先,请注意您的f(原始的,args不受限制)是一个功能:

In[1423]:= f[50,50,49.,51.]
Out[1423]= 0.489033

In[1392]:= f[50,50,k,j]/.{j->51.`,k->49.`}
Out[1392]= -21.0465
Run Code Online (Sandbox Code Playgroud)

真正的罪魁祸首是NSolve,它提供了两个有序的解决方案:

In[1398]:= NSolve[util[x,y,c+l]==Log[10+l],c]
Out[1398]= {{c->0.5 (-2. l+1. x+1. y-2. Sqrt[100.+20. l+1. l^2+0.25 x^2-0.5 x y+0.25 y^2])},
 {c->0.5 (-2. l+1. x+1. y+2. Sqrt[100.+20. l+1. l^2+0.25 x^2-0.5 x y+0.25 y^2])}}
Run Code Online (Sandbox Code Playgroud)

问题是,订单是什么.事实证明,符号和数字参数不同NSolve,因为在后一种情况下,我们没有任何符号.这可以看作:

In[1399]:= 
Block[{cost},
   cost[x_,y_,l_]:=c/.Last[NSolve[util[x,y,c+l]==Log[10+l],c]];
   f[50,50,k,j]/.{j->51.,k->49.}]

Out[1399]= 0.489033
Run Code Online (Sandbox Code Playgroud)

所以你真的必须找到适合你的订单,以及你真正想要选择哪种解决方案.