このページは機械翻訳を使用して翻訳されました。最新版の英語を参照するには、ここをクリックします。
粒子群最適化プロセスの調整
この例では、particleswarm
ソルバーを使用して最適化する方法を示します。粒子群アルゴリズムは、群と呼ばれる粒子の母集団を目的関数の最小値に向かって移動させます。群れの中の各粒子の速度は、次の 3 つの要因に応じて変化します。
慣性の影響(
InertiaRange
オプション)粒子が訪れた最適な場所への引力(
SelfAdjustmentWeight
オプション)近傍粒子間の最適な位置への引力(
SocialAdjustmentWeight
オプション)
この例では、パーティクル スウォーム オプションを変更した場合のいくつかの効果を示します。
オプションを変更するタイミング
多くの場合、particleswarm
はデフォルトのオプションを使用すると適切な解決策を見つけます。たとえば、デフォルトのオプションで rastriginsfcn
を適切に最適化します。この関数には多くの局所最小値があり、点 [0,0]
では 0
が大域的最小値となります。
rng default % for reproducibility [x,fval,exitflag,output] = particleswarm(@rastriginsfcn,2);
Optimization ended: relative change in the objective value over the last OPTIONS.MaxStallIterations iterations is less than OPTIONS.FunctionTolerance.
formatstring = 'particleswarm reached the value %f using %d function evaluations.\n';
fprintf(formatstring,fval,output.funccount)
particleswarm reached the value 0.000000 using 2560 function evaluations.
この関数の場合、最適な目的値がわかっているので、ソルバーがそれを見つけたことがわかります。しかし、解決策がわからない場合はどうすればよいでしょうか?ソリューションの品質を評価する 1 つの方法は、ソルバーを再実行することです。
[x,fval,exitflag,output] = particleswarm(@rastriginsfcn,2);
Optimization ended: relative change in the objective value over the last OPTIONS.MaxStallIterations iterations is less than OPTIONS.FunctionTolerance.
fprintf(formatstring,fval,output.funccount)
particleswarm reached the value 0.000000 using 1480 function evaluations.
解と関数評価の数はどちらも前回の実行と同様です。これは、ソルバーが解決策に到達するのに困難がないことを示しています。
デフォルトパラメーターを使用した難しい目的関数
Rosenbrock 関数は最適化が難しい関数としてよく知られています。この例では、Rosenbrock 関数の多次元バージョンを使用します。関数は、点 [1,1,1,...]
で 0
の最小値を持ちます。
rng default % for reproducibility nvars = 6; % choose any even value for nvars fun = @multirosenbrock; [x,fval,exitflag,output] = particleswarm(fun,nvars);
Optimization ended: relative change in the objective value over the last OPTIONS.MaxStallIterations iterations is less than OPTIONS.FunctionTolerance.
fprintf(formatstring,fval,output.funccount)
particleswarm reached the value 3106.436648 using 12960 function evaluations.
ソルバーは、あまり良い解決策を見つけられませんでした。
探索空間を制限する
ソルバーが適切なポイントを見つけられるように、空間を境界で囲んでみてください。
lb = -10*ones(1,nvars); ub = -lb; [xbounded,fvalbounded,exitflagbounded,outputbounded] = particleswarm(fun,nvars,lb,ub);
Optimization ended: relative change in the objective value over the last OPTIONS.MaxStallIterations iterations is less than OPTIONS.FunctionTolerance.
fprintf(formatstring,fvalbounded,outputbounded.funccount)
particleswarm reached the value 0.000006 using 71160 function evaluations.
ソルバーははるかに優れた解決策を見つけました。しかし、これを行うには非常に多くの関数評価が必要でした。
オプションの変更
おそらく、より小さな近傍ではなく、空間全体の最適な近傍に重点を置いた方が、ソルバーの収束が速くなるでしょう。
options = optimoptions('particleswarm','MinNeighborsFraction',1); [xn,fvaln,exitflagn,outputn] = particleswarm(fun,nvars,lb,ub,options);
Optimization ended: relative change in the objective value over the last OPTIONS.MaxStallIterations iterations is less than OPTIONS.FunctionTolerance.
fprintf(formatstring,fvaln,outputn.funccount)
particleswarm reached the value 0.000462 using 30180 function evaluations.
ソルバーによる関数評価の回数は減りましたが、これがランダム性によるものか、オプション設定の改善によるものかは不明です。
おそらく、SelfAdjustmentWeight
オプションを上げる必要があります。
options.SelfAdjustmentWeight = 1.9; [xn2,fvaln2,exitflagn2,outputn2] = particleswarm(fun,nvars,lb,ub,options);
Optimization ended: relative change in the objective value over the last OPTIONS.MaxStallIterations iterations is less than OPTIONS.FunctionTolerance.
fprintf(formatstring,fvaln2,outputn2.funccount)
particleswarm reached the value 0.000074 using 18780 function evaluations.
今回は、particleswarm
の関数評価の回数がさらに少なくなりました。この改善はランダム性によるものでしょうか、それともオプション設定は本当に価値があるのでしょうか?ソルバーを再実行し、関数評価の回数を確認します。
[xn3,fvaln3,exitflagn3,outputn3] = particleswarm(fun,nvars,lb,ub,options);
Optimization ended: relative change in the objective value over the last OPTIONS.MaxStallIterations iterations is less than OPTIONS.FunctionTolerance.
fprintf(formatstring,fvaln3,outputn3.funccount)
particleswarm reached the value 0.157026 using 53040 function evaluations.
今回は関数評価の回数が増えました。どうやら、この SelfAdjustmentWeight
設定によってパフォーマンスが必ずしも向上するわけではないようです。
初期点を提供する
おそらく、particleswarm
は、解決策からそれほど遠くない既知のポイントから開始すると、より効果的でしょう。起源を試してください。同じ初期点で数人の個体に与えます。それらのランダムな速度により、それらが一緒に留まることはなくなります。
x0 = zeros(20,6); % set 20 individuals as row vectors options.InitialSwarmMatrix = x0; % the rest of the swarm is random [xn3,fvaln3,exitflagn3,outputn3] = particleswarm(fun,nvars,lb,ub,options);
Optimization ended: relative change in the objective value over the last OPTIONS.MaxStallIterations iterations is less than OPTIONS.FunctionTolerance.
fprintf(formatstring,fvaln3,outputn3.funccount)
particleswarm reached the value 0.039015 using 32100 function evaluations.
関数評価の回数が再び減少しました。
スピードを追求するベクトル化
multirosenbrock
関数を使用すると、ベクトル化された関数評価が可能になります。これは、群れ内のすべての粒子の目的関数を同時に評価できることを意味します。これにより、通常、ソルバーの速度が大幅に向上します。
rng default % do a fair comparison options.UseVectorized = true; tic [xv,fvalv,exitflagv,outputv] = particleswarm(fun,nvars,lb,ub,options);
Optimization ended: relative change in the objective value over the last OPTIONS.MaxStallIterations iterations is less than OPTIONS.FunctionTolerance.
toc
Elapsed time is 0.150014 seconds.
options.UseVectorized = false;
rng default
tic
[xnv,fvalnv,exitflagnv,outputnv] = particleswarm(fun,nvars,lb,ub,options);
Optimization ended: relative change in the objective value over the last OPTIONS.MaxStallIterations iterations is less than OPTIONS.FunctionTolerance.
toc
Elapsed time is 0.239662 seconds.
ベクトル化された計算には、シリアル計算の約半分の時間がかかりました。
プロット関数
プロット関数を使用してソルバーの進行状況を表示できます。
options = optimoptions(options,'PlotFcn',@pswplotbestf); rng default [x,fval,exitflag,output] = particleswarm(fun,nvars,lb,ub,options);
Optimization ended: relative change in the objective value over the last OPTIONS.MaxStallIterations iterations is less than OPTIONS.FunctionTolerance.
fprintf(formatstring,fval,output.funccount)
particleswarm reached the value 0.079755 using 24960 function evaluations.
より多くの粒子を使用する
多くの場合、より多くの粒子を使用すると、より正確なソリューションが得られます。
rng default
options.SwarmSize = 200;
[x,fval,exitflag,output] = particleswarm(fun,nvars,lb,ub,options);
Optimization ended: relative change in the objective value over the last OPTIONS.MaxStallIterations iterations is less than OPTIONS.FunctionTolerance.
fprintf(formatstring,fval,output.funccount)
particleswarm reached the value 0.000424 using 169400 function evaluations.
ハイブリッド関数
particleswarm
は、複数の引き込み領域を探索して、適切な局所解に到達できます。ただし、十分に正確な局所的最小値に到達できない場合もあります。粒子群アルゴリズムが停止した後に実行されるハイブリッド関数を指定して、最終的な回答を改善してみてください。ハイブリッド関数による違いを確認するには、パーティクルの数を元の値 60 にリセットします。
rng default
options.HybridFcn = @fmincon;
options.SwarmSize = 60;
[x,fval,exitflag,output] = particleswarm(fun,nvars,lb,ub,options);
Optimization ended: relative change in the objective value over the last OPTIONS.MaxStallIterations iterations is less than OPTIONS.FunctionTolerance.
fprintf(formatstring,fval,output.funccount)
particleswarm reached the value 0.000000 using 25191 function evaluations.
disp(output.hybridflag)
1
ハイブリッド関数によって結果が改善されましたが、プロット関数では以前と同じ最終値が表示されます。これは、プロット関数が粒子群アルゴリズムの反復のみを表示し、ハイブリッド関数の計算は表示しないためです。ハイブリッド関数により、最終的な関数値は真の最小値 0 に非常に近くなりました。output.hybridflag
フィールドは、fmincon
が終了フラグ 1 で停止し、x
が真の局所的最小値であることを示しています。