Main Content

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

粒子群最適化プロセスの調整

この例では、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.168662 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.357250 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 が真の局所最小値であることを示しています。

関連するトピック