# 静的解析のための for ループの制約の変換

この例では、$i=1,2,...,20$ に対して ${x}_{i}\le u+i-1$${x}_{i}\ge -u-i+1$ の制約があります。まず最適化変数を作成します。

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

for ループの制約を表すには、制約が 0 と比較されるように適切な値を引きます。

$\begin{array}{c}{x}_{i}-u-i+1\le 0\\ {x}_{i}+u+i-1\ge 0.\end{array}$

for i = 1:N
cons1(i) = x(i) - u - i + 1;
cons2(i) = x(i) + u + i - 1;
end

[cons1,cons2] = fcn2optimexpr(@forloopfcn,x,u);

prob = optimproblem;
prob.Constraints.cons1 = cons1 <= 0;
prob.Constraints.cons2 = cons2 >= 0;

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)

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: []

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

### 補助関数

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