2011-09-10 12 views
12

Digamos que tiene una función loco, f, que se define así:NMinimize parece ser en la grieta

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] 

Ahora me llaman NMinimize así:

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

¿Qué me dice esto:

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

Pero si realmente compruebo qué es f[50,50,49,51], es esto:

0.489033 

Que es bastante diferente del -21.0465 que dijo NMinimize. ¿Esto es parte del curso con NMinimize? ¿Compensación de errores de punto flotante o qué? ¿Alguna idea para derrotar NMinimize (o alguna de esas funciones) en el envío?

+4

+1 por el título – Verbeia

Respuesta

17

Ciertamente parece estar relacionado con su función f que no está restringida a argumentos numéricos, más el preprocesamiento simbólico realizado por NMinimize. Una vez que cambie la firma a

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

El resultado es el esperado, aunque lleva mucho más tiempo obtenerlo.

EDITAR

Podemos profundizar más para revelar la verdadera razón. En primer lugar, tenga en cuenta que su f (el original, args sin restricciones) es bastante una función:

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 

El verdadero culpable es NSolve, lo que da dos soluciones ordenadas:

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])}} 

El problema es , ¿cuál es el orden? Resulta ser diferente para argumentos simbólicos y numéricos a NSolve, porque en este último caso no tenemos ningún símbolo alrededor. Esto puede ser visto como:

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 

Por lo que realmente tienen que conformarse en lo que es el orden correcto para usted, y cuál es la solución que realmente quiere recoger.

+1

¡Guau, buen descubrimiento al detectar ese problema con NSolve! Gracias Leonid! – dreeves

+0

@dreeves Daniel, me alegro de poder ayudar. Por algún tiempo, estaba bastante desconcertado, no tenía idea antes de que esto pudiera suceder. –

+0

FYI, 51 y 49 están al revés en 'In [1400]' (¡pero obtienes el mismo resultado!) – JxB

Cuestiones relacionadas