Main Content

将非线性函数转换为优化表达式

本节说明如何选择是将非线性函数转换为优化表达式,还是根据支持的优化变量运算创建表达式。本节还说明如何在必要时使用 fcn2optimexpr 转换函数。

尽可能使用支持的运算

通常,通过对优化变量和表达式使用支持的运算来创建目标或非线性约束函数。这样做的优点是 solve 包括通过自动微分计算的梯度。请参阅Effect of Automatic Differentiation in Problem-Based Optimization

一般情况下,支持的运算包括所有初等数学运算:加、减、乘、除、幂以及初等函数(例如指数函数和三角函数及其逆函数)。不支持非平滑运算,如 maxabsifcase。有关完整的描述,请参阅Supported Operations for Optimization Variables and Expressions

例如,假设您的目标函数是

f(x,y,r)=100(y-x2)2+(r-x)2

其中 r 是您提供的参数,问题是在 xy 的取值范围内求 f 的最小值。此目标函数是一个平方和,它在点 x=r, y=r2 处取最小值 0。

目标函数是一个多项式,因此您可以把它写为优化变量的基本运算。

r = 2;
x = optimvar('x');
y = optimvar('y');
f = 100*(y - x^2)^2 + (r - x)^2;
prob = optimproblem("Objective",f);
x0.x = -1;
x0.y = 2;
[sol,fval] = solve(prob,x0) 
Solving problem using lsqnonlin.

Local minimum found.

Optimization completed because the size of the gradient is less than
the value of the optimality tolerance.
sol = struct with fields:
    x: 2.0000
    y: 4.0000

fval = 4.4373e-31

要通过使用 fcn2optimexpr 转换目标函数来求解相同的问题,请首先将目标编写为一个匿名函数。

fun = @(x,y)100*(y - x^2)^2 + (r - x)^2;

将该匿名函数转换为优化表达式。

prob.Objective = fcn2optimexpr(fun,x,y);
[sol2,fval2] = solve(prob,x0)
Solving problem using lsqnonlin.

Local minimum found.

Optimization completed because the size of the gradient is less than
the value of the optimality tolerance.
sol2 = struct with fields:
    x: 2.0000
    y: 4.0000

fval2 = 4.4373e-31

解与之前一样。通常,在 R2022b 或更高的软件版本中,使用 fcn2optimexpr 几乎不会降低性能,在某些情况下,因为静态分析,性能还会有所提高。请参阅Static Analysis of Optimization Expressions

此示例的其余部分显示关于在目标函数或非线性约束的优化表达式中使用 fcn2optimexpr 的更多详细信息。

函数文件

要在基于问题的方法中使用包含不支持的运算符的函数文件,必须使用 fcn2optimexpr 将该文件转换为表达式。

例如,expfn3.m 文件包含以下代码:

type expfn3.m
function [f,g,mineval] = expfn3(u,v)
mineval = min(eig(u));
f = v'*u*v;
f = -exp(-f);
t = u*v;
g = t'*t + sum(t) - 3;

由于存在 min(eig(u)),此函数不完全由支持的运算组成。因此,要使用 expfn3(u,v) 作为优化表达式,必须先使用 fcn2optimexpr 进行转换。

要使用 expfn3 作为优化表达式,请首先创建适当大小的优化变量。

u = optimvar('u',3,3,'LowerBound',-1,'UpperBound',1); % 3-by-3 variable
v = optimvar('v',3,'LowerBound',-2,'UpperBound',2); % 3-by-1 variable

使用 fcn2optimexpr 将函数文件转换为优化表达式。

[f,g,mineval] = fcn2optimexpr(@expfn3,u,v);

由于所有返回的表达式均为标量,因此可以通过使用 'OutputSize' 名称-值参量指定表达式大小来节省计算时间。此外,由于 expfn3 会计算所有输出,因此使用 ReuseEvaluation 名称-值参量可以节省更多计算时间。

[f,g,mineval] = fcn2optimexpr(@expfn3,u,v,'OutputSize',[1,1],'ReuseEvaluation',true)
f = 
  Nonlinear OptimizationExpression

    [argout,~,~] = expfn3(u, v)

g = 
  Nonlinear OptimizationExpression

    [~,argout,~] = expfn3(u, v)

mineval = 
  Nonlinear OptimizationExpression

    [~,~,argout] = expfn3(u, v)

匿名函数

为了在基于问题的方法中使用一般的非线性函数句柄,请使用 fcn2optimexpr 将句柄转换为优化表达式。例如,编写等效于 mineval 的函数句柄,并进行转换。

fun = @(u)min(eig(u));
funexpr = fcn2optimexpr(fun,u,'OutputSize',[1,1])
funexpr = 
  Nonlinear OptimizationExpression

    arg1

  where:

      anonymousFunction1 = @(u)min(eig(u));
      arg1 = anonymousFunction1(u);

创建目标

要将目标表达式用作目标函数,请创建一个优化问题。

prob = optimproblem;
prob.Objective = f;

定义约束

定义优化问题中的约束 g <= 0

prob.Constraints.nlcons1 = g <= 0;

还要定义约束 u 是对称的且 mineval-1/2

prob.Constraints.sym = u == u.';
prob.Constraints.mineval = mineval >= -1/2;

查看问题。

show(prob)
  OptimizationProblem : 

	Solve for:
       u, v

	minimize :
       [argout,~,~] = expfn3(u, v)


	subject to nlcons1:
       arg_LHS <= 0

       where:

             [~,arg_LHS,~] = expfn3(u, v);

	subject to sym:
       u(2, 1) - u(1, 2) == 0
       u(3, 1) - u(1, 3) == 0
       -u(2, 1) + u(1, 2) == 0
       u(3, 2) - u(2, 3) == 0
       -u(3, 1) + u(1, 3) == 0
       -u(3, 2) + u(2, 3) == 0

	subject to mineval:
       arg_LHS >= (-0.5)

       where:

             [~,~,arg_LHS] = expfn3(u, v);

	variable bounds:
       -1 <= u(1, 1) <= 1
       -1 <= u(2, 1) <= 1
       -1 <= u(3, 1) <= 1
       -1 <= u(1, 2) <= 1
       -1 <= u(2, 2) <= 1
       -1 <= u(3, 2) <= 1
       -1 <= u(1, 3) <= 1
       -1 <= u(2, 3) <= 1
       -1 <= u(3, 3) <= 1

       -2 <= v(1) <= 2
       -2 <= v(2) <= 2
       -2 <= v(3) <= 2

求解问题

要求解该问题,请调用 solve。设置初始点 x0

rng default % For reproducibility
x0.u = 0.25*randn(3);
x0.u = x0.u + x0.u.';
x0.v = 2*randn(3,1);
[sol,fval,exitflag,output] = solve(prob,x0)
Solving problem using fmincon.

Feasible point with lower objective function value found, but optimality criteria not satisfied. See output.bestfeasible..


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:
    u: [3x3 double]
    v: [3x1 double]

fval = -403.4288
exitflag = 
    OptimalSolution

output = struct with fields:
              iterations: 84
               funcCount: 1233
         constrviolation: 2.0777e-12
                stepsize: 3.3705e-04
               algorithm: 'interior-point'
           firstorderopt: 7.2829e-04
            cgiterations: 67
                 message: 'Local minimum found that satisfies the constraints....'
            bestfeasible: [1x1 struct]
     objectivederivative: "finite-differences"
    constraintderivative: "finite-differences"
                  solver: 'fmincon'

查看解。

disp(sol.u)
    0.9190    0.5579   -0.8611
    0.5579    0.6804    0.6225
   -0.8611    0.6225    0.9835
disp(sol.v)
    2.0000
   -2.0000
    2.0000

解矩阵 u 是对称矩阵。v 的所有值都在边界上。

Copyright 2018–2022 The MathWorks, Inc.

另请参阅

|

相关主题