Main Content

转换 for 循环中的约束以进行静态分析

静态分析提高了基于问题的表达式中 for 循环的速度,如 优化表达式的静态分析 中所述。静态分析适用于由 fcn2optimexpr 创建的表达式,而不适用于比较运算符 <===>=。因此,当您使用 for 循环创建约束时,从比较的两侧减去约束的右侧,以使比较结果为零或常数。然后应用 fcn2optimexpr

此示例对 i=1,2,...,20 有约束 xiu+i-1xi-u-i+1。首先创建优化变量。

N = 20;
x = optimvar("x",N);
u = optimvar("u");

为了在 for 循环中表达约束,请减去适当的值,以便将约束与 0 进行比较:

xi-u-i+10xi+u+i-10.

通常,您可以在以下代码中表达这些约束:

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

另请参阅

相关主题