Main Content

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 Resolver un problema no lineal restringido basado en solvers.

Formulación del problema: función de Rosenbrock

Considere el problema de minimizar la función de Rosenbrock

f(x)=100(x2-x12)2+(1-x1)2,

sobre el disco unidad, es decir, el disco de radio 1 centrado en el origen. En otras palabras, encontrar x que minimiza la función f(x) sobre el x12+x221 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 log(1+f(x)). 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

Figure contains 2 axes objects. Axes object 1 contains 2 objects of type surface, contour. Axes object 2 with title Rosenbrock's Function: Two Views contains 2 objects of type surface, contour.

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 f(x) se llama función objetivo. La función objetivo es la función que desea minimizar. La desigualdad x12+x221 se llama restricción. Las restricciones limitan el conjunto de x 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 con fcn2optimexpr 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 x 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 estructura output.

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.

Temas relacionados