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

解析的ヘッシアンを使用した fmincon の内点法アルゴリズム

fmincon の内点法アルゴリズムは入力にヘッセ関数を受け入れることができます。ヘッシアンを与えると、制約付き最小化問題は効率的に解くことができ、より正確な解を得ることができます。

この例の制約集合は 2 つの円錐の内部交差部分です。1 つの円錐は上向きで、もう 1 つの円錐は下向きです。制約関数 c は各円錐に 1 要素ずつあるため 2 要素のベクトルになります。これは 3 次元の例であるため、制約 c の勾配は 3 行 2 列の行列です。

function [c ceq gradc gradceq] = twocone(x)
% This constraint is two cones, z > -10 + r
% and z < 3 - r

ceq = [];
r = sqrt(x(1)^2 + x(2)^2);
c = [-10+r-x(3);
    x(3)-3+r];

if nargout > 2

    gradceq = [];
    gradc = [x(1)/r,x(1)/r;
       x(2)/r,x(2)/r;
       -1,1];

end
x(1) 座標が負の場合、目的関数は急速に負になります。その勾配は 3 要素のベクトルです。
function [f gradf] = bigtoleft(x)
% This is a simple function that grows rapidly negative
% as x(1) gets negative
%
f=10*x(1)^3+x(1)*x(2)^2+x(3)*(x(1)^2+x(2)^2);

if nargout > 1

   gradf=[30*x(1)^2+x(2)^2+2*x(3)*x(1);
       2*x(1)*x(2)+2*x(3)*x(2);
       (x(1)^2+x(2)^2)];

end
以下はこの問題のプロットです。色の違いにより目的関数の値を表します。目的関数が x = [-6.5,0,-3.5] のまわりで最小化されていることがわかります。

 図を生成するコード

ラグランジュ関数のヘッシアンは以下の式によって与えられます。

xx2L(x,λ)=2f(x)+λi2ci(x)+λi2ceqi(x).

以下の関数は点 x でのヘッシアンをラグランジュ乗数構造体 lambda を用いて計算します。

function h = hessinterior(x,lambda)

h = [60*x(1)+2*x(3),2*x(2),2*x(1);
    2*x(2),2*(x(1)+x(3)),2*x(2);
    2*x(1),2*x(2),0];% Hessian of f
r = sqrt(x(1)^2+x(2)^2);% radius
rinv3 = 1/r^3;
hessc = [(x(2))^2*rinv3,-x(1)*x(2)*rinv3,0;
    -x(1)*x(2)*rinv3,x(1)^2*rinv3,0;
    0,0,0];% Hessian of both c(1) and c(2)
h = h + lambda.ineqnonlin(1)*hessc + lambda.ineqnonlin(2)*hessc;

fmincon の内点法アルゴリズムを使用してこの問題を実行します。最適化アプリを使用してこれを行うには以下のようにします。

  1. 以下の図のように問題を設定します。

  2. 反復出力の場合は、[オプション] ペインの下部へスクロールし、[表示レベル][各反復] を選択します。

  3. [オプション] ペインに解析的なヘッセ関数ハンドルを与えます。

  4. [ソルバーを実行して結果を表示] の下にある [開始] をクリックします。

コマンド ラインで最小化を行うには以下のようにします。

  1. 以下のように options を設定します。

    options = optimoptions(@fmincon,'Algorithm','interior-point',...
            'Display','off','SpecifyObjectiveGradient',true,'SpecifyConstraintGradient',true,...
            'HessianFcn',@hessinterior);
  2. options 構造体を使用して初期点を [–1,–1,–1] とし、fmincon を実行します。

    [x,fval,mflag,output] = fmincon(@bigtoleft,[-1,-1,-1],...
               [],[],[],[],[],[],@twocone,options);

解、目的関数値、終了フラグおよび関数の評価と反復の回数を調べます。

x,fval,mflag,output.funcCount,output.iterations
x =

   -6.5000   -0.0000   -3.5000


fval =

  -2.8941e+03


mflag =

     1


ans =

     7


ans =

     6

ヘッセ関数を使用しない場合、fmincon は収束するまでに 6 回ではなく 9 回の反復を行います。

options = optimoptions(@fmincon,'Algorithm','interior-point',...
        'Display','off','SpecifyObjectiveGradient',true,'SpecifyConstraintGradient',true);

[x fval mflag output]=fmincon(@bigtoleft,[-1,-1,-1],...
           [],[],[],[],[],[],@twocone,options);

x,output.funcCount,output.iterations

x =

   -6.5000   -0.0000   -3.5000


ans =

    13


ans =

     9
両方の実行結果は同様の解になりますが、F-count と反復数は解析的なヘッシアンを使うと小さくなります。

関連するトピック