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.

Tutorial para la caja de herramientas de optimización™

Este ejemplo muestra cómo utilizar dos solucionadores de optimización no lineales y cómo establecer opciones. Los solucionadores no lineales que usamos en este ejemplo son y.fminuncfmincon

Todos los principios descritos en este ejemplo se aplican a los demás solucionadores no lineales, como,,, y.fgoalattainfminimaxlsqnonlinlsqcurvefitfsolve

El ejemplo comienza con la minimización de una función objetiva, luego procede a minimizar la misma función con parámetros adicionales. Después de eso, el ejemplo muestra cómo minimizar la función objetiva cuando hay una restricción, y finalmente muestra cómo obtener una solución más eficiente y/o precisa al proporcionar gradientes o hessian, o cambiando algunas opciones.

Ejemplo de optimización sin restricciones

Considere el problema de encontrar un mínimo de la función:

<math display="block">
<mrow>
<mi>x</mi>
<mi mathvariant="normal">exp</mi>
<mo stretchy="false">(</mo>
<mo>-</mo>
<mo stretchy="false">(</mo>
<msup>
<mrow>
<mi>x</mi>
</mrow>
<mrow>
<mn>2</mn>
</mrow>
</msup>
<mo>+</mo>
<msup>
<mrow>
<mi>y</mi>
</mrow>
<mrow>
<mn>2</mn>
</mrow>
</msup>
<mo stretchy="false">)</mo>
<mo stretchy="false">)</mo>
<mo>+</mo>
<mo stretchy="false">(</mo>
<msup>
<mrow>
<mi>x</mi>
</mrow>
<mrow>
<mn>2</mn>
</mrow>
</msup>
<mo>+</mo>
<msup>
<mrow>
<mi>y</mi>
</mrow>
<mrow>
<mn>2</mn>
</mrow>
</msup>
<mo stretchy="false">)</mo>
<mo>/</mo>
<mn>2</mn>
<mn>0</mn>
<mo>.</mo>
</mrow>
</math>

Trace la función para tener una idea de dónde se minimiza

f = @(x,y) x.*exp(-x.^2-y.^2)+(x.^2+y.^2)/20; fsurf(f,[-2,2],'ShowContours','on')

La gráfica muestra que el mínimo está cerca del punto (-1/2, 0).

Normalmente se define la función objetiva como un archivo MATLAB. Por ahora, esta función es lo suficientemente simple como para definirla como una función anónima:

fun = @(x) f(x(1),x(2));

Tome una suposición en la solución:

x0 = [-.5; 0];

Establecer opciones de optimización para no utilizar el algoritmo de gran escala por defecto, ya que ese algoritmo requiere el gradiente de la función objetivo que se proporcionará:fminunc

options = optimoptions('fminunc','Algorithm','quasi-newton');

Ver las iteraciones mientras el solucionador calcula:

options.Display = 'iter';

Llamada, un minimizador no lineal sin restricciones:fminunc

[x, fval, exitflag, output] = fminunc(fun,x0,options);
                                                        First-order   Iteration  Func-count       f(x)        Step-size       optimality      0           3          -0.3769                         0.339      1           6        -0.379694              1          0.286        2           9        -0.405023              1         0.0284        3          12        -0.405233              1        0.00386        4          15        -0.405237              1       3.17e-05        5          18        -0.405237              1       3.35e-08    Local minimum found.  Optimization completed because the size of the gradient is less than the value of the optimality tolerance. 

El solucionador encontró una solución en:

uncx = x
uncx = 2×1

   -0.6691
    0.0000

El valor de la función en la solución es:

uncf = fval
uncf = -0.4052 

Usaremos el número de evaluaciones de funciones como medida de eficiencia en este ejemplo. El número total de evaluaciones de funciones es:

output.funcCount
ans = 18 

Optimización sin restricciones con parámetros adicionales

Ahora pasaremos parámetros extra como argumentos adicionales a la función objetiva. Mostramos dos maneras diferentes de hacer esto-usando un archivo MATLAB, o usando una función anidada.

Considere la función objetiva de la sección anterior:

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

Parametrizamos la función con (a, b, c) de la siguiente manera:

<math display="block">
<mrow>
<mi>f</mi>
<mo stretchy="false">(</mo>
<mi>x</mi>
<mo>,</mo>
<mi>y</mi>
<mo>,</mo>
<mi>a</mi>
<mo>,</mo>
<mi>b</mi>
<mo>,</mo>
<mi>c</mi>
<mo stretchy="false">)</mo>
<mo>=</mo>
<mo stretchy="false">(</mo>
<mi>x</mi>
<mo>-</mo>
<mi>a</mi>
<mo stretchy="false">)</mo>
<mi mathvariant="normal">exp</mi>
<mo stretchy="false">(</mo>
<mo>-</mo>
<mo stretchy="false">(</mo>
<mo stretchy="false">(</mo>
<mi>x</mi>
<mo>-</mo>
<mi>a</mi>
<msup>
<mrow>
<mo stretchy="false">)</mo>
</mrow>
<mrow>
<mn>2</mn>
</mrow>
</msup>
<mo>+</mo>
<mo stretchy="false">(</mo>
<mi>y</mi>
<mo>-</mo>
<mi>b</mi>
<msup>
<mrow>
<mo stretchy="false">)</mo>
</mrow>
<mrow>
<mn>2</mn>
</mrow>
</msup>
<mo stretchy="false">)</mo>
<mo stretchy="false">)</mo>
<mo>+</mo>
<mo stretchy="false">(</mo>
<mo stretchy="false">(</mo>
<mi>x</mi>
<mo>-</mo>
<mi>a</mi>
<msup>
<mrow>
<mo stretchy="false">)</mo>
</mrow>
<mrow>
<mn>2</mn>
</mrow>
</msup>
<mo>+</mo>
<mo stretchy="false">(</mo>
<mi>y</mi>
<mo>-</mo>
<mi>b</mi>
<msup>
<mrow>
<mo stretchy="false">)</mo>
</mrow>
<mrow>
<mn>2</mn>
</mrow>
</msup>
<mo stretchy="false">)</mo>
<mo>/</mo>
<mi>c</mi>
<mo>.</mo>
</mrow>
</math>

Esta función es una versión desplazada y ajustada de la función objetiva original.

Método 1: Archivo MATLAB function

Supongamos que tenemos una función de objetivo de archivo MATLAB llamada definida como:bowlpeakfun

type bowlpeakfun
function y = bowlpeakfun(x, a, b, c) %BOWLPEAKFUN Objective function for parameter passing in TUTDEMO.  %   Copyright 2008 The MathWorks, Inc.  y = (x(1)-a).*exp(-((x(1)-a).^2+(x(2)-b).^2))+((x(1)-a).^2+(x(2)-b).^2)/c; 

Defina los parámetros:

a = 2; b = 3; c = 10;

Cree un manejador de funciones anónimo para el archivo MATLAB:

f = @(x)bowlpeakfun(x,a,b,c)
f = function_handle with value:
    @(x)bowlpeakfun(x,a,b,c)

Llame para encontrar el mínimo:fminunc

x0 = [-.5; 0]; options = optimoptions('fminunc','Algorithm','quasi-newton'); [x, fval] = fminunc(f,x0,options)
Local minimum found.  Optimization completed because the size of the gradient is less than the value of the optimality tolerance. 
x = 2×1

    1.3639
    3.0000

fval = -0.3840 

Método 2: Función anidada

Tenga en cuenta la siguiente función que implementa el objetivo como una función anidada

type nestedbowlpeak
function [x,fval] =  nestedbowlpeak(a,b,c,x0,options) %NESTEDBOWLPEAK Nested function for parameter passing in TUTDEMO.  %   Copyright 2008 The MathWorks, Inc.  [x,fval] = fminunc(@nestedfun,x0,options);       function y = nestedfun(x)       y = (x(1)-a).*exp(-((x(1)-a).^2+(x(2)-b).^2))+((x(1)-a).^2+(x(2)-b).^2)/c;         end end 

En este método, los parámetros (a, b, c) son visibles para la función de objetivo anidada llamada.nestedfun La función externa,, llama y pasa la función objetiva,.nestedbowlpeakfminuncnestedfun

Defina los parámetros, la suposición inicial y las opciones:

a = 2; b = 3; c = 10; x0 = [-.5; 0]; options = optimoptions('fminunc','Algorithm','quasi-newton');

Ejecute la optimización:

[x,fval] =  nestedbowlpeak(a,b,c,x0,options)
Local minimum found.  Optimization completed because the size of the gradient is less than the value of the optimality tolerance. 
x = 2×1

    1.3639
    3.0000

fval = -0.3840 

Puedes ver que ambos métodos produjeron respuestas idénticas, así que usa el que encuentres más conveniente.

Ejemplo de optimización restringida: desigualdades

Considere el problema anterior con una restricción:

<math display="block">
<mrow>
<mrow>
<mtext>minimize </mtext>
</mrow>
<mi>x</mi>
<mi mathvariant="normal">exp</mi>
<mo stretchy="false">(</mo>
<mo>-</mo>
<mo stretchy="false">(</mo>
<msup>
<mrow>
<mi>x</mi>
</mrow>
<mrow>
<mn>2</mn>
</mrow>
</msup>
<mo>+</mo>
<msup>
<mrow>
<mi>y</mi>
</mrow>
<mrow>
<mn>2</mn>
</mrow>
</msup>
<mo stretchy="false">)</mo>
<mo stretchy="false">)</mo>
<mo>+</mo>
<mo stretchy="false">(</mo>
<msup>
<mrow>
<mi>x</mi>
</mrow>
<mrow>
<mn>2</mn>
</mrow>
</msup>
<mo>+</mo>
<msup>
<mrow>
<mi>y</mi>
</mrow>
<mrow>
<mn>2</mn>
</mrow>
</msup>
<mo stretchy="false">)</mo>
<mo>/</mo>
<mn>2</mn>
<mn>0</mn>
<mo>,</mo>
</mrow>
</math>

<math display="block">
<mrow>
<mrow>
<mtext>subject to </mtext>
</mrow>
<mi>x</mi>
<mi>y</mi>
<mo>/</mo>
<mn>2</mn>
<mo>+</mo>
<mo stretchy="false">(</mo>
<mi>x</mi>
<mo>+</mo>
<mn>2</mn>
<msup>
<mrow>
<mo stretchy="false">)</mo>
</mrow>
<mrow>
<mn>2</mn>
</mrow>
</msup>
<mo>+</mo>
<mo stretchy="false">(</mo>
<mi>y</mi>
<mo>-</mo>
<mn>2</mn>
<msup>
<mrow>
<mo stretchy="false">)</mo>
</mrow>
<mrow>
<mn>2</mn>
</mrow>
</msup>
<mo>/</mo>
<mn>2</mn>
<mo></mo>
<mn>2</mn>
<mo>.</mo>
</mrow>
</math>

El conjunto de restricciones es el interior de una elipse inclinada. Mira los contornos de la función objetiva trazada junto con la elipse inclinada

f = @(x,y) x.*exp(-x.^2-y.^2)+(x.^2+y.^2)/20; g = @(x,y) x.*y/2+(x+2).^2+(y-2).^2/2-2; fimplicit(g) axis([-6 0 -1 7]) hold on fcontour(f) plot(-.9727,.4685,'ro'); legend('constraint','f contours','minimum'); hold off

La gráfica muestra que el valor más bajo de la función objetiva dentro de la elipse se produce cerca de la parte inferior derecha de la elipse. Estamos a punto de calcular el mínimo que se acaba de trazar. Tome una suposición en la solución:

x0 = [-2 1];

Configure las opciones de optimización: Utilice el algoritmo de punto interior y active la visualización de los resultados en cada iteración:

options = optimoptions('fmincon','Algorithm','interior-point','Display','iter');

Los solucionadores requieren que las funciones de restricción no lineal den dos salidas: una para las desigualdades no lineales, la segunda para las ecualidades no lineales. Así que escribimos la restricción usando la función para dar ambas salidas:deal

gfun = @(x) deal(g(x(1),x(2)),[]);

Llame al solucionador restringido no lineal. No hay ecualidades lineales o desigualdades o límites, así que pase [] para esos argumentos:

[x,fval,exitflag,output] = fmincon(fun,x0,[],[],[],[],[],[],gfun,options);
                                            First-order      Norm of  Iter F-count            f(x)  Feasibility   optimality         step     0       3    2.365241e-01    0.000e+00    1.972e-01     1       6    1.748504e-01    0.000e+00    1.734e-01    2.260e-01     2      10   -1.570560e-01    0.000e+00    2.608e-01    9.347e-01     3      14   -6.629160e-02    0.000e+00    1.241e-01    3.103e-01     4      17   -1.584082e-01    0.000e+00    7.934e-02    1.826e-01     5      20   -2.349124e-01    0.000e+00    1.912e-02    1.571e-01     6      23   -2.255299e-01    0.000e+00    1.955e-02    1.993e-02     7      26   -2.444225e-01    0.000e+00    4.293e-03    3.821e-02     8      29   -2.446931e-01    0.000e+00    8.100e-04    4.035e-03     9      32   -2.446933e-01    0.000e+00    1.999e-04    8.126e-04    10      35   -2.448531e-01    0.000e+00    4.004e-05    3.289e-04    11      38   -2.448927e-01    0.000e+00    4.036e-07    8.156e-05  Local minimum found that satisfies the constraints.  Optimization completed because the objective function is non-decreasing in  feasible directions, to within the value of the optimality tolerance, and constraints are satisfied to within the value of the constraint tolerance. 

Una solución a este problema se ha encontrado en:

x
x = 1×2

   -0.9727    0.4686

El valor de la función en la solución es:

fval
fval = -0.2449 

El número total de evaluaciones de funciones fue:

Fevals = output.funcCount
Fevals = 38 

La restricción de desigualdad se satisface en la solución.

[c, ceq] = gfun(x)
c = -2.4608e-06 
ceq =       [] 

Puesto que c (x) está cerca de 0, la restricción es "activa", lo que significa que la restricción afecta a la solución. Recuerde que la solución sin restricciones se encontró en

uncx
uncx = 2×1

   -0.6691
    0.0000

y se descubrió que la función objetiva no restringida era

uncf
uncf = -0.4052 

La restricción movió la solución y aumentó el objetivo mediante

fval-uncf
ans = 0.1603 

Ejemplo de optimización restringida: degradados proporcionados por el usuario

Los problemas de optimización se pueden resolver de manera más eficiente y precisa si el usuario suministra gradientes. Este ejemplo muestra cómo esto puede ser realizado. De nuevo resolvemos el problema de desigualdad limitada

<math display="block">
<mrow>
<mrow>
<mtext>minimize </mtext>
</mrow>
<mi>x</mi>
<mi mathvariant="normal">exp</mi>
<mo stretchy="false">(</mo>
<mo>-</mo>
<mo stretchy="false">(</mo>
<msup>
<mrow>
<mi>x</mi>
</mrow>
<mrow>
<mn>2</mn>
</mrow>
</msup>
<mo>+</mo>
<msup>
<mrow>
<mi>y</mi>
</mrow>
<mrow>
<mn>2</mn>
</mrow>
</msup>
<mo stretchy="false">)</mo>
<mo stretchy="false">)</mo>
<mo>+</mo>
<mo stretchy="false">(</mo>
<msup>
<mrow>
<mi>x</mi>
</mrow>
<mrow>
<mn>2</mn>
</mrow>
</msup>
<mo>+</mo>
<msup>
<mrow>
<mi>y</mi>
</mrow>
<mrow>
<mn>2</mn>
</mrow>
</msup>
<mo stretchy="false">)</mo>
<mo>/</mo>
<mn>2</mn>
<mn>0</mn>
<mo>,</mo>
</mrow>
</math>

<math display="block">
<mrow>
<mrow>
<mtext>subject to </mtext>
</mrow>
<mi>x</mi>
<mi>y</mi>
<mo>/</mo>
<mn>2</mn>
<mo>+</mo>
<mo stretchy="false">(</mo>
<mi>x</mi>
<mo>+</mo>
<mn>2</mn>
<msup>
<mrow>
<mo stretchy="false">)</mo>
</mrow>
<mrow>
<mn>2</mn>
</mrow>
</msup>
<mo>+</mo>
<mo stretchy="false">(</mo>
<mi>y</mi>
<mo>-</mo>
<mn>2</mn>
<msup>
<mrow>
<mo stretchy="false">)</mo>
</mrow>
<mrow>
<mn>2</mn>
</mrow>
</msup>
<mo>/</mo>
<mn>2</mn>
<mo></mo>
<mn>2</mn>
<mo>.</mo>
</mrow>
</math>

Para proporcionar el degradado de f (x) a, escribimos la función objetivo en forma de un archivo MATLAB:fmincon

type onehump
function [f,gf] = onehump(x) % ONEHUMP Helper function for Tutorial for the Optimization Toolbox demo  %   Copyright 2008-2009 The MathWorks, Inc.  r = x(1)^2 + x(2)^2; s = exp(-r); f = x(1)*s+r/20;  if nargout > 1    gf = [(1-2*x(1)^2)*s+x(1)/10;        -2*x(1)*x(2)*s+x(2)/10]; end 

La restricción y su gradiente se encuentran en el archivo tiltellipse de MATLAB:

type tiltellipse
function [c,ceq,gc,gceq] = tiltellipse(x) % TILTELLIPSE Helper function for Tutorial for the Optimization Toolbox demo  %   Copyright 2008-2009 The MathWorks, Inc.  c = x(1)*x(2)/2 + (x(1)+2)^2 + (x(2)-2)^2/2 - 2; ceq = [];  if nargout > 2    gc = [x(2)/2+2*(x(1)+2);        x(1)/2+x(2)-2];    gceq = []; end 

Haga una suposición en la solución:

x0 = [-2; 1];

Establecer opciones de optimización: seguimos utilizando el mismo algoritmo para fines de comparación.

options = optimoptions('fmincon','Algorithm','interior-point');

También se establecen opciones para utilizar la información de degradado en las funciones de objetivo y restricción. Nota: estas opciones deben estar activadas o la información del degradado se ignorará.

options = optimoptions(options,...     'SpecifyObjectiveGradient',true,...     'SpecifyConstraintGradient',true);

Esta vez debería haber menos recuentos de funciones, ya que no es necesario estimar los degradados utilizando diferencias finitas.fmincon

options.Display = 'iter';

Llame al solucionador:

[x,fval,exitflag,output] = fmincon(@onehump,x0,[],[],[],[],[],[], ...                                    @tiltellipse,options);
                                            First-order      Norm of  Iter F-count            f(x)  Feasibility   optimality         step     0       1    2.365241e-01    0.000e+00    1.972e-01     1       2    1.748504e-01    0.000e+00    1.734e-01    2.260e-01     2       4   -1.570560e-01    0.000e+00    2.608e-01    9.347e-01     3       6   -6.629161e-02    0.000e+00    1.241e-01    3.103e-01     4       7   -1.584082e-01    0.000e+00    7.934e-02    1.826e-01     5       8   -2.349124e-01    0.000e+00    1.912e-02    1.571e-01     6       9   -2.255299e-01    0.000e+00    1.955e-02    1.993e-02     7      10   -2.444225e-01    0.000e+00    4.293e-03    3.821e-02     8      11   -2.446931e-01    0.000e+00    8.100e-04    4.035e-03     9      12   -2.446933e-01    0.000e+00    1.999e-04    8.126e-04    10      13   -2.448531e-01    0.000e+00    4.004e-05    3.289e-04    11      14   -2.448927e-01    0.000e+00    4.036e-07    8.156e-05  Local minimum found that satisfies the constraints.  Optimization completed because the objective function is non-decreasing in  feasible directions, to within the value of the optimality tolerance, and constraints are satisfied to within the value of the constraint tolerance. 

degradados estimados bien en el ejemplo anterior, por lo que las iteraciones en el ejemplo actual son similares.fmincon

La solución a este problema se ha encontrado en:

xold = x
xold = 2×1

   -0.9727
    0.4686

El valor de la función en la solución es:

minfval = fval
minfval = -0.2449 

El número total de evaluaciones de funciones fue:

Fgradevals = output.funcCount
Fgradevals = 14 

Compare esto con el número de evaluaciones de función sin degradados:

Fevals
Fevals = 38 

Cambio de las tolerancias de terminación predeterminadas

Esta vez resolvemos el mismo problema restringido

<math display="block">
<mrow>
<mrow>
<mtext>minimize </mtext>
</mrow>
<mi>x</mi>
<mi mathvariant="normal">exp</mi>
<mo stretchy="false">(</mo>
<mo>-</mo>
<mo stretchy="false">(</mo>
<msup>
<mrow>
<mi>x</mi>
</mrow>
<mrow>
<mn>2</mn>
</mrow>
</msup>
<mo>+</mo>
<msup>
<mrow>
<mi>y</mi>
</mrow>
<mrow>
<mn>2</mn>
</mrow>
</msup>
<mo stretchy="false">)</mo>
<mo stretchy="false">)</mo>
<mo>+</mo>
<mo stretchy="false">(</mo>
<msup>
<mrow>
<mi>x</mi>
</mrow>
<mrow>
<mn>2</mn>
</mrow>
</msup>
<mo>+</mo>
<msup>
<mrow>
<mi>y</mi>
</mrow>
<mrow>
<mn>2</mn>
</mrow>
</msup>
<mo stretchy="false">)</mo>
<mo>/</mo>
<mn>2</mn>
<mn>0</mn>
<mo>,</mo>
</mrow>
</math>

<math display="block">
<mrow>
<mrow>
<mtext>subject to </mtext>
</mrow>
<mi>x</mi>
<mi>y</mi>
<mo>/</mo>
<mn>2</mn>
<mo>+</mo>
<mo stretchy="false">(</mo>
<mi>x</mi>
<mo>+</mo>
<mn>2</mn>
<msup>
<mrow>
<mo stretchy="false">)</mo>
</mrow>
<mrow>
<mn>2</mn>
</mrow>
</msup>
<mo>+</mo>
<mo stretchy="false">(</mo>
<mi>y</mi>
<mo>-</mo>
<mn>2</mn>
<msup>
<mrow>
<mo stretchy="false">)</mo>
</mrow>
<mrow>
<mn>2</mn>
</mrow>
</msup>
<mo>/</mo>
<mn>2</mn>
<mo></mo>
<mn>2</mn>
<mo>,</mo>
</mrow>
</math>

con mayor precisión anulando los criterios de terminación predeterminados (opciones. StepTolerance y opciones. OptimalityTolerance). Seguimos utilizando gradientes. Los valores predeterminados para el algoritmo de punto interior son opciones. StepTolerance = 1E-10, opciones. OptimalityTolerance = 1E-6.fmincon

Invalide dos criterios de terminación predeterminados: tolerancias de terminación en X y FVal.

options = optimoptions(options,...     'StepTolerance',1e-15,...     'OptimalityTolerance',1e-8);

Llame al solucionador:

[x,fval,exitflag,output] = fmincon(@onehump,x0,[],[],[],[],[],[], ...                                    @tiltellipse,options);
                                            First-order      Norm of  Iter F-count            f(x)  Feasibility   optimality         step     0       1    2.365241e-01    0.000e+00    1.972e-01     1       2    1.748504e-01    0.000e+00    1.734e-01    2.260e-01     2       4   -1.570560e-01    0.000e+00    2.608e-01    9.347e-01     3       6   -6.629161e-02    0.000e+00    1.241e-01    3.103e-01     4       7   -1.584082e-01    0.000e+00    7.934e-02    1.826e-01     5       8   -2.349124e-01    0.000e+00    1.912e-02    1.571e-01     6       9   -2.255299e-01    0.000e+00    1.955e-02    1.993e-02     7      10   -2.444225e-01    0.000e+00    4.293e-03    3.821e-02     8      11   -2.446931e-01    0.000e+00    8.100e-04    4.035e-03     9      12   -2.446933e-01    0.000e+00    1.999e-04    8.126e-04    10      13   -2.448531e-01    0.000e+00    4.004e-05    3.289e-04    11      14   -2.448927e-01    0.000e+00    4.036e-07    8.156e-05    12      15   -2.448931e-01    0.000e+00    4.000e-09    8.230e-07  Local minimum found that satisfies the constraints.  Optimization completed because the objective function is non-decreasing in  feasible directions, to within the value of the optimality tolerance, and constraints are satisfied to within the value of the constraint tolerance. 

Ahora elegimos ver más decimales en la solución, con el fin de ver con mayor precisión la diferencia que hacen las nuevas tolerancias.

format long

El optimizador encontró una solución en:

x
x = 2×1

  -0.972742227363546
   0.468569289098342

Compare esto con el valor anterior:

xold
xold = 2×1

  -0.972742694488360
   0.468569966693330

El cambio es

x - xold
ans = 2×1
10-6 ×

   0.467124813385844
  -0.677594988729435

El valor de la función en la solución es:

fval
fval =    -0.244893137879894  

La solución mejorada por

fval - minfval
ans =      -3.996450220755676e-07  

(esto es negativo ya que la nueva solución es más pequeña)

El número total de evaluaciones de funciones fue:

output.funcCount
ans =      15  

Compare esto con el número de evaluaciones de función cuando el problema se resuelve con los degradados proporcionados por el usuario, pero con las tolerancias predeterminadas:

Fgradevals
Fgradevals =      14  

Ejemplo de optimización restringida con hessian suministrado por el usuario

Si le das no sólo un gradiente, sino también un hessian, los solucionadores son aún más precisos y eficientes.

el solucionador de punto interior toma una matriz Hessiana como una función separada (no parte de la función objetiva).fmincon La función hessiana H (x, lambda) debe evaluar el hessian de los Lagrangios; Consulte la guía del usuario para la definición de este término.

Solvers calcular los valores lambda. ineqnonlin y lambda. eqlin; su función hessian indica a los solucionadores cómo utilizar estos valores.

En este problema sólo tenemos una restricción de desigualdad, por lo que el hessian es:

type hessfordemo
function H = hessfordemo(x,lambda) % HESSFORDEMO Helper function for Tutorial for the Optimization Toolbox demo  %   Copyright 2008-2009 The MathWorks, Inc.  s = exp(-(x(1)^2+x(2)^2)); H = [2*x(1)*(2*x(1)^2-3)*s+1/10, 2*x(2)*(2*x(1)^2-1)*s;         2*x(2)*(2*x(1)^2-1)*s, 2*x(1)*(2*x(2)^2-1)*s+1/10]; hessc = [2,1/2;1/2,1]; H = H + lambda.ineqnonlin(1)*hessc; 

Con el fin de utilizar el hessian, es necesario establecer las opciones de manera adecuada:

options = optimoptions('fmincon',...     'Algorithm','interior-point',...     'SpecifyConstraintGradient',true,...     'SpecifyObjectiveGradient',true,...     'HessianFcn',@hessfordemo);

Las tolerancias se han fijado de nuevo a los valores por defecto. Esta vez debería haber menos recuentos de funciones.

options.Display = 'iter';

Llame al solucionador:

[x,fval,exitflag,output] = fmincon(@onehump,x0,[],[],[],[],[],[], ...                                    @tiltellipse,options);
                                            First-order      Norm of  Iter F-count            f(x)  Feasibility   optimality         step     0       1    2.365241e-01    0.000e+00    1.972e-01     1       3    5.821325e-02    0.000e+00    1.443e-01    8.728e-01     2       5   -1.218829e-01    0.000e+00    1.007e-01    4.927e-01     3       6   -1.421167e-01    0.000e+00    8.486e-02    5.165e-02     4       7   -2.261916e-01    0.000e+00    1.989e-02    1.667e-01     5       8   -2.433609e-01    0.000e+00    1.537e-03    3.486e-02     6       9   -2.446875e-01    0.000e+00    2.057e-04    2.727e-03     7      10   -2.448911e-01    0.000e+00    2.068e-06    4.191e-04     8      11   -2.448931e-01    0.000e+00    2.001e-08    4.218e-06  Local minimum found that satisfies the constraints.  Optimization completed because the objective function is non-decreasing in  feasible directions, to within the value of the optimality tolerance, and constraints are satisfied to within the value of the constraint tolerance. 

Hubo menos, y diferentes iteraciones esta vez.

La solución a este problema se ha encontrado en:

x
x = 2×1

  -0.972742246093537
   0.468569316215571

El valor de la función en la solución es:

fval
fval =    -0.244893121872758  

El número total de evaluaciones de funciones fue:

output.funcCount
ans =      11  

Compare esto con el número utilizando sólo evaluaciones de degradado, con las mismas tolerancias predeterminadas:

Fgradevals
Fgradevals =      14  

Temas relacionados