このペ,ジの翻訳は最新ではありません。ここをクリックして,英語の最新版を参照してください。
このチュトリアルには,2の非線形最適化ソルバ(fminunc
とfmincon
)の使用方法とオプションの設定方法を示す複数の例が含まれています。このチュ,トリアルで紹介する原理は,fgoalattain
、fminimax
、lsqnonlin
、lsqcurvefit
、fsolve
などの他の非線形ソルバ,にも適用されます。
チュ,トリアルの例では以下のタスクを取り上げます。
目的関数の最小化
追加のパラメ,タ,を使用した同じ関数の最小化
制約付きの目的関数の最小化
勾配またはヘッシアンを提供するか,オプションを変更することによる,より効率的または正確な解の取得
次の関数の最小値を求める問題を考えます。
関数をプロットしてそれが最小になる位置を確認します。
F = @(x,y) x.*exp(-x.²-y.²)+(x.²+y.²)/20;fsurf (f (2, 2),“ShowContours”,“上”)
プロットは,最小値が点(-1/2,0)の近くにあることを示しています。
通常は,目的関数をmatlab®ファescルとして定義します。この場合は,関数が単純なため無名関数として定義します。
Fun = @(x) f(x(1),x(2));
解を求める初期点を設定します。
X0 = [-.5;0);
fminunc
の既定の“拟牛顿”
アルゴリズムを使用するように最適化オプションを設定します。このステップにより,チュートリアルがすべてのMATLABバージョンで必ず同じように動作するようになります。
选项= optimoptions(“fminunc”,“算法”,“拟牛顿”);
ソルバ,が計算を実行した反復回数を表示します。
选项。显示=“通路”;
制約なしの非線形最小化関数fminunc
を呼び出します。
[x, fval, exitflag, output] = fminunc(fun,x0,options);
一阶迭代函数函数计数f(x)步长最优性03 -0.3769 0.339 1 6 -0.379694 1 0.286 2 9 -0.405023 1 0.0284 3 12 -0.405233 1 0.00386 4 15 -0.405237 1 3.17e-05 5 18 -0.405237 1 3.35e-08找到局部最小值。优化完成,因为梯度的大小小于最优性公差的值。
ソルバ,によって求められた解を表示します。
Uncx = x
uncx =2×1-0.6691 - 0.0000
この解での関数値を表示します。
Uncf = fval
Uncf = -0.4052
この例では,関数評価の回数を効率の尺度として使用します。関数評価の合計回数を表示します。
output.funcCount
Ans = 18
ここでは,まず,MATLABファイルを使用して,次に,入れ子関数を使用して,特別なパラメーターを追加引数として目的関数に渡します。
前の例で示した目的関数を考えます。
次のように,(a,b,c)を使用して関数をパラメ,タ,化します。
この関数は,元の目的関数をシフトおよびスケ,リングしたバ,ジョンです。
次のように定義されたbowlpeakfun
という名前のmatlabファescル目的関数を考えます。
类型bowlpeakfun
function y = bowlpeakfun(x, a, b, c) %% 2008年版权MathWorks公司y = (x(1)——)。* exp (- ((x(1)——)^ 2 + (x (2) - b) ^ 2)) + ((x(1)——)^ 2 + (x (2) - b) ^ 2) / c;
パラメ,タ,を定義します。
A = 2;B = 3;C = 10;
Matlabファescルに対する無名関数ハンドルを作成します。
F = @(x)bowlpeakfun(x,a,b,c)
f =Function_handle with value:@ (x) bowlpeakfun (x, a, b, c)
fminunc
を呼び出して,最小値を見けます。
X0 = [-.5;0);选项= optimoptions(“fminunc”,“算法”,“拟牛顿”);[x, fval] = fminunc(f,x0,options)
找到局部极小值。优化完成,因为梯度的大小小于最优性公差的值。
x =2×11.3639 - 3.0000
Fval = -0.3840
目的を入れ子関数として実装する関数nestedbowlpeak
を考えます。
类型nestedbowlpeak
function [x,fval] = nestedbowlpeak(a,b,c,x0,options) % nestedbowlpeak用于TUTDEMO中参数传递的嵌套函数。版权所有2008 The MathWorks, Inc. [x,fval] = fminunc(@nestedfun,x0,options);函数y = nestedfun (x) y = (x(1)——)。* exp (- ((x(1)——)^ 2 + (x (2) - b) ^ 2)) + ((x(1)——)^ 2 + (x (2) - b) ^ 2) / c;结束结束
パラメ,タ,(a,b,c)は入れ子目的関数nestedfun
に認識されます。外側の関数nestedbowlpeak
はfminunc
を呼び出し,目的関数nestedfun
を渡します。
パラメ,タ,初期推定値,およびオプションを定義します。
A = 2;B = 3;C = 10;X0 = [-.5;0);选项= optimoptions(“fminunc”,“算法”,“拟牛顿”);
最適化を実行します。
[x,fval] = nestedbowlpeak(a,b,c,x0,options)
找到局部极小值。优化完成,因为梯度的大小小于最优性公差的值。
x =2×11.3639 - 3.0000
Fval = -0.3840
どらのアプロチでも同じ結果が得られるため,都合の良い方を選択できます。
前の問題を制約付きで考えます。
この制約は,傾いた楕円の内部です。傾いた楕円と一緒にプロットされた目的関数の等高線を表示します。
F = @(x,y) x.*exp(-x.²-y.²)+(x.²+y.²)/20;G = @(x,y) x.*y/2+(x+2).^2+(y-2).^2/2-2;Fimplicit (g)轴([-6 0 -1 7])保持不变在fcontour (f)情节(-.9727 .4685,“罗”);传奇(“约束”,“f轮廓”,“最低”);持有从
このプロットは,楕円内の目的関数の最小値が楕円の右下付近にあることを示しています。プロットされた最小値を計算する前に,その解を推定します。
X0 = [-2 1];
内点法アルゴリズムを使用して,反復ごとに結果を表示するように,最適化オプションを設定します。
选项= optimoptions(“fmincon”,“算法”,“内点”,“显示”,“通路”);
ソルバ:には,非線形制約関数からの2:の出力が必要です。第1の出力は非線形不等式で,第2の出力は非線形等式です。両方の出力を提供するために,関数交易
を使用して制約を記述します。
Gfun = @(x) deal(g(x(1),x(2)),[]);
非線形制約付きソルバ,を呼び出します。問題に線形の等式,不等式,または範囲は含まれていないため,これらの引数として[]を渡します。
[x, fval exitflag,输出]= fmincon (x0有趣, ,[],[],[],[],[],[], gfun选项);
Iter f -count f(x)可行性优化步骤03 2.365241e-01 0.000e+00 1.734e-01 0.000e+00 1.734e-01 2.260e-01 2 10 -1.570560e-01 0.000e+00 2.608e-01 9.347e-01 3 14 -6.629160e-02 0.000e+00 1.934e -02 1.826e-01 5 20 -2.349124e-01 0.000e+00 1.955e-02 1.571e-01 6 23 -2.444225e-01 0.000e+00 4.293e-03 3.821e-02 8 29 -2.446931e-01 0.000e+00 8.100e-04 4.035e-03 9 32-2.446933e-01 0.000e+00 1.999e-04 8.126e-04 10 35 -2.448531e-01 0.000e+00 4.004e-05 3.289e-04 11 38 -2.448927e-01 0.000e+00 4.036e-07 8.156e-05发现满足约束的局部最小值。优化完成是因为目标函数在可行方向上不递减,在最优性容差值范围内,约束条件满足在约束容差值范围内。
ソルバ,によって求められた解を表示します。
x
x =1×2-0.9727 - 0.4686
この解での関数値を表示します。
fval
Fval = -0.2449
関数評価の合計回数を表示します。
Fevals = output.funcCount
发烧= 38次
不等式制約は,この解において満たされます。
[c, ceq] = gfun(x)
C = -2.4608e-06
Ceq = []
C (x)が0に近いため,この制約は“アクティブ”です。まり,解に影響を及ぼします。制約なしの解を再現します。
uncx
uncx =2×1-0.6691 - 0.0000
制約なしの目的関数を再現します。
uncf
Uncf = -0.4052
制約によってどのくらい解が移動し,目的が増加したかを確認します。
fval-uncf
Ans = 0.1603
勾配を指定することによって,最適化問題をより効率的か正確に解くことができます。前の例と同様に,この例では,不等式制約付き問題を解きます。
F (x)の勾配をfmincon
に与えるために,目的関数をmatlabファescルの形式で記述します。
类型onehump
函数[f,gf] = one驼峰(x) %帮助函数为教程的优化工具箱演示%版权所有2008-2009 the MathWorks, Inc. r = x(1)^2 + x(2)^2;S = exp(-r);F = x(1)*s+r/20;If nargout > 1 gf = [(1-2*x(1)^2)*s+x(1)/10;2 * x (1) * (2) * s + x (2) / 10);结束
制約とその勾配は,matlabファescルtiltellipse
に含まれています。
类型tiltellipse
函数[c,ceq,gc,gceq] = tiltellipse(x) % tiltellipse辅助函数用于优化工具箱演示教程%版权所有2008-2009 the MathWorks, Inc. c = x(1)*x(2)/2 + (x(1)+2)^2 + (x(2)-2)^2/2 -2;Ceq = [];如果nargout > 2 gc = [x(2)/2+2*(x(1)+2);(1) / 2 + x (2) 2);Gceq = [];结束
解を求める初期点を設定します。
X0 = [-2;1);
比較のために前の例と同じアルゴリズムを使用するように最適化オプションを設定します。
选项= optimoptions(“fmincon”,“算法”,“内点”);
目的関数と制約関数で勾配情報を使用するようにオプションを設定します。メモ:これらのオプションは必ずオンにしてください。そうしないと,勾配情報が無視されます。
选项= optimoptions(选项,...“SpecifyObjectiveGradient”,真的,...“SpecifyConstraintGradient”,真正的);
fmincon
は有限差分を使用して勾配を推定する必要がないため,ソルバ,の関数カウントが少なくなるはずです。反復ごとに結果を表示するようにオプションを設定します。
选项。显示=“通路”;
ソルバ,を呼び出します。
[x, fval exitflag,输出]= fmincon (x0 @onehump ,[],[],[],[],[],[],...@tiltellipse选项);
Iter f -count f(x)可行性优化步骤01 2.365241e-01 0.000e+00 1.734e-01 0.000e+00 1.734e-01 2.260e-01 24 -1.570560e-01 0.000e+00 2.608e-01 9.347e-01 3 36 -6.629161e-02 0.000e+00 7.934e-02 1.826e-01 58 -2.349124e-01 0.000e+00 1.955e-02 1.993e-02 69 -2.444225e-01 0.000e+00 4.293e-03 3.821e- 01 0.000e 8 11 -2.446931e-01 0.000e+00 8.100e-04 4.035e-03 912-2.446933e-01 0.000e+00 1.999e-04 8.126e-04 10 13 -2.448531e-01 0.000e+00 4.004e-05 3.289e-04 11 14 -2.448927e-01 0.000e+00 4.036e-07 8.156e-05发现满足约束的局部最小值。优化完成是因为目标函数在可行方向上不递减,在最优性容差值范围内,约束条件满足在约束容差值范围内。
前の例でfmincon
による勾配の推定が成功したため,この例での反復も同様です。
ソルバ,によって求められた解を表示します。
Xold = x
xold =2×1-0.9727 - 0.4686
この解での関数値を表示します。
Minfval = fval
Minfval = -0.2449
関数評価の合計回数を表示します。
Fgradevals = output.funcCount
Fgradevals = 14
この数字を,勾配を使用しない場合の関数評価回数と比較します。
函数宏指令
发烧= 38次
この例では,勾配の使用に進んで,同じ制約付き問題を解きます。
.
この場合は、既定の終了基準(选项。StepTolerance
と选项。OptimalityTolerance
)をオ、バ、ラ、ドすることによって、より正確な解を求めます。fmincon
内点法アルゴリズムの既定値は选项。步进公差= 1e-10
と选项。OptimalityTolerance = 1e-6
です。
この2の既定の終了基準をオバラドします。
选项= optimoptions(选项,...“StepTolerance”1 e15汽油,...“OptimalityTolerance”1 e-8);
ソルバ,を呼び出します。
[x, fval exitflag,输出]= fmincon (x0 @onehump ,[],[],[],[],[],[],...@tiltellipse选项);
Iter f -count f(x)可行性优化步骤01 2.365241e-01 0.000e+00 1.734e-01 0.000e+00 1.734e-01 2.260e-01 24 -1.570560e-01 0.000e+00 2.608e-01 9.347e-01 3 36 -6.629161e-02 0.000e+00 7.934e-02 1.826e-01 58 -2.349124e-01 0.000e+00 1.955e-02 1.993e-02 69 -2.444225e-01 0.000e+00 4.293e-03 3.821e- 01 0.000e 8 11 -2.446931e-01 0.000e+00 8.100e-04 4.035e-03 912-2.446933e-01 0.000e+00 1.999e-04 8.126e-04 10 13 -2.448531e-01 0.000e+00 4.004e-05 3.289e-04 11 14 -2.448927e-01 0.000e+00 4.036e-07 8.156e-05 12 15 -2.448931e-01 0.000e+00 4.000e-09 8.230e-07发现满足约束的局部最小值。优化完成是因为目标函数在可行方向上不递减,在最优性容差值范围内,约束条件满足在约束容差值范围内。
新しい許容誤差によって生じる差をより正確に把握するために,解の小数点以下の桁数を増やします。
格式长
ソルバ,によって求められた解を表示します。
x
x =2×1-0.972742227363546 - 0.468569289098342
これらの値と前の例の値を比較します。
xold
xold =2×1-0.972742694488360 - 0.468569966693330
値の違いを確認します。
X - xold
ans =2×1106× 0.467124813385844 -0.677594988729435
この解での関数値を表示します。
fval
Fval = -0.244893137879894
解がどのくらい改善したかを確認します。
Fval - minfval
Ans = -3.996450220755676e-07
新しい解の方が小さいため,答えは負になります。
関数評価の合計回数を表示します。
output.funcCount
Ans = 15
この数字を,ユ,ザ,指定の勾配と既定の許容誤差を使用して解いた例の関数評価の回数と比較します。
Fgradevals
Fgradevals = 14
勾配だけでなくヘッシアンも指定すると,ソルバ,の精度と効率がさらに向上します。
fmincon
内点法アルゴリズムは,ヘッシアン行列を別個の関数(目的関数の一部ではなく)として取得します。ヘッシアン関数H(x,lambda)はラグランジュ関数のヘッシアンを評価します。Fminconの内点法アルゴリズムのヘッシアンを参照してください。
ソルバ,が,値のlambda.ineqnonlin
とlambda.eqlin
を計算します。ヘッシアン関数が,これらの値の使用方法をソルバ,に指示します。
この例には不等式制約が1しか含まれていないため,ヘッシアンは関数hessfordemo
で指定されたように定義されます。
类型hessfordemo
H = hessfordemo(x,lambda) % hessfordemo用于优化工具箱教程的帮助函数%版权所有2008-2009 the MathWorks, Inc. s = exp(-(x(1)^2+x(2)^2));H = (2 * x (1) * (2 * x (1) ^ 2 - 3) * s + 1/10, 2 * x (2) * (2 * x(1) ^ 2 - 1) *年代;2 * x (2) * (2 * x (1) ^ 2 - 1) * s, 2 * x (1) * (2 * x (2) ^ 2 - 1) * s + 1/10);Hessc = [2,1/2;1/2,1];H = H + lambda.ineqnonlin(1)*hessc;
このヘッシアンを使用するには,オプションを適切に設定しなければなりません。
选项= optimoptions(“fmincon”,...“算法”,“内点”,...“SpecifyConstraintGradient”,真的,...“SpecifyObjectiveGradient”,真的,...“HessianFcn”, @hessfordemo);
許容誤差は既定値に設定されるため,関数のカウントは減るはずです。反復ごとに結果を表示するようにオプションを設定します。
选项。显示=“通路”;
ソルバ,を呼び出します。
[x, fval exitflag,输出]= fmincon (x0 @onehump ,[],[],[],[],[],[],...@tiltellipse选项);
Iter f -count f(x)可行性优化步骤01 2.365241e-01 0.000e+00 1.972e-01 0.000e+00 1.443e-01 8.728e-01 25 -1.218829e-01 0.000e+00 1.486e -02 4.927e-01 36 -1.421167e-01 0.000e+00 1.989e-02 5.167e -02 5 8 -2.433609e-01 0.000e+00 1.537e-03 3.486e-02 6 9 -2.446875e-01 0.000e+00 2.057e-04 4.191e- 01 0.000e+00 2.068e-06 4.191e- 01 0.000e 8 11 -2.448911e-01 0.000e+00 2.001e-08 4.218e-06本地最小值满足约束条件。优化完成是因为目标函数在可行方向上不递减,在最优性容差值范围内,约束条件满足在约束容差值范围内。
結果は,反復回数が少なくなり,異なる反復が示されます。
ソルバ,によって求められた解を表示します。
x
x =2×1-0.972742246093537 - 0.468569316215571
この解での関数値を表示します。
fval
Fval = -0.244893121872758
関数評価の合計回数を表示します。
output.funcCount
Ans = 11
この数字を,既定の許容誤差を同じにし,勾配評価のみを使用して解いた例の関数評価の回数と比較します。
Fgradevals
Fgradevals = 14