初始化优化表达式
本主题介绍优化表达式未正确初始化时发生的错误,并提供了求解该错误的不同方法的示例。
表达式中的错误
有时您会从目标或非线性约束函数或表达式收到此错误:
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