Main Content

本页采用了机器翻译。点击此处可查看英文原文。

初始化优化表达式

本主题介绍优化表达式未正确初始化时发生的错误,并提供了求解该错误的不同方法的示例。

表达式中的错误

有时您会从目标或非线性约束函数或表达式收到此错误:

Unable to perform assignment because value of type 'optim.problemdef.OptimizationExpression' is not convertible
to 'double'.

通常,此错误是由于优化表达式的初始化不当造成的。通常,您可以通过声明一个零数组在标准循环中初始化变量 F,例如:

F = zeros(N,1);

但是,如果 F 是优化表达式,则必须使用 optimexpr 初始化它。

F = optimexpr(N,1);

本主题提供了正确的初始化技术的示例。所有这些都基于同一个示例,即使用内部循环的函数。

function f = myFun(x)
out = zeros(size(x));
out(1) = x(1);
for i = 2:10
    out(i) = (x(i) - x(i-1))^3;
end
f = mean(out);
end

如果您尝试使用 myFun(x) 作为优化变量 x 的目标函数,则会出错。

x = optimvar("x",10,LowerBound=0,UpperBound=10);
prob = optimproblem(Objective=myFun(x));
Unable to perform assignment because value of type 'optim.problemdef.OptimizationVariable' is not convertible
to 'double'.

Error in myFun (line 3)
out(1) = x(1);

Caused by:
    Error using double
    Conversion to double from optim.problemdef.OptimizationVariable is not possible.

然而,myFun 在基于求解器的问题中起着目标的作用。

rng default
x0 = 10*rand(10,1);
lb = zeros(10,1);
ub = 10 + lb;
[sol,fval] = fmincon(@myFun,x0,[],[],[],[],lb,ub)
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 =

    9.4226
   10.0000
    0.0000
    5.0000
   10.0000
    0.0000
    3.3333
    6.6667
   10.0000
    0.0000


fval =

 -262.9274

这个问题有几个局部解,因此您可能会根据您的起点获得不同的答案。

使用 "like" 语法初始化数组

重写该函数以使用 zeros"like" 参量。然后,您可以传递优化表达式或数字数组作为输入。

这种方法有几个优点:

  • 函数签名得以保留。

  • 该方法不会引入在解过程中运行的额外代码。

  • 如果适用,则启用自动区分。

  • 您可以在基于求解器或基于问题的工作流程中使用该函数。

  • 该方法在使用 fcn2optimexpr 时可实现静态分析。有关静态分析的信息,请参阅 优化表达式的静态分析

function f = myFun1(x)
out = zeros(size(x),"like",x);
out(1) = x(1);
for i = 2:10
    out(i) = (x(i) - x(i-1))^3;
end
f = mean(out);
end

在基于问题的工作流程中使用 myFun1

x = optimvar("x",10,LowerBound=0,UpperBound=10);
prob = optimproblem(Objective=myFun1(x));
rng default
x0.x = 10*rand(10,1);
[sol,fval] = 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: [10×1 double]


fval =

 -262.9274

在基于求解器的工作流程中使用 myFun1

rng default
x0 = 10*rand(10,1);
lb = zeros(10,1);
ub = 10 + lb;
[sol,fval] = fmincon(@myFun1,x0,[],[],[],[],lb,ub)
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 =

    9.4226
   10.0000
    0.0000
    5.0000
   10.0000
    0.0000
    3.3333
    6.6667
   10.0000
    0.0000


fval =

 -262.9274

修改函数以接受初始数组

重写该函数以接受初始值作为附加参量。然后,您可以传递优化表达式或数字数组作为初始值。myFun2 使用输入变量 out 作为输出变量,并接受零数组或优化表达式。

这种方法有几个优点:

  • 如果适用,则启用自动区分。

  • 该方法不会引入在解过程中运行的额外代码。

  • 您可以在基于求解器或基于问题的工作流程中使用该函数。

  • 该方法在使用 fcn2optimexpr 时可实现静态分析。有关静态分析的信息,请参阅 优化表达式的静态分析

这种方法的缺点是您必须使用不同的函数签名重写该函数。

function f = myFun2(out,x)
out(1) = x(1);
for i = 2:10
    out(i) = (x(i) - x(i-1))^3;
end
f = mean(out);
end

在基于问题的工作流程中使用 myFun2

x = optimvar("x",10,LowerBound=0,UpperBound=10);
out = optimexpr(size(x));
prob = optimproblem(Objective=myFun2(out,x));
rng default
x0.x = 10*rand(10,1);
[sol,fval] = 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: [10×1 double]


fval =

 -262.9274

在基于求解器的工作流程中使用 myFun2

rng default
x0 = 10*rand(10,1);
lb = zeros(10,1);
ub = 10 + lb;
out = zeros(size(x0));
[sol,fval] = fmincon(@(x)myFun2(out,x),x0,[],[],[],[],lb,ub)
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 =

    9.4226
   10.0000
    0.0000
    5.0000
   10.0000
    0.0000
    3.3333
    6.6667
   10.0000
    0.0000


fval =

 -262.9274

重写函数以适当地初始化表达式

您可以明确检查问题变量的类型并适当地初始化表达式。这种方法有几个优点:

  • 如果适用,则启用自动区分。

  • 您可以在基于求解器或基于问题的工作流程中使用该函数。

这种方法的缺点是您必须重写函数,求解器运行时会引入少量开销,并且由于 if 语句,并且在使用 fcn2optimexpr 时不支持静态分析(由于 if 语句)。有关静态分析的信息,请参阅 优化表达式的静态分析

function f = myFun3(x)
% Check for the data type of variable x
if isa(x,'double')
    out = zeros(size(x));
else
    out = optimexpr(size(x));
end
% No changes to the rest of the code
out(1) = x(1);
for i = 2:10
    out(i) = (x(i) - x(i-1))^3;
end
f = mean(out);
end

使用具有目标函数 myFun3 的优化变量求解问题。

x = optimvar("x",10,LowerBound=0,UpperBound=10);
prob = optimproblem(Objective=myFun3(x));
rng default
x0.x = 10*rand(10,1);
[sol,fval] = 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: [10×1 double]


fval =

 -262.9274

使用 fmincon 和目标函数 myFun3 求解问题。

rng default
x0 = 10*rand(10,1);
lb = zeros(10,1);
ub = 10 + lb;
out = zeros(size(x0));
[sol,fval] = fmincon(@myFun3,x0,[],[],[],[],lb,ub)
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 =

    9.4226
   10.0000
    0.0000
    5.0000
   10.0000
    0.0000
    3.3333
    6.6667
   10.0000
    0.0000


fval =

 -262.9274

使用 fcn2optimexpr 转换

对于 R2022b 及更高版本,您可以使用 fcn2optimexpr 将目标函数转换为优化表达式,然后使用标准零数组初始化该表达式。

这种方法有几个优点:

  • 函数签名得以保留。

  • 如果适用,则启用自动区分。

  • 您可以在基于求解器或基于问题的工作流程中使用该函数。

这种方法需要静态分析,因此它可能无法在早期的 MATLAB® 版本中正确运行,并且可能会产生一些开销。此示例使用原始函数 myFun,该函数在 表达式中的错误 中基于问题的工作流中失败。

x = optimvar("x",10,LowerBound=0,UpperBound=10);
obj = fcn2optimexpr(@myFun,x,Display="on");
prob = optimproblem(Objective=obj);
rng default
x0.x = 10*rand(10,1);
[sol,fval] = solve(prob,x0)
The function uses only supported operators. The returned expressions use the operators on the problem variables.

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: [10×1 double]


fval =

 -262.9274

另请参阅

|

相关主题