Resolver un problema no lineal restringido, basado problemas
Problema de optimización típico
Este ejemplo muestra cómo resolver un problema de optimización no lineal restringido utilizando el enfoque basado en problemas. Este ejemplo demuestra el flujo de trabajo típico: crear una función objetivo, crear restricciones, resolver el problema y examinar los resultados.
Nota:
Si la función objetivo o las restricciones no lineales no están compuestas por funciones elementales, deberá convertir las funciones no lineales en expresiones de optimización utilizando fcn2optimexpr
. Consulte la última parte de este ejemplo, Formulación alternativa con fcn2optimexpr, o Convert Nonlinear Function to Optimization Expression.
Si desea ver el enfoque basado en solvers para este problema, consulte Problema no lineal restringido utilizando la tarea Optimize de Live Editor o el solver.
Formulación del problema: función de Rosenbrock
Considere el problema de minimizar la función de Rosenbrock
sobre el disco unidad, es decir, el disco de radio 1 centrado en el origen. En otras palabras, encontrar que minimiza la función sobre el establecido. Este problema es una minimización de una función no lineal sujeta a una restricción no lineal.
La función de Rosenbrock es una función de prueba estándar de optimización. Tiene un valor mínimo único de 0 alcanzado en el punto [1,1]
. Encontrar el mínimo es un reto para algunos algoritmos, ya que la función tiene un mínimo superficial dentro de un valle con muchas curvas. La solución para este problema no se encuentra en el punto [1,1]
, ya que ese punto no satisface la restricción.
Esta figura muestra dos vistas de la función de Rosenbrock en el disco unidad. El eje vertical está en escala logarítmica, es decir, que la gráfica muestra . Las líneas de contorno quedan debajo de la gráfica de superficie.
rosenbrock = @(x)100*(x(:,2) - x(:,1).^2).^2 + (1 - x(:,1)).^2; % Vectorized function figure1 = figure('Position',[1 200 600 300]); colormap('gray'); axis square; R = 0:.002:1; TH = 2*pi*(0:.002:1); X = R'*cos(TH); Y = R'*sin(TH); Z = log(1 + rosenbrock([X(:),Y(:)])); Z = reshape(Z,size(X)); % Create subplot subplot1 = subplot(1,2,1,'Parent',figure1); view([124 34]); grid('on'); hold on; % Create surface surf(X,Y,Z,'Parent',subplot1,'LineStyle','none'); % Create contour contour(X,Y,Z,'Parent',subplot1); % Create subplot subplot2 = subplot(1,2,2,'Parent',figure1); view([234 34]); grid('on'); hold on % Create surface surf(X,Y,Z,'Parent',subplot2,'LineStyle','none'); % Create contour contour(X,Y,Z,'Parent',subplot2); % Create textarrow annotation(figure1,'textarrow',[0.4 0.31],... [0.055 0.16],... 'String',{'Minimum at (0.7864,0.6177)'}); % Create arrow annotation(figure1,'arrow',[0.59 0.62],... [0.065 0.34]); title("Rosenbrock's Function: Two Views") hold off
El identificador de función rosenbrock
calcula la función de Rosenbrock en un número cualquiera de puntos 2D al mismo tiempo. Esta Vectorización acelera la representación de la función y puede resultar útil en otros contextos para acelerar la evaluación de una función en varios puntos.
La función se llama función objetivo. La función objetivo es la función que desea minimizar. La desigualdad se llama restricción. Las restricciones limitan el conjunto de sobre el que un solver busca un mínimo. Puede tener cualquier número de restricciones, que son desigualdades o ecuaciones.
Definir un problema utilizando variables de optimización
El enfoque basado en problemas sobre la optimización utiliza variables de optimización para definir el objetivo y las restricciones. Existen dos enfoques para crear expresiones utilizando estas variables:
Para funciones polinómicas o racionales, escriba expresiones directamente en las variables.
Para otros tipos de funciones, convierta funciones a expresiones de optimización con
fcn2optimexpr
. Consulte Formulación alternativa confcn2optimexpr
al final de este ejemplo.
Para este problema, tanto la función objetivo como la restricción no lineal son polinomios, de modo que puede escribir las expresiones directamente en términos de variables de optimización. Cree una variable de optimización en 2D llamada 'x'
.
x = optimvar('x',1,2);
Cree la función objetivo como un polinomio en la variable de optimización.
obj = 100*(x(2) - x(1)^2)^2 + (1 - x(1))^2;
Cree un problema de optimización llamado prob
con obj
como la función objetivo.
prob = optimproblem('Objective',obj);
Cree la restricción no lineal como un polinomio en la variable de optimización.
nlcons = x(1)^2 + x(2)^2 <= 1;
Incluya la restricción no lineal en el problema.
prob.Constraints.circlecons = nlcons;
Revise el problema.
show(prob)
OptimizationProblem : Solve for: x minimize : ((100 .* (x(2) - x(1).^2).^2) + (1 - x(1)).^2) subject to circlecons: (x(1).^2 + x(2).^2) <= 1
Resolver el problema
Para resolver el problema de optimización, llame a solve
. El problema requiere un punto inicial, que es una estructura que proporciona el valor inicial de la variable de optimización. Cree la estructura de punto inicial x0
con un valor de [0 0]
.
x0.x = [0 0]; [sol,fval,exitflag,output] = solve(prob,x0)
Solving problem using fmincon. 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.
sol = struct with fields:
x: [0.7864 0.6177]
fval = 0.0457
exitflag = OptimalSolution
output = struct with fields:
iterations: 24
funcCount: 34
constrviolation: 0
stepsize: 6.9161e-06
algorithm: 'interior-point'
firstorderopt: 2.1625e-08
cgiterations: 4
message: 'Local minimum found that satisfies the constraints....'
bestfeasible: [1x1 struct]
objectivederivative: "reverse-AD"
constraintderivative: "closed-form"
solver: 'fmincon'
Examinar la solución
La solución muestra exitflag = OptimalSolution
. Este indicador de salida indica que la solución es un óptimo local. Para obtener información sobre cómo encontrar una solución mejor, consulte Cuando el solver tiene éxito.
El mensaje de salida indica que la solución cumple las restricciones. Puede comprobar que la solución realmente sea factible de varias formas.
Compruebe la infactibilidad indicada en el campo
constrviolation
de la estructuraoutput
.
infeas = output.constrviolation
infeas = 0
Una infactibilidad de 0 indica que la solución es factible.
Calcule la infactibilidad en la solución.
infeas = infeasibility(nlcons,sol)
infeas = 0
De nuevo, una infactibilidad de 0 indica que la solución es factible.
Calcule la norma de
x
para garantizar que sea menor que o igual a 1.
nx = norm(sol.x)
nx = 1.0000
La estructura output
proporciona más información sobre el proceso de resolución, como el número de iteraciones (24), el solver (fmincon
) y el número de evaluaciones de función (84). Para obtener más información sobre estas estadísticas, consulte Tolerancias y criterios de detención.
Formulación alternativa con fcn2optimexpr
Para obtener expresiones más complejas, escriba archivos de función para la función objetivo o la función de restricción y conviértalas a una expresión de optimización mediante fcn2optimexpr
. Por ejemplo, la base de la función de restricción no lineal está en el archivo disk.m
:
type disk
function radsqr = disk(x) radsqr = x(1)^2 + x(2)^2;
Convierta este archivo de función a una expresión de optimización.
radsqexpr = fcn2optimexpr(@disk,x);
Además, también puede convertir el identificador de función rosenbrock
, que se definió al comenzar la rutina de representación, a una expresión de optimización.
rosenexpr = fcn2optimexpr(rosenbrock,x);
Cree un problema de optimización con estas expresiones de optimización convertidas.
convprob = optimproblem('Objective',rosenexpr,'Constraints',radsqexpr <= 1);
Visualice el problema nuevo.
show(convprob)
OptimizationProblem : Solve for: x minimize : ((100 .* (x(2) - x(1).^2).^2) + (1 - x(1)).^2) subject to : (x(1).^2 + x(2).^2) <= 1
Resuelva el problema nuevo. La solución es básicamente la misma que antes.
[sol,fval,exitflag,output] = solve(convprob,x0)
Solving problem using fmincon. 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.
sol = struct with fields:
x: [0.7864 0.6177]
fval = 0.0457
exitflag = OptimalSolution
output = struct with fields:
iterations: 24
funcCount: 34
constrviolation: 0
stepsize: 6.9161e-06
algorithm: 'interior-point'
firstorderopt: 2.1625e-08
cgiterations: 4
message: 'Local minimum found that satisfies the constraints....'
bestfeasible: [1x1 struct]
objectivederivative: "reverse-AD"
constraintderivative: "closed-form"
solver: 'fmincon'
Para ver la lista de funciones compatibles, consulte Supported Operations for Optimization Variables and Expressions.