NMinimize, кажется, на трещине - PullRequest
       17

NMinimize, кажется, на трещине

12 голосов
/ 10 сентября 2011

Скажем, у меня есть сумасшедшая функция, 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]

Теперь я называю NMinimize так:

NMinimize[{f[50, 50, k, j], k >= 49, k <= 51, j >= 49, j <= 51}, {j, k}]

, которая говорит мне следующее:

{-21.0465, {j -> 51., k -> 49.}}

Но тогда, если я действительно проверю, что такое f[50,50,49,51], то это:

0.489033

Что довольно сильно отличается от -21.0465, который сказал NMinimize.Является ли это нормой для курса с NMinimize?Составление ошибок с плавающей точкой или еще много чего?Любые идеи для избиения NMinimize (или некоторые такие функции) в подчинение?

1 Ответ

17 голосов
/ 10 сентября 2011

Очевидно, что это связано с тем, что ваша функция f не ограничена числовыми аргументами, плюс символическая предварительная обработка, выполняемая NMinimize.Как только вы измените подпись на

f[x_?NumericQ, y_?NumericQ, a_?NumericQ, b_?NumericQ]:=...

Результат будет таким, как ожидалось, хотя его получение займет значительно больше времени.

РЕДАКТИРОВАТЬ

Мыможет копать глубже, чтобы раскрыть истинную причину.Во-первых, обратите внимание, что ваш f (исходный, аргументы неограничены) вполне функция:

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

Реальный виновник - 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])}}

Проблема в том, каков порядок.Оказывается, он отличается для символьных и числовых аргументов от 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

Так что вам действительно нужно определиться с тем, какой заказ вам подходит, и какое решение вы действительно хотите выбрать.

...