Main Content

勾配付き非線形制約

この例では、導関数情報を使用して、非線形制約のある非線形問題を解く方法を説明します。

通常、最小化ルーチンでは、有限差分近似により計算された数値勾配を使用します。この手続きは、関数および制約の偏導関数を計算するために、各変数にシステマチックな摂動を与えます。または、関数を与えて解析的に偏導関数を計算することができます。通常、導関数情報を提供すると、ソルバーはより正確かつ効率的に動作します。

目的関数と非線形制約

問題は、次の式を解くことです。

minxf(x)=ex1(4x12+2x22+4x1x2+2x2+1),

以下の制約に従います。

x1x2-x1-x2-1.5x1x2-10.

fmincon ソルバーは c(x) 0 の形式で記述される制約を前提としているため、次の値を返すように制約関数を記述します。

c(x)=[x1x2-x1-x2+1.5-10-x1x2].

勾配のある目的関数

目的関数は次のとおりです。

f(x)=ex1(4x12+2x22+4x1x2+2x2+1).

f(x) の勾配を変数 x1 および x2 に関して計算します。

f(x)=[f(x)+exp(x1)(8x1+4x2)exp(x1)(4x1+4x2+2)].

補助関数 objfungrad (この例の終わりに掲載) は、目的関数 f(x)、および 2 番目の出力 gradf においてその目的関数の勾配の両方を返します。@objfungrad を目的として設定します。

fun = @objfungrad;

勾配のある制約関数

補助関数 confungrad (この例の終わりに掲載) が非線形制約関数になります。

不等式制約の導関数情報には、1 つの制約に対応する各々の列が含まれます。つまり、制約の勾配は、次のような形式になります。

[c1x1c2x1c1x2c2x2]=[x2-1-x2x1-1-x1].

@confungrad を非線形制約関数として設定します。

nonlcon = @confungrad;

導関数情報を使用するためのオプションの設定

fmincon ソルバーに対し、目的関数と制約関数が導関数情報を提供することを示します。これを行うには、optimoptions を使用して、SpecifyObjectiveGradient オプションおよび SpecifyConstraintGradient オプションの値を true に設定します。

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

問題を解く

初期点を [-1,1] に設定します。

x0 = [-1,1];

この問題には範囲または線形制約がないため、これらの引数の値を [] に設定します。

A = [];
b = [];
Aeq = [];
beq = [];
lb = [];
ub = [];

fmincon を呼び出してこの問題を解きます。

[x,fval] = fmincon(fun,x0,A,b,Aeq,beq,lb,ub,nonlcon,options)
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.
x = 1×2

   -9.5473    1.0474

fval = 0.0236

解は非線形不等式制約の例と同じく、導関数情報を使用せずに問題を解きます。導関数を使用する利点は、問題を解く際に、関数評価の回数を減らすと同時にロバスト性が得られることにあります。ただし、この例はその点を強調するものではありません。解析的ヘッシアンを使用した fmincon の内点法アルゴリズムで示されているように、さらに多くの導関数情報を使用することには、ソルバーの反復回数を減少させるなどの付加的な利点があります。

補助関数

次のコードは、補助関数 objfungrad を作成します。

function [f,gradf] = objfungrad(x)
f = exp(x(1))*(4*x(1)^2+2*x(2)^2+4*x(1)*x(2)+2*x(2)+1);
% Gradient of the objective function:
if nargout  > 1
    gradf = [ f + exp(x(1)) * (8*x(1) + 4*x(2)), 
    exp(x(1))*(4*x(1)+4*x(2)+2)];
end
end

次のコードは、補助関数 confungrad を作成します。

function [c,ceq,DC,DCeq] = confungrad(x)
c(1) = 1.5 + x(1) * x(2) - x(1) - x(2); % Inequality constraints
c(2) = -x(1) * x(2)-10; 
% No nonlinear equality constraints
ceq=[];
% Gradient of the constraints:
if nargout > 2
    DC= [x(2)-1, -x(2);
        x(1)-1, -x(1)];
    DCeq = [];
end
end

関連するトピック