Tutorial para Optimization Toolbox
Este tutorial incluye múltiples ejemplos que muestran cómo usar dos solvers de optimización no lineales, fminunc
y fmincon
, y cómo establecer las opciones. Los principios descritos en este tutorial son aplicables a otros solvers no lineales, como fgoalattain
, fminimax
, lsqnonlin
, lsqcurvefit
y fsolve
.
Los ejemplos del tutorial cubren estas tareas:
Minimizar una función objetivo
Minimizar la misma función con parámetros adicionales
Minimizar la función objetivo con una restricción
Obtener una solución más eficiente y precisa proporcionando gradientes o una matriz hessiana, o cambiando opciones
Ejemplo de optimización no restringida
Considere el problema de encontrar un mínimo de la función
Represente la función para ver dónde está minimizada.
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).
Por lo general, la función objetivo se define como un archivo de MATLAB®. En este caso, la función es lo suficientemente simple como para definirla como una función anónima.
fun = @(x) f(x(1),x(2));
Establezca un punto inicial para encontrar la solución.
x0 = [-.5; 0];
Establezca las opciones de optimización para usar el algoritmo 'quasi-newton'
predeterminado de fminunc
. Este paso garantiza que el tutorial funciona igual en cualquier versión de MATLAB.
options = optimoptions('fminunc','Algorithm','quasi-newton');
Visualice las iteraciones mientras el solver realiza sus cálculos.
options.Display = 'iter';
Llame a fminunc
, un minimizador no lineal no restringido.
[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.
Muestre la solución encontrada por el solver.
uncx = x
uncx = 2×1
-0.6691
0.0000
Visualice el valor de la función en la solución.
uncf = fval
uncf = -0.4052
Los ejemplos usan el número de evaluaciones de función como una medida de eficiencia. Visualice el número total de evaluaciones de función.
output.funcCount
ans = 18
Ejemplo de optimización no restringida con parámetros adicionales
A continuación, pase parámetros adicionales como argumentos adicionales a la función objetivo; primero utilizando un archivo de MATLAB y, después, utilizando una función anidada.
Considere la función objetivo del ejemplo anterior.
Parametrice la función con (a,b,c) de la siguiente manera:
Esta función es una versión desplazada y escalada de la función objetivo original.
Función de un archivo de MATLAB
Considere una función objetivo de un archivo de MATLAB denominada bowlpeakfun
definida de la siguiente manera.
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 identificador de función anónima para el archivo de MATLAB.
f = @(x)bowlpeakfun(x,a,b,c)
f = function_handle with value:
@(x)bowlpeakfun(x,a,b,c)
Llame a fminunc
para encontrar el mínimo.
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
Función anidada
Considere la función nestedbowlpeak
, 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
Los parámetros (a,b,c) son visibles para la función objetivo anidada nestedfun
. La función exterior, nestedbowlpeak
, llama a fminunc
y pasa la función objetivo, nestedfun
.
Defina los parámetros, la conjetura 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
Ambos enfoques producen las mismas respuestas, así que puede utilizar el que resulte más conveniente.
Ejemplo de optimización restringida: Desigualdades
Considere el problema anterior con una restricción:
El conjunto de restricciones es el interior de una elipse inclinada. Visualice los contornos de la función objetivo representada 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 objetivo dentro de la elipse se produce cerca de la parte inferior derecha de la elipse. Antes de calcular el mínimo representado, realice una conjetura en la solución.
x0 = [-2 1];
Establezca las opciones de optimización para usar el algoritmo interior-point y muestre los resultados en cada iteración.
options = optimoptions('fmincon','Algorithm','interior-point','Display','iter');
Los solvers requieren que las funciones de restricción no lineal den dos salidas, una para desigualdades no lineales y una para igualdades no lineales. Para dar ambas salidas, escriba la restricción utilizando la función deal
.
gfun = @(x) deal(g(x(1),x(2)),[]);
Llame al solver restringido no lineal. El problema no tiene igualdades o desigualdades lineales 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.
Muestre la solución encontrada por el solver.
x
x = 1×2
-0.9727 0.4686
Visualice el valor de la función en la solución.
fval
fval = -0.2449
Visualice el número total de evaluaciones de función.
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 = []
Dado que c(x) está cerca de 0, la restricción está activa lo que significa que afecta a la solución. Vuelva a llamar a la solución no restringida.
uncx
uncx = 2×1
-0.6691
0.0000
Vuelva a llamar a la función objetivo no restringida.
uncf
uncf = -0.4052
Compruebe cuánto ha movido la restricción la solución y ha aumentado el objetivo.
fval-uncf
ans = 0.1603
Ejemplo de optimización restringida: Gradientes proporcionados por el usuario
Puede resolver problemas de optimización con más eficiencia y precisión proporcionando gradientes. Este ejemplo, como el anterior, resuelve el problema de desigualdad restringido
Para proporcionar el gradiente de f(x) a fmincon
, escriba la función objetivo en forma de un archivo de MATLAB.
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 de MATLAB tiltellipse
.
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
Establezca un punto inicial para encontrar la solución.
x0 = [-2; 1];
Establezca las opciones de optimización para usar el mismo algoritmo que en el ejemplo anterior con el objetivo de realizar una comparación.
options = optimoptions('fmincon','Algorithm','interior-point');
Establezca opciones para utilizar la información del gradiente en las funciones objetivo y de restricción. Nota: estas opciones deben activarse o se ignorará la información del gradiente.
options = optimoptions(options,... 'SpecifyObjectiveGradient',true,... 'SpecifyConstraintGradient',true);
Dado que fmincon
no necesita estimar gradientes utilizando diferencias finitas, el solver debería tener menos recuentos de la función. Establezca las opciones para mostrar los resultados en cada iteración.
options.Display = 'iter';
Llame al solver.
[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.
fmincon
estimó bien los gradientes en el ejemplo anterior, de modo que las iteraciones en este ejemplo son similares.
Muestre la solución encontrada por el solver.
xold = x
xold = 2×1
-0.9727
0.4686
Visualice el valor de la función en la solución.
minfval = fval
minfval = -0.2449
Visualice el número total de evaluaciones de función.
Fgradevals = output.funcCount
Fgradevals = 14
Compare este número con el número de evaluaciones de función sin gradientes.
Fevals
Fevals = 38
Ejemplo de optimización restringida: Cambiar las tolerancias de terminación predeterminadas
Este ejemplo continúa utilizando gradientes y resuelve el mismo problema restringido
.
En este caso, logra una solución más precisa anulando los criterios predeterminados de terminación (options.StepTolerance
y options.OptimalityTolerance
). Los valores predeterminados para el algoritmo interior-point fmincon
son options.StepTolerance = 1e-10
y options.OptimalityTolerance = 1e-6
.
Anule estos dos criterios predeterminados de terminación.
options = optimoptions(options,... 'StepTolerance',1e-15,... 'OptimalityTolerance',1e-8);
Llame al solver.
[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.
Para ver la diferencia causada por las nuevas tolerancias con más precisión, muestre más decimales en la solución.
format long
Muestre la solución encontrada por el solver.
x
x = 2×1
-0.972742227363546
0.468569289098342
Compare estos valores con los valores del ejemplo anterior.
xold
xold = 2×1
-0.972742694488360
0.468569966693330
Determine el cambio en los valores.
x - xold
ans = 2×1
10-6 ×
0.467124813385844
-0.677594988729435
Visualice el valor de la función en la solución.
fval
fval = -0.244893137879894
Compruebe cuánto ha mejorado la solución.
fval - minfval
ans = -3.996450220755676e-07
La respuesta es negativa porque la nueva solución es más pequeña.
Visualice el número total de evaluaciones de función.
output.funcCount
ans = 15
Compare este número con el número de evaluaciones de función del ejemplo resuelto con gradientes proporcionados por el usuario y las tolerancias predeterminadas.
Fgradevals
Fgradevals = 14
Ejemplo de optimización restringida: Matriz hessiana proporcionada por el usuario
Si proporciona una matriz hessiana además de un gradiente, los solvers son incluso más precisos y eficientes.
El algoritmo interior-point de fmincon
toma una matriz hessiana como una función separada (no como parte de una función objetivo). La función hessiana H(x,lambda) evalúa la matriz hessiana del lagrangiano; consulte Matriz hessiana para el algoritmo fmincon interior-point.
Los solvers calculan los valores lambda.ineqnonlin
y lambda.eqlin
; su función hessiana indica a los solvers cómo utilizar estos valores.
Este ejemplo tiene una restricción de desigualdad, de manera que la matriz hessiana se define como se establece en la función hessfordemo
.
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;
Para utilizar la matriz hessiana, debe establecer las opciones de manera adecuada.
options = optimoptions('fmincon',... 'Algorithm','interior-point',... 'SpecifyConstraintGradient',true,... 'SpecifyObjectiveGradient',true,... 'HessianFcn',@hessfordemo);
Las tolerancias están establecidas en sus valores predeterminados, lo que debería resultar en menos recuentos de función. Establezca las opciones para mostrar los resultados en cada iteración.
options.Display = 'iter';
Llame al solver.
[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.
Los resultados muestran menos y diferentes iteraciones.
Muestre la solución encontrada por el solver.
x
x = 2×1
-0.972742246093537
0.468569316215571
Visualice el valor de la función en la solución.
fval
fval = -0.244893121872758
Visualice el número total de evaluaciones de función.
output.funcCount
ans = 11
Compare este número con el número de evaluaciones de función del ejemplo resuelto utilizando solo evaluaciones de gradientes, con las mismas tolerancias predeterminadas.
Fgradevals
Fgradevals = 14