Esta página aún no se ha traducido para esta versión. Puede ver la versión más reciente de esta página en inglés.

Función de banana minimización

Este ejemplo muestra cómo minimizar la "función banana" de Rosenbrock:

<math display="block">
<mrow>
<mi>f</mi>
<mo stretchy="false">(</mo>
<mi>x</mi>
<mo stretchy="false">)</mo>
<mo>=</mo>
<mn>1</mn>
<mn>0</mn>
<mn>0</mn>
<mo stretchy="false">(</mo>
<mi>x</mi>
<mo stretchy="false">(</mo>
<mn>2</mn>
<mo stretchy="false">)</mo>
<mo>-</mo>
<mi>x</mi>
<mo stretchy="false">(</mo>
<mn>1</mn>
<msup>
<mrow>
<mo stretchy="false">)</mo>
</mrow>
<mrow>
<mn>2</mn>
</mrow>
</msup>
<msup>
<mrow>
<mo stretchy="false">)</mo>
</mrow>
<mrow>
<mn>2</mn>
</mrow>
</msup>
<mo>+</mo>
<mo stretchy="false">(</mo>
<mn>1</mn>
<mo>-</mo>
<mi>x</mi>
<mo stretchy="false">(</mo>
<mn>1</mn>
<mo stretchy="false">)</mo>
<msup>
<mrow>
<mo stretchy="false">)</mo>
</mrow>
<mrow>
<mn>2</mn>
</mrow>
</msup>
<mo>.</mo>
</mrow>
</math>

<math display="block">
<mrow>
<mi>f</mi>
<mo stretchy="false">(</mo>
<mi>x</mi>
<mo stretchy="false">)</mo>
</mrow>
</math>
se llama la función banana debido a su curvatura alrededor del origen. Es notorio en los ejemplos de optimización debido a la convergencia lenta que la mayoría de los métodos exhiben al tratar de resolver este problema.

<math display="block">
<mrow>
<mi>f</mi>
<mo stretchy="false">(</mo>
<mi>x</mi>
<mo stretchy="false">)</mo>
</mrow>
</math>
tiene un mínimo único en el punto
<math display="block">
<mrow>
<mi>x</mi>
<mo>=</mo>
<mo stretchy="false">[</mo>
<mn>1</mn>
<mo>,</mo>
<mn>1</mn>
<mo stretchy="false">]</mo>
</mrow>
</math>
Dónde
<math display="block">
<mrow>
<mi>f</mi>
<mo stretchy="false">(</mo>
<mi>x</mi>
<mo stretchy="false">)</mo>
<mo>=</mo>
<mn>0</mn>
</mrow>
</math>
. Este ejemplo muestra varias maneras de minimizar
<math display="block">
<mrow>
<mi>f</mi>
<mo stretchy="false">(</mo>
<mi>x</mi>
<mo stretchy="false">)</mo>
</mrow>
</math>
comenzando en el punto
<math display="block">
<mrow>
<mi>x</mi>
<mn>0</mn>
<mo>=</mo>
<mo stretchy="false">[</mo>
<mo>-</mo>
<mn>1</mn>
<mo>.</mo>
<mn>9</mn>
<mo>,</mo>
<mn>2</mn>
<mo stretchy="false">]</mo>
</mrow>
</math>
.

Optimización sin derivados

La función encuentra un mínimo para un problema sin restricciones.fminsearch Utiliza un algoritmo que no estima ninguna derivada de la función objetiva. Más bien, utiliza un método de búsqueda geométrica descrito en.Algoritmofminsearch

Minimice la función banana usando.fminsearch Incluya una función de salida para notificar la secuencia de iteraciones.

fun = @(x)(100*(x(2) - x(1)^2)^2 + (1 - x(1))^2); options = optimset('OutputFcn',@bananaout,'Display','off'); x0 = [-1.9,2]; [x,fval,eflag,output] = fminsearch(fun,x0,options); title 'Rosenbrock solution via fminsearch'

Fcount = output.funcCount; disp(['Number of function evaluations for fminsearch was ',num2str(Fcount)])
Number of function evaluations for fminsearch was 210 
disp(['Number of solver iterations for fminsearch was ',num2str(output.iterations)])
Number of solver iterations for fminsearch was 114 

Optimización con derivados estimados

La función encuentra un mínimo para un problema sin restricciones.fminunc Utiliza un algoritmo basado en derivaciones. El algoritmo intenta estimar no sólo la primera derivada de la función objetiva, sino también la matriz de segundas derivadas. suele ser más eficiente que.fminuncfminsearch

Minimice la función banana usando.fminunc

options = optimoptions('fminunc','Display','off',...     'OutputFcn',@bananaout,'Algorithm','quasi-newton'); [x,fval,eflag,output] = fminunc(fun,x0,options); title 'Rosenbrock solution via fminunc'

Fcount = output.funcCount; disp(['Number of function evaluations for fminunc was ',num2str(Fcount)])
Number of function evaluations for fminunc was 150 
disp(['Number of solver iterations for fminunc was ',num2str(output.iterations)])
Number of solver iterations for fminunc was 34 

Optimización con descenso más empen

Si intenta minimizar la función de plátano utilizando un algoritmo de descenso más inclinado, la alta curvatura del problema hace que el proceso de solución sea muy lento.

Puede ejecutar con el algoritmo de descenso más inclinado estableciendo la opción oculta en el valor del algoritmo.fminuncHessUpdate'steepdesc''quasi-newton' Establezca un número máximo mayor que el predeterminado de evaluaciones de función, porque el solucionador no encuentra la solución rápidamente. En este caso, el solucionador no encuentra la solución incluso después de 600 evaluaciones de función.

options = optimoptions(options,'HessUpdate','steepdesc',...     'MaxFunctionEvaluations',600); [x,fval,eflag,output] = fminunc(fun,x0,options); title 'Rosenbrock solution via steepest descent'

Fcount = output.funcCount; disp(['Number of function evaluations for steepest descent was ',...     num2str(Fcount)])
Number of function evaluations for steepest descent was 600 
disp(['Number of solver iterations for steepest descent was ',...     num2str(output.iterations)])
Number of solver iterations for steepest descent was 45 

Optimización con gradiente analítico

Si proporciona un degradado, resuelve la optimización con menos evaluaciones de funciones.fminunc Cuando se proporciona un degradado, puede utilizar el algoritmo, que es a menudo más rápido y utiliza menos memoria que el algoritmo.'trust-region''quasi-newton' Restablezca las opciones y sus valores predeterminados.HessUpdateMaxFunctionEvaluations

grad = @(x)[-400*(x(2) - x(1)^2)*x(1) - 2*(1 - x(1));             200*(x(2) - x(1)^2)]; fungrad = @(x)deal(fun(x),grad(x)); options = resetoptions(options,{'HessUpdate','MaxFunctionEvaluations'}); options = optimoptions(options,'SpecifyObjectiveGradient',true,...     'Algorithm','trust-region'); [x,fval,eflag,output] = fminunc(fungrad,x0,options); title 'Rosenbrock solution via fminunc with gradient'

Fcount = output.funcCount; disp(['Number of function evaluations for fminunc with gradient was ',...     num2str(Fcount)])
Number of function evaluations for fminunc with gradient was 32 
disp(['Number of solver iterations for fminunc with gradient was ',...     num2str(output.iterations)])
Number of solver iterations for fminunc with gradient was 31 

Optimización con hessian analítico

Si proporciona un hessian (matriz de segundas derivadas), puede resolver la optimización utilizando aún menos evaluaciones de funciones.fminunc Para este problema los resultados son los mismos con o sin el hessian.

hess = @(x)[1200*x(1)^2 - 400*x(2) + 2, -400*x(1);             -400*x(1), 200]; fungradhess = @(x)deal(fun(x),grad(x),hess(x)); options.HessianFcn = 'objective'; [x,fval,eflag,output] = fminunc(fungradhess,x0,options); title 'Rosenbrock solution via fminunc with Hessian'

Fcount = output.funcCount; disp(['Number of function evaluations for fminunc with gradient and Hessian was ',...     num2str(Fcount)])
Number of function evaluations for fminunc with gradient and Hessian was 32 
disp(['Number of solver iterations for fminunc with gradient and Hessian was ',num2str(output.iterations)])
Number of solver iterations for fminunc with gradient and Hessian was 31 

Optimización con un solucionador de mínimos cuadrados

El solucionador recomendado para una suma de cuadrados no lineales es.lsqnonlin Este solucionador es aún más eficiente que sin un degradado para esta clase especial de problemas.fminunc Para usar, no escribas tu objetivo como una suma de cuadrados.lsqnonlin En su lugar, escriba el vector subyacente que internamente cuadrados y sumas.lsqnonlin

options = optimoptions('lsqnonlin','Display','off','OutputFcn',@bananaout); vfun = @(x)[10*(x(2) - x(1)^2),1 - x(1)]; [x,resnorm,residual,eflag,output] = lsqnonlin(vfun,x0,[],[],options); title 'Rosenbrock solution via lsqnonlin'

Fcount = output.funcCount; disp(['Number of function evaluations for lsqnonlin was ',...     num2str(Fcount)])
Number of function evaluations for lsqnonlin was 87 
disp(['Number of solver iterations for lsqnonlin was ',num2str(output.iterations)])
Number of solver iterations for lsqnonlin was 28 

Optimización con un solucionador de mínimos cuadrados y

Como en la minimización utilizando un degradado para, puede utilizar información derivada para reducir el número de evaluaciones de función.fminunclsqnonlin Proporcione el jacobiano del vector de función objetiva no lineal y vuelva a ejecutar la optimización.

jac = @(x)[-20*x(1),10;            -1,0]; vfunjac = @(x)deal(vfun(x),jac(x)); options.SpecifyObjectiveGradient = true; [x,resnorm,residual,eflag,output] = lsqnonlin(vfunjac,x0,[],[],options); title 'Rosenbrock solution via lsqnonlin with Jacobian'

Fcount = output.funcCount; disp(['Number of function evaluations for lsqnonlin with Jacobian was ',...     num2str(Fcount)])
Number of function evaluations for lsqnonlin with Jacobian was 29 
disp(['Number of solver iterations for lsqnonlin with Jacobian was ',...     num2str(output.iterations)])
Number of solver iterations for lsqnonlin with Jacobian was 28