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

問題ベースのワークフローに導関数を含める

導関数を含める理由

この例では、問題ベースの非線形最適化に導関数情報を含める方法を説明します。最適化に勾配またはヘッシアンを含めると、次の利点があります。

  • より確実な結果が得られます。有限差分のステップでは、目的関数または非線形制約関数が未定義、有限ではない、または複雑である点に到達することがあります。

  • 解析勾配は、有限差分の推定値より精度が高い場合があります。

  • ヘッシアンを含めることによって収束が早くなる、つまり反復回数が少なくなる可能性があります。

  • 解析勾配は、特にスパース構造を持つ問題の場合に、有限差分の推定値より早く計算できます。ただし、複雑な式の場合には、解析勾配は計算が遅くなることがあります。

これらの利点がある一方で、問題ベースのアプローチでは現在、導関数情報が使用されません。問題ベースの最適化で導関数を使用するには、prob2struct を使用して問題を変換し、結果として得られる目的関数と制約関数を編集します。

最適化問題の作成

問題ベースの非線形最適化を作成します。2 次元制御変数 x および y を使って、次の目的関数を使用します。

fun1=100(x2x12)2+(1x1)2fun2=exp((xiyi)2)exp(exp(y1))sech(y2)objective = fun1 fun2.

xy の二乗和が 4 以下になるという制約を含めます。

fun2 は最適化式向けにサポートされている関数に基づくものではありません。最適化変数および式でサポートされる演算を参照してください。そのため、fun2 を最適化問題に含めるには、fcn2optimexpr を使用して最適化式に変換しなければなりません。

prob = optimproblem;
x = optimvar('x',2);
y = optimvar('y',2);
fun1 = 100*(x(2) - x(1)^2)^2 + (1 - x(1))^2;
fun2 = @(x,y)-exp(-sum((x - y).^2))*exp(-exp(-y(1)))*sech(y(2));
prob.Objective = fun1 + fcn2optimexpr(fun2,x,y);
prob.Constraints.cons = sum(x.^2 + y.^2) <= 4;

ソルバーベース形式への問題の変換

導関数を含めるには、prob2struct を使用して問題を構造体に変換します。

problem = prob2struct(prob);

変換中に、prob2struct は目的関数と非線形制約関数を表す関数ファイルを作成します。既定では、これらの関数の名前は 'generatedObjective.m''generatedConstraints.m' です。

導関数の計算と変数の追跡

目的関数と非線形制約関数に関連付けられた導関数を計算します。Symbolic Math Toolbox™ ライセンスをお持ちの場合は、関数 gradient (Symbolic Math Toolbox) または jacobian (Symbolic Math Toolbox) を使用して導関数の計算に役立てることができます。詳細は、Symbolic Math Toolbox™ による勾配とヘッシアンの計算を参照してください。

ソルバーベースのアプローチには 1 つの制御変数があります。各最適化変数 (この例では x または y) は制御変数の一部です。

生成された目的関数ファイル 'generatedObjective.m' で、最適化変数と単一の制御変数の間のマッピングを確認できます。ファイルの最初には次のコード行が含まれます。

%% Variable indices.
idx_x = [1 2];
idx_y = [3 4];

%% Map solver-based variables to problem-based.
x = inputVariables(idx_x);
x = x(:);
y = inputVariables(idx_y);
y = y(:);

このコードで、制御変数の名前は inputVariables です。

または、varindex を使用してマッピングを確認できます。

idx = varindex(prob);
disp(idx.x)
     1     2
disp(idx.y)
     3     4

マッピングを確認したら、標準微積分を使用して、制御変数 [x(:);y(:)] に関する目的関数 objective = fun1 + fun2 の勾配 grad の式を次のように求めることができます。

gradfun2=[σ1σ2σ1+dexp(y1)σ2dtanh(y2)],

ここで、

d=fun2(x;y)σ1=2(x1y1)dσ2=2(x2y2)d.

目的関数ファイルと制約ファイルの編集

目的関数ファイルに計算された勾配を含めるには、次のように 'generatedObjective.m' を編集します。

%% Insert gradient calculation here.
% If you include a gradient, notify the solver by setting the
% SpecifyObjectiveGradient option to true.
if nargout > 1
    c = exp(-sum((x - y).^2));
    d = c*exp(-exp(-y(1)))*sech(y(2));
    sigma1 = 2*(x(1) - y(1))*d;
    sigma2 = 2*(x(2) - y(2))*d;
    grad = zeros(4,1);
    grad(1) = 2*x(1) - 400*x(1)*(x(2) - x(1)^2) + sigma1 - 2;
    grad(2) = 200*x(2) - 200*x(1)^2 + sigma2;
    grad(3) = -sigma1 - d*exp(-y(1));
    grad(4) = -sigma2 + d*tanh(y(2));
end

非線形制約は x(1)^2 + x(2)^2 + y(1)^2 + y(2)^2 <= 4 であることを思い出してください。この制約関数の勾配が 2*[x;y] であることは明らかです。非線形制約の計算された勾配を含めるには、次のように 'generatedConstraints.m' を編集します。

%% Insert gradient calculation here.
% If you include a gradient, notify the solver by setting the
% SpecifyConstraintGradient option to true.
if nargout > 2
    cineqGrad = 2*[x;y];
    ceqGrad = [];
end

2 つの方法を使用した問題の実行

問題ベースの方法とソルバーベースの方法の両方を使用して問題を実行し、違いを確認します。導関数情報を使用して問題を実行するには、問題構造体に適切なオプションを作成します。

options = optimoptions('fmincon','SpecifyObjectiveGradient',true,...
    'SpecifyConstraintGradient',true);
problem.options = options;

非線形問題では、問題構造体の x0 フィールドが空でないことが必要です。

x0 = [-1;2;1;-1];
problem.x0 = x0;

問題構造体に対して fmincon を呼び出します。

[xsolver,fvalsolver,exitflagsolver,outputsolver] = fmincon(problem)
Local 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>

xsolver =

    0.8671
    0.7505
    1.0433
    0.5140


fvalsolver =

   -0.5500


exitflagsolver =

     1


outputsolver = 

  struct with fields:

         iterations: 46
          funcCount: 77
    constrviolation: 0
           stepsize: 7.4091e-06
          algorithm: 'interior-point'
      firstorderopt: 7.5203e-07
       cgiterations: 9
            message: '↵Local 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 first-order optimality measure, 7.520304e-07,↵is less than options.OptimalityTolerance = 1.000000e-06, and the relative maximum constraint↵violation, 0.000000e+00, is less than options.ConstraintTolerance = 1.000000e-06.↵↵'

この解と、導関数情報を使用しない solve から取得した解を比較します。

init.x = x0(1:2);
init.y = x0(3:4);
[xproblem,fvalproblem,exitflagproblem,outputproblem] = solve(prob,init)
Local 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>

xproblem = 

  struct with fields:

    x: [2×1 double]
    y: [2×1 double]


fvalproblem =

   -0.5500


exitflagproblem = 

    OptimalSolution


outputproblem = 

  struct with fields:

         iterations: 48
          funcCount: 276
    constrviolation: 0
           stepsize: 7.9340e-07
          algorithm: 'interior-point'
      firstorderopt: 6.5496e-07
       cgiterations: 9
            message: '↵Local 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 first-order optimality measure, 6.549635e-07,↵is less than options.OptimalityTolerance = 1.000000e-06, and the relative maximum constraint↵violation, 0.000000e+00, is less than options.ConstraintTolerance = 1.000000e-06.↵↵'
             solver: 'fmincon'

どちらの解でも精度を表示する関数値は同じ値が報告されており、どちらの解もほぼ同じ回数の反復 (勾配情報を使用する場合は 46 回、使用しない場合は 48 回) を必要としています。ただし、勾配を使用しない解では 276 回の関数評価が必要であるのに対し、勾配を使用する解では関数評価が 77 回しか必要ありません。

参考

| |

関連するトピック