Main Content

このページは機械翻訳を使用して翻訳されました。元の英語を参照するには、ここをクリックします。

整数および非線形制約を持つ非線形問題を解く

surrogateopt ソルバーは整数制約と非線形制約の両方を受け入れます。整数制約がある場合とない場合の非線形問題の解を比較します。整数制約により、解は適度に細かいグリッド上に配置されます。

目的関数と制約関数

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

f(x)=log(1+3(x2-(x13-x1))2+(x1-4/3)2).

この目的関数は非負であり、x=[4/3,(4/3)3-4/3] = [1.3333, 1.0370]の点で最小値0になります。

この問題には 2 つの非線形制約関数があります。

x145sinh(x2/5),x225tanh(x1/5)+1.

非線形制約の実行可能領域をプロットします。

[X,Y] = meshgrid(-2:.01:3);
Z = (5*sinh(Y./5) >= X.^4); 
% Z=1 where the first constraint is satisfied, Z=0 otherwise
Z = Z+ 2*(5*tanh(X./5) >= Y.^2 - 1); 
% Z=2 where the second constraint is satisfied
% Z=3 where both constraints are satisfied
surf(X,Y,Z,'LineStyle','none');
fig = gcf;
fig.Color = 'w'; % white background
view(0,90)
xlabel('x_1')
ylabel('x_2')

黄色の領域は、両方の制約が満たされている場所を示しています。

surrogateopt では、目的関数と制約関数が同じ関数の一部であり、構造体を返す必要があります。目的関数は構造体の Fval フィールドにあり、制約は Ineq フィールドにあります。これらのフィールドは、この例の最後にある objconstr 関数の出力です。

整数制約を細かいグリッド上にスケールする

x(1)x(2) の両方の変数に整数制約があるように問題を設定します。

intcon = [1 2];

変数が s = 1/10 でスケーリングされるように問題をスケーリングします。ここで、s は変数を乗算します。

s = 0.1;
f = @(x)objconstr(x,s);

このスケーリングを有効にするには、境界を 1/s でスケーリングする必要があります。スケールされていない境界を -2xi3 に設定し、それぞれを 1/s でスケールします。

lb = [-2,-2]/s;
ub = [3,3]/s;

スケーリング s を使用すると、問題では各コンポーネント x(1)x(2) に実質的に s の間隔が設定されます。整数点を間隔 s のグリッドとしてプロットします。

hold on
grid on
ax = gca;
sp = -2:s:3;
ax.XTick = sp;
ax.YTick = sp;
ax.Layer = 'top';
ax.GridAlpha = 1/2;
ax.XTickLabel = '';
ax.YTickLabel = '';
xlabel('x_1')
ylabel('x_2')
hold off

スケール問題を解く

デフォルトよりも厳しい制約を使用し、surrogateoptplot プロット関数を使用するようにオプションを設定します。

opts = optimoptions('surrogateopt','PlotFcn',"surrogateoptplot","ConstraintTolerance",1e-6);

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

rng default % For reproducibility
[sol,fval,eflag,outpt] = surrogateopt(f,lb,ub,intcon,opts)

surrogateopt stopped because it exceeded the function evaluation limit set by 
'options.MaxFunctionEvaluations'.
sol = 1×2

     5     1

fval = 0.8634
eflag = 0
outpt = struct with fields:
        elapsedtime: 28.6785
          funccount: 200
    constrviolation: -0.0375
               ineq: [-0.0375 -1.4883]
           rngstate: [1x1 struct]
            message: 'surrogateopt stopped because it exceeded the function evaluation limit set by ...'

解を図上に赤い円でプロットします。目的関数の値がおよそ 0.86 であることに注意してください。

figure(fig);
hold on
plot3(sol(1)*s,sol(2)*s,5,'ro')
hold off

整数制約のないソリューションと比較する

整数制約のあるソリューションと整数制約のないソリューションを比較します。

[sol2,fval2,eflag2,outpt2] = surrogateopt(f,lb,ub,[],opts)

surrogateopt stopped because it exceeded the function evaluation limit set by 
'options.MaxFunctionEvaluations'.
sol2 = 1×2

    4.3882    0.3709

fval2 = 0.8153
eflag2 = 0
outpt2 = struct with fields:
        elapsedtime: 22.8327
          funccount: 200
    constrviolation: -1.2426e-05
               ineq: [-1.2426e-05 -1.4363]
           rngstate: [1x1 struct]
            message: 'surrogateopt stopped because it exceeded the function evaluation limit set by ...'

ここで、目的関数の値はおよそ 0.815 です。整数制約により、目的関数の値は 10% 未満増加します。新しい解を以前の整数解とともにプロットします。ズームインすると、解決ポイントがより明確に表示されます。

figure(fig)
hold on
plot3(sol2(1)*s,sol2(2)*s,5,'k*','MarkerSize',12)
xlim([0 1])
ylim([-1/2 1/2])
hold off

補助関数

次のコードは、補助関数 objconstr を作成します。この関数は、変数 x を係数 s でスケーリングし、目的関数値を F 構造体の Fval フィールドに返して、非線形制約を F 構造体の Ineq フィールドに返します。

function F = objconstr(x,s)
x = x*s;
fun = log(1 + 3*(x(2) - (x(1)^3 - x(1)))^2 + (x(1) - 4/3)^2);
c1 = x(1)^4 - 5*sinh(x(2)/5);
c2 = x(2)^2 - 5*tanh(x(1)/5) - 1;
c = [c1 c2];
F.Fval = fun;
F.Ineq = c;
end

参考

関連するトピック