ドキュメンテーション センター

  • 評価版
  • 製品アップデート

最新のリリースでは、このページがまだ翻訳されていません。 このページの最新版は英語でご覧になれます。

制約の記述

制約の種類

Optimization Toolbox™ のソルバーには制約を定義する特定の形式があります。

  • 範囲制約 — 個々の要素の上限と下限。x ≥ l と x ≤ u です。

  • 線形不等式制約 — A·x ≤ b。A は m 行 n 列の行列で、n 次元のベクトル x に対する m の制約を表しています。b は m 次元です。

  • 線形等式制約 — Aeq·x = beq。等式制約は不等式制約と同じ形式をもっています。

  • 非線形制約 — c(x) ≤ 0 かつ ceq(x) = 0。c と ceq は、いくつかの制約を示すスカラーまたはベクトルです。

Optimization Toolbox 関数は ci(x) ≤ 0 または A x ≤ b の形式の不等式制約を仮定します。大なり記号の制約は、-1 を乗算して小なり記号の制約として表現します。たとえば、ci(x) ≥ 0 の形式の制約は –ci(x) ≤ 0 の制約と同じです。A·x ≥ b の形式の制約は –A·x ≤ –b の制約と同じです。詳細は 線形不等式制約非線形制約 を参照してください。

制約は、いくつかの方法で記述できる場合があります。最適な結果を得るために、使用する制約はできるだけ少なくしてください。

  1. 範囲

  2. 線形等式

  3. 線形不等式

  4. 非線形等式

  5. 非線形不等式

たとえば、制約 5 x ≤ 20 の場合、線形不等式または非線形不等式ではなく、x ≤ 4 の範囲を使用します。

追加パラメーターを制約関数に受け渡す方法は 追加パラメーターの受け渡し を参照してください。

反復は制約に違反する可能性あり

目的関数と制約関数を記述するときに気を付けてください。中間的な反復は、実行不可能な (制約を満たさない) 点を導くことがあります。実行可能性を仮定して目的関数または制約関数を記述する場合は、これらの関数はエラーを発生するか、予期しない結果をもたらすことがあります。

たとえば、x や x < 0 の平方根または対数を取ると、結果は実数にはなりません。0 を x の下限として設定することにより、このエラーを避けることはできます。しかし、中間的な反復はこの範囲に違反する可能性があります。

範囲制約を満たすアルゴリズム

一部のソルバー アルゴリズムは、すべての反復で範囲制約を満たします。

  • fmincon interior-pointsqp、および trust-region-reflective アルゴリズム

  • lsqcurvefit trust-region-reflective アルゴリズム

  • lsqnonlin trust-region-reflective アルゴリズム

  • fminbnd

    メモ:   下限を上限と等しく設定すると、反復がこれらの制約に違反することがあります。

範囲制約に違反できるソルバーとアルゴリズム

次のソルバーとアルゴリズムは、中間の反復で範囲制約に違反することができます。

  • fmincon active-set アルゴリズム

  • fgoalattain ソルバー

  • fminimax ソルバー

  • fseminf ソルバー

範囲制約

上限と下限は、解 x の成分を制限します。

最適解の位置の範囲を知っている場合は、これらの範囲を明示的に問題の式に含めることで、より速く信頼できる解を得ることができます。

範囲は x と同じ長さのベクトルとして、または x と同じ要素数の行列として与えます。

  • 特定成分に下限がない場合は、範囲として -Inf を使用します。同様に、上限がない場合は Inf を使用します。

  • 片側の範囲 (上限または下限) しかない場合は、他方を記述する必要はありません。たとえば上限がない場合は、Inf のベクトルを指定する必要はありません。

  • n 個のコンポーネントのうち最初の m 個のみが範囲をもつ場合は、範囲を含む長さ m のベクトルを指定するだけで済みます。ただし、このショートカットではソルバーで警告が発生します。

たとえば、範囲が

x3 ≥ 8
x2 ≤ 3.

の場合、制約ベクトルは以下のように記述します。

l = [-Inf; -Inf; 8]
u = [Inf; 3] (警告を発生) または u = [Inf; 3; Inf]

範囲制約に勾配を与える必要はありません。ソルバーが自動的に勾配を計算します。範囲はヘッセ行列に影響を与えません。

より複雑な範囲の例については、「線形計画法の設定」を参照してください。

線形不等式制約

線形不等式制約は A·x ≤ b の形式になります。A が m 行 n 列の場合、n 個の要素をもつ変数 x に対し m 個の制約条件があります。m 行 n 列の行列 A と m 要素のベクトル b を入力します。

初期点 x0 を行列として渡す場合でも、ソルバーは現在の点 x を列ベクトルとして線形制約に渡します。「行列引数」を参照してください。

たとえば、以下の線形不等式制約について考えてみましょう。

x1 + x3 ≤ 4,
2x2 – x3 ≥ –2,
x1 – x2 + x3 – x4 ≥ 9.

ここで、m = 3、n = 4 です。

以下の行列 A とベクトル b を使用して、これらを記述します。

"大なり" の不等式は -1 を乗算して "小なり" の不等式の形式に変換されていることに注意してください。MATLAB® 構文では次のようになります。

A = [1 0 1 0;
    0 -2 1 0;
    -1 1 -1 1];
b = [4;2;-9];

線形制約に勾配を与える必要はありません。ソルバーが自動的に勾配を計算します。線形制約はヘッセ行列に影響を与えません。

より複雑な線形制約の例については、「線形計画法の設定」を参照してください。

線形等式制約

線形等式は Aeq·x = beq の形式をもちます。これは n 要素のベクトル x をもつ m 個の等式を表します。m 行 n 列の行列 Aeq と m 要素のベクトル beq を入力します。

線形制約に勾配を与える必要はありません。ソルバーが自動的に勾配を計算します。線形制約はヘッセ行列に影響を与えません。この種類の形式の制約は、「線形不等式制約」と同じです。

非線形制約

非線形不等式制約は c(x) ≤ 0 の形式をもちます。ここで c は制約のベクトルであり、各制約に 1 つの要素が対応します。同様に、非線形等式制約は ceq(x) = 0 の形式になります。

    メモ:   非線形制約関数は cceq、つまり不等式と等式制約の両方を必ず出力します。これは両方共が存在しない場合でも当てはまります。存在しない制約には空の [] を返します。

たとえば、以下の不等式制約を考えてみましょう。

この制約に対して関数ファイルの記述は以下のようになります。

function [c,ceq]=ellipseparabola(x)
c(1) = (x(1)^2)/9 + (x(2)^2)/4 - 1;
c(2) = x(1)^2 - x(2) - 1;
ceq = [];
end

ellipseparabola は、非線形等式関数 ceq に空の [] を返します。また両方の不等式は ≤ 0 の形式にします。

制約関数に勾配を含める

c と ceq の勾配を指定すると、ソルバーの実行速度が上がり、より信頼できる結果が得られます。

勾配を与えることで別の利点があります。ソルバーは、x が実現可能であるような点 x に到達できますが、x の周囲の有限差分は常に実行不可能な点を導きます。この場合、ソルバーは失敗するか途中で停止する可能性があります。勾配を与えることで、ソルバーは続行できます。

勾配情報を含めるには以下のように条件付きの関数を記述します。

function [c,ceq,gradc,gradceq]=ellipseparabola(x)
c(1) = x(1)^2/9 + x(2)^2/4 - 1;
c(2) = x(1)^2 - x(2) - 1;
ceq = [];

if nargout > 2
    gradc = [2*x(1)/9, 2*x(1); ...
             x(2)/2, -1];
    gradceq = [];
end

条件付き関数の詳細は、「スカラー目的関数の記述」を参照してください。勾配行列は以下の形式をもちます。

gradci, j = [∂c(j)/∂xi].

勾配行列の最初の列は c(1) と関連し、2 番目の列は c(2) と関連します。これはヤコビ行列の転置型になります。

ソルバーに非線形制約の勾配を使用させるには、optimoptions を使用してこれらが存在することを指示します。

options=optimoptions(@fmincon,'GradConstr','on');

options 構造体をソルバーに渡すようにしてください。

[x,fval] = fmincon(@myobj,x0,A,b,Aeq,beq,lb,ub, ...
           @ellipseparabola,options)

Symbolic Math Toolbox™ のライセンスをおもちの場合は、勾配とヘッセ行列を自動的に計算することができます (Symbolic Math Toolbox による勾配とヘッセ行列の計算を参照)。

非線形制約の無名関数

無名目的関数の詳細は、「無名関数の目的関数」を参照してください。

非線形制約関数では、2 つの出力が返されなければなりません。最初の出力は非線形不等式に、2 番目の出力は非線形等式に対応します。

無名関数は 1 つの出力のみを返します。では、無名関数を非線形制約として記述するにはどうすればよいでしょうか。

関数 deal は複数の出力を生成します。たとえば、非線形不等式が以下のようであるとします。

また、非線形等式は以下のようであるとします。

x2 = tanh(x1)

非線形制約関数は以下のように記述します。

c = @(x)[x(1)^2/9 + x(2)^2/4 - 1;
        x(1)^2 - x(2) - 1];
ceq = @(x)tanh(x(1)) - x(2);
nonlinfcn = @(x)deal(c(x),ceq(x));

関数 cosh(x1) + sinh(x2) を nonlinfcn の制約に従って最小化するには、次のように fmincon を使用します。

obj = @(x)cosh(x(1))+sinh(x(2));
opts = optimoptions(@fmincon,'Algorithm','sqp');
z = fmincon(obj,[0;0],[],[],[],[],[],[],nonlinfcn,opts)

Local minimum found that satisfies the constraints.

Optimization completed because the objective function is 
non-decreasing in feasible directions, to within the default 
value of the function tolerance, and constraints are satisfied 
to within the default value of the constraint tolerance.

z =
   -0.6530
   -0.5737

結果の点 z が制約をどの程度満たすかをチェックするには、nonlinfcn を使用します。

[cout,ceqout] = nonlinfcn(z)

cout =
   -0.8704
         0

ceqout =
     1.1102e-016

z は実際、TolCon 制約の既定の許容誤差、1e-6 内ですべての制約を満たしています。

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

一般的に、ソルバーは次のような暗黙的 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

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

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

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

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

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

 Figure を作成するコード

四角形を範囲の制約ではなく非線形制約として表現するために、四角形 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))]);

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

function [c,ceq] = rectconstrfcn(x)

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

 Figure を作成するコード

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

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,output] = fmincon(fun,x0,[],[],[],[],[],[],@rectconstrfcn,opts)
xsol =

    0.4998   -0.9996


fval =

   2.4649e-07


eflag =

     1


output = 

         iterations: 17
          funcCount: 59
    constrviolation: 0
           stepsize: 1.8763e-04
          algorithm: 'interior-point'
      firstorderopt: 4.9302e-07
       cgiterations: 0
            message: [1x777 char]

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

すべての制約タイプの使用方法

この節では、すべての制約タイプが利用できる非線形最小化問題の例を示します。目的関数はローカル関数 myobj(x) 内にあります。非線形制約はローカル関数 myconstr(x) 内にあります。この例は勾配を使用しません。

function [x fval exitflag] = fullexample
x0 = [1; 4; 5; 2; 5];
lb = [-Inf; -Inf;  0; -Inf;   1];
ub = [ Inf;  Inf; 20];
Aeq = [1 -0.3 0 0 0];
beq = 0;
A = [0 0  0 -1  0.1
     0 0  0  1 -0.5
     0 0 -1  0  0.9];
b = [0; 0; 0];
opts = optimoptions(@fmincon,'Algorithm','sqp');
     
[x,fval,exitflag]=fmincon(@myobj,x0,A,b,Aeq,beq,lb,ub,...
                                  @myconstr,opts)

%---------------------------------------------------------
function f = myobj(x)

f = 6*x(2)*x(5) + 7*x(1)*x(3) + 3*x(2)^2;

%---------------------------------------------------------
function [c, ceq] = myconstr(x)

c = [x(1) - 0.2*x(2)*x(5) - 71
     0.9*x(3) - x(4)^2 - 67];
ceq = 3*x(2)^2*x(5) + 3*x(1)^2*x(3) - 20.875;

fullexample を呼び出すと、コマンド ウィンドウに以下が表示されます。

[x fval exitflag] = fullexample;

Local minimum found that satisfies the constraints.

Optimization completed because the objective function is non-decreasing in 
feasible directions, to within the default value of the function tolerance,
and constraints are satisfied to within the default value of the constraint tolerance.

x =
    0.6114
    2.0380
    1.3948
    0.1572
    1.5498

fval =
   37.3806

exitflag =
     1
この情報は役に立ちましたか?