转换 for
循环中的约束以进行静态分析
静态分析提高了基于问题的表达式中 for
循环的速度,如 优化表达式的静态分析 中所述。静态分析适用于由 fcn2optimexpr
创建的表达式,而不适用于比较运算符 <=
、==
和 >=
。因此,当您使用 for
循环创建约束时,从比较的两侧减去约束的右侧,以使比较结果为零或常数。然后应用 fcn2optimexpr
。
此示例对 有约束 和 。首先创建优化变量。
N = 20; x = optimvar("x",N); u = optimvar("u");
为了在 for
循环中表达约束,请减去适当的值,以便将约束与 0 进行比较:
通常,您可以在以下代码中表达这些约束:
for i = 1:N cons1(i) = x(i) - u - i + 1; cons2(i) = x(i) + u + i - 1; end
要应用静态分析,请将此 for
循环放在名为 forloopfcn
的单独辅助函数中。生成的函数出现在本示例的末尾。(您可以轻松地将脚本中的 for
循环转换为单独的函数,如 创建 for 循环进行静态分析 所示。)
为了利用静态分析,请使用 fcn2optimexpr
将函数转换为优化表达式。
[cons1,cons2] = fcn2optimexpr(@forloopfcn,x,u);
创建一个优化问题,并将这些约束放在该问题中。
prob = optimproblem; prob.Constraints.cons1 = cons1 <= 0; prob.Constraints.cons2 = cons2 >= 0;
创建一个目标函数,它是 u
变量的加权和与向量 1.5*(1:N)
中 x
变量的平方差和。
M = 100; % Weight factor for u
prob.Objective = M*u + sum((x - 1.5*(1:N)').^2);
检查此问题。
show(prob)
OptimizationProblem : Solve for: u, x minimize : x(1)^2 + x(2)^2 + x(3)^2 + x(4)^2 + x(5)^2 + x(6)^2 + x(7)^2 + x(8)^2 + x(9)^2 + x(10)^2 + x(11)^2 + x(12)^2 + x(13)^2 + x(14)^2 + x(15)^2 + x(16)^2 + x(17)^2 + x(18)^2 + x(19)^2 + x(20)^2 + 100*u - 3*x(1) - 6*x(2) - 9*x(3) - 12*x(4) - 15*x(5) - 18*x(6) - 21*x(7) - 24*x(8) - 27*x(9) - 30*x(10) - 33*x(11) - 36*x(12) - 39*x(13) - 42*x(14) - 45*x(15) - 48*x(16) - 51*x(17) - 54*x(18) - 57*x(19) - 60*x(20) + 6457.5 subject to cons1: -u + x(1) <= 0 -u + x(2) <= 1 -u + x(3) <= 2 -u + x(4) <= 3 -u + x(5) <= 4 -u + x(6) <= 5 -u + x(7) <= 6 -u + x(8) <= 7 -u + x(9) <= 8 -u + x(10) <= 9 -u + x(11) <= 10 -u + x(12) <= 11 -u + x(13) <= 12 -u + x(14) <= 13 -u + x(15) <= 14 -u + x(16) <= 15 -u + x(17) <= 16 -u + x(18) <= 17 -u + x(19) <= 18 -u + x(20) <= 19 subject to cons2: u + x(1) >= 0 u + x(2) >= -1 u + x(3) >= -2 u + x(4) >= -3 u + x(5) >= -4 u + x(6) >= -5 u + x(7) >= -6 u + x(8) >= -7 u + x(9) >= -8 u + x(10) >= -9 u + x(11) >= -10 u + x(12) >= -11 u + x(13) >= -12 u + x(14) >= -13 u + x(15) >= -14 u + x(16) >= -15 u + x(17) >= -16 u + x(18) >= -17 u + x(19) >= -18 u + x(20) >= -19
求解。
[sol,fval,exitflag,output] = solve(prob)
Solving problem using quadprog. 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. <stopping criteria details>
sol = struct with fields:
u: 4.1786
x: [20×1 double]
fval = 653.3036
exitflag = OptimalSolution
output = struct with fields:
message: '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.↵↵<stopping criteria details>↵↵Optimization completed: The relative dual feasibility, 1.421085e-16,↵is less than options.OptimalityTolerance = 1.000000e-08, the complementarity measure,↵1.536130e-10, is less than options.OptimalityTolerance, and the relative maximum constraint↵violation, 0.000000e+00, is less than options.ConstraintTolerance = 1.000000e-08.'
algorithm: 'interior-point-convex'
firstorderopt: 6.1445e-09
constrviolation: 0
iterations: 8
linearsolver: 'sparse'
cgiterations: []
solver: 'quadprog'
查看解中的 x
变量。
disp(sol.x)
1.5000 3.0000 4.5000 6.0000 7.5000 9.0000 10.1786 11.1786 12.1786 13.1786 14.1786 15.1786 16.1786 17.1786 18.1786 19.1786 20.1786 21.1786 22.1786 23.1786
查看解处的约束函数值。
evaluate(cons1,sol)
ans = 1×20
-2.6786 -2.1786 -1.6786 -1.1786 -0.6786 -0.1786 -0.0000 -0.0000 -0.0000 -0.0000 -0.0000 -0.0000 -0.0000 -0.0000 -0.0000 -0.0000 -0.0000 -0.0000 -0.0000 -0.0000
evaluate(cons2,sol)
ans = 1×20
5.6786 8.1786 10.6786 13.1786 15.6786 18.1786 20.3571 22.3571 24.3571 26.3571 28.3571 30.3571 32.3571 34.3571 36.3571 38.3571 40.3571 42.3571 44.3571 46.3571
cons1
约束指定该值为非正数。cons1
的前六个值为负数,其余值为零以显示精度。因此,在解中,cons1
约束对于除前六个值之外的所有值都有效。相反,cons2
约束指定该值是非负的。cons2
的所有值都严格为正值,这意味着此约束在解中不起作用。
辅助函数
以下代码创建 forloopfcn
辅助函数。
function [cons1,cons2] = forloopfcn(x,u) N = length(x); cons1 = zeros(1,N); cons2 = zeros(1,N); for i = 1:N cons1(i) = x(i) - u - i + 1; cons2(i) = x(i) + u + i - 1; end end