メインコンテンツ

And 制約に代わる Or 制約の使用

R2026b

一般的に、ソルバーは次のような暗黙的 AND による制約を受け入れます。

制約 1 AND 制約 2 AND 制約 3 がすべて満たされる。

しかし、次のように OR を使用するのが望ましい場合もあります。

制約 1 OR 制約 2 OR 制約 3 が満たされる。

これらの定式化は論理的に等価ではなく、一般に、OR 制約を AND 制約で表現する方法はありません。

ヒント

幸い、非線形制約は非常に柔軟です。非線形関数を制約関数の最小値に設定するだけで、OR 制約は実現されます。

最小値を制約として設定できる理由は非線形制約の性質にあります。与える制約は、実行可能な点において負になるべき一連の関数となります。次のような制約があるとします。

F1(x) ≤ 0 OR F2(x) ≤ 0 OR F3(x) ≤ 0

この場合は、非線形不等式制約関数 ineqnonlin(x) を次のように設定します。

ineqnonlin(x) = min(F1(x),F2(x),F3(x))

最小値のため、ineqnonlin(x) は滑らかではありません。これは制約関数における一般的な要件です。しかし、この方法は多くの場合うまく機能します。

メモ

OR 制約で通常の範囲や線形制約を使用することはできません。代わりに、この例のように範囲と線形制約を非線形制約関数に変換します。

たとえば、実行可能領域が L 字型の領域だとします。x は四角形 –1 ≤ x(1) ≤ 1, 0 ≤ x(2) ≤ 1 の内部に存在するか、x は四角形 0 ≤ x(1) ≤ 1, –1 ≤ x(2) ≤ 1 の内部に存在します (OR 制約)。

L-shaped region

% Write the x and y coordinates of the figure, clockwise from (0,0)
x = [0,-1,-1,1,1,0,0];
y = [0,0,1,1,-1,-1,0];
plot(x,y)
xlim([-1.2 1.2])
ylim([-1.2 1.2])
axis equal

四角形を範囲の制約ではなく非線形制約として表現するために、四角形 a ≤ x(1) ≤ b, c ≤ x(2) ≤ d の内部で負値をとる関数を作成します。

function cout = rectconstr(x,a,b,c,d)
% Negative when  x is in the rectangle [a,b][c,d]
% First check that a,b,c,d are in the correct order

if (b <= a) || (d <= c)
    error("Give a rectangle a < b, c < d")
end

cout = max([(x(1)-b),(x(2)-d),(a-x(1)),(c-x(2))]);
end

非線形制約関数の最小値を使用する規定に従うと、L 字型の領域で非線形制約関数は次のようになります。

function [ineqnonlin,eqnonlin] = rectconstrfcn(x)

eqnonlin = []; % no equality constraint
F(1) = rectconstr(x,-1,1,0,1); % one rectangle
F(2) = rectconstr(x,0,1,-1,1); % another rectangle
ineqnonlin = min(F); % for OR constraints
end

L-shaped region with nonlinear constraints color-coded

a = –1, b = 1, c = 0, d = 1 に対し、rectconstrfcn を領域 max|x| ≤ 2 上でプロットします。

[xx,yy] = meshgrid(-2:.1:2);
x = [xx(:),yy(:)]; % one row per point

z = zeros(length(x),1); % allocate 
for ii = 1:length(x)
    [z(ii),~] = rectconstrfcn(x(ii,:));
end

z = reshape(z,size(xx));
surf(xx,yy,z)
colorbar
axis equal
xlabel("x");ylabel("y")
view(0,90)

次のような目的関数について考えます。

fun = @(x)exp(x(1)) * (4*x(1)^2 + 2*x(2)^2 + 4*x(1)*x(2) + 2*x(2) + 1);

fun を L 字型の領域で最小化します。

opts = optimoptions(@fmincon,Algorithm="interior-point",Display="off");
x0 = [-.5,.6]; % an arbitrary guess
[xsol,fval,eflag] = fmincon(fun,x0,[],[],[],[],[],[],@rectconstrfcn,opts)
xsol =

    0.4998   -0.9996


fval =

   2.4650e-07


eflag =

     1

明らかに、解 xsol は L 字型領域の内部にあります。終了フラグは 1 で、xsol が局所的最小値であることを示しています。

参考

トピック