メインコンテンツ

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

シミュレーテッド アニーリング オプション

この例では、Global Optimization Toolbox の optimoptions を使用して、シミュレーテッド アニーリング関数 simulannealbnd のオプションを作成および管理する方法を示します。

最適化問題の設定

simulannealbnd はシミュレーテッド アニーリングを使用して関数の最小値を探索します。この例では、simulannealbnd を使用して目的関数 dejong5fcn を最小化します。この関数は、この例を実行するときに使用できます。dejong5fcn は 2 つの変数の実数値関数であり、多くの局所最小値があるため、最適化が困難です。x =(-32,-32) の唯一の大域的最小値は f(x) = 0.998 です。問題を定義するには、目的関数、開始点、および各 x(i) について範囲-64 <= x(i) <= 64 で指定される境界を定義する必要があります。

ObjectiveFunction = @dejong5fcn;
startingPoint = [-30 0];
lb = [-64 -64];
ub = [64 64];

この例を実行するときに使用できる関数 plotobjective は、範囲-64 <= x1 <= 64-64 <= x2 <= 64 にわたって目的関数をプロットします。

plotobjective(ObjectiveFunction,[-64 64; -64 64]);
view(-15,150);

Figure contains an axes object. The axes object contains 2 objects of type surface, contour.

ここで、simulannealbnd ソルバーを実行して目的関数を最小化できます。

rng default % For reproducibility
[x,fval,exitFlag,output] = simulannealbnd(ObjectiveFunction,startingPoint,lb,ub);
simulannealbnd stopped because the change in best function value is less than options.FunctionTolerance.
fprintf('The number of iterations was : %d\n', output.iterations);
The number of iterations was : 1095
fprintf('The number of function evaluations was : %d\n', output.funccount);
The number of function evaluations was : 1104
fprintf('The best function value found was : %g\n', fval);
The best function value found was : 2.98211

この例を実行すると、シミュレーテッド アニーリング法が乱数を使用してポイントを生成するため、結果が上記の結果と異なる場合があることに注意してください。

視覚化の追加

simulannealbnd は、「options」引数を通じて 1 つ以上のプロット関数を受け入れることができます。この機能は、実行時にソルバーのパフォーマンスを視覚化するのに役立ちます。プロット関数は optimoptions を使用して選択されます。ツールボックスには選択可能なプロット関数のセットが含まれていますが、独自のカスタム プロット関数を提供することもできます。

複数のプロット関数を選択するには、optimoptions 関数を介して PlotFcn オプションを設定します。この例では、反復ごとに最適な関数値をプロットする saplotbestf、反復ごとに各次元の現在の温度を表示する saplottemperature、現在の関数値を表示する saplotf (現在の値が必ずしも最適な値ではないことに注意してください)、および 10 回の反復ごとに満たされた停止基準の割合をプロットする saplotstopping を選択します。

options = optimoptions(@simulannealbnd, ...
                     'PlotFcn',{@saplotbestf,@saplottemperature,@saplotf,@saplotstopping});

ソルバーを実行します。

simulannealbnd(ObjectiveFunction,startingPoint,lb,ub,options);

Figure Simulated Annealing contains 4 axes objects. Axes object 1 with title Best Function Value: 0.998004, xlabel Iteration, ylabel Function value contains an object of type scatter. Axes object 2 with title Current Temperature, xlabel Variable number, ylabel Current temperature contains an object of type bar. Axes object 3 with title Current Function Value: 0.998004, xlabel Iteration, ylabel Function value contains an object of type scatter. Axes object 4 with title Stopping Criteria, xlabel Progress contains an object of type bar.

simulannealbnd stopped because the change in best function value is less than options.FunctionTolerance.

温度オプションの指定

シミュレーテッド アニーリングで使用される温度パラメーターは、全体的な探索結果を制御します。各次元の温度は、その次元での探索の範囲を制限するために使用されます。ツールボックスを使用すると、初期温度を指定できるほか、解析プロセス中に温度を更新する方法も指定できます。温度に関連する 2 つのオプションは、InitialTemperatureTemperatureFcn です。

初期温度の指定

各次元のデフォルトの初期温度は 100 に設定されています。初期温度を異なる次元で異なるものにしたい場合は、温度のベクトルを指定する必要があります。これは、問題が各次元ごとに異なるスケールになっている場合に必要になることがあります。以下に例を示します。

options = optimoptions(@simulannealbnd,'InitialTemperature',[300 50]);

InitialTemperature は、変数の数 (次元) よりも短い長さのベクトルに設定できます。ソルバーは、初期温度ベクトルの最後の要素を取得して、ベクトルを残りの次元に拡張します。ここでは、初期温度をすべての次元で同じにしたいので、単一の温度のみを指定する必要があります。

options.InitialTemperature = 100;

温度関数の指定

simulannealbnd で使用されるデフォルトの温度関数は temperatureexp と呼ばれます。temperatureexp スケジュールでは、任意のステップでの温度は、前のステップでの温度の 0.95 倍になります。これにより、最初は温度がゆっくりと下がりますが、最終的には他の方式よりも早く冷えます。別のスキーム(たとえば、ボルツマン スケジュールまたは「高速」スケジュール アニーリング)が必要な場合は、それぞれ temperatureboltz または temperaturefast を使用できます。高速温度スケジュールを選択するには、TemperatureFcn を直接変更して、以前に作成したオプションを更新します。

options.TemperatureFcn = @temperaturefast;

再アニーリングの指定

再アニーリングはアニーリングプロセスの一部です。一定数の新しいポイントが受け入れられた後、探索を再開して局所的最小値から抜け出すことを期待して、温度がより高い値に上げられます。再アニーリングをあまり早く実行すると、ソルバーが最小値を識別できなくなる可能性があるため、比較的長い間隔を選択することをお勧めします。再アニーリングが行われる間隔は、ReannealInterval オプションを使用して設定できます。ここでは、関数が多くの領域で平坦になり、ソルバーが急速に停止する可能性があるため、デフォルトの再アニーリング間隔を 50 に減らします。

options.ReannealInterval = 50;

新しい温度オプションを設定したので、ソルバーを再度実行します。

[x,fval,exitFlag,output] = simulannealbnd(ObjectiveFunction,startingPoint,lb,ub,options);
simulannealbnd stopped because the change in best function value is less than options.FunctionTolerance.
fprintf('The number of iterations was : %d\n', output.iterations);
The number of iterations was : 1306
fprintf('The number of function evaluations was : %d\n', output.funccount);
The number of function evaluations was : 1321
fprintf('The best function value found was : %g\n', fval);
The best function value found was : 16.4409

結果の再現

simulannealbnd は非決定論的なアルゴリズムです。つまり、設定を変更せずにソルバーを複数回実行すると、異なる結果が出る可能性があります。これは、simulannealbnd が後続のポイントを生成するとき、また新しいポイントを受け入れるかどうかを決定するときに、MATLAB ® 乱数ジェネレーターを利用するためです。乱数が生成されるたびに、乱数ジェネレータの状態が変化します。

これを確認するには、simulannealbnd ソルバーを 2 回実行すると次の結果が得られます。

[x,fval] = simulannealbnd(ObjectiveFunction,startingPoint,lb,ub,options);
simulannealbnd stopped because the change in best function value is less than options.FunctionTolerance.
fprintf('The best function value found was : %g\n', fval);
The best function value found was : 1.99203

そして、

[x,fval] = simulannealbnd(ObjectiveFunction,startingPoint,lb,ub,options);
simulannealbnd stopped because the change in best function value is less than options.FunctionTolerance.
fprintf('The best function value found was : %g\n', fval);
The best function value found was : 10.7632

前の 2 回の実行では、simulannealbnd は異なる結果を出力します。

simulannealbnd によって返された情報を使用して、ソルバーの実行間で乱数ジェネレーターの状態をリセットすると、結果を再現できます。simulannealbnd は、出力引数で simulannealbnd が呼び出された時点での乱数ジェネレーターの状態を返します。この情報を使用して状態をリセットできます。ここでは、この出力情報を使用して実行間の状態をリセットし、次の 2 回の実行の結果が同じになるようにします。

[x,fval,exitFlag,output] = simulannealbnd(ObjectiveFunction,startingPoint,lb,ub,options);
simulannealbnd stopped because the change in best function value is less than options.FunctionTolerance.
fprintf('The best function value found was : %g\n', fval);
The best function value found was : 20.1535

乱数ジェネレータの状態をリセットします。

strm = RandStream.getGlobalStream;
strm.State = output.rngstate.State;

さて、もう一度 simulannealbnd を実行してみましょう。

[x,fval] = simulannealbnd(ObjectiveFunction,startingPoint,lb,ub,options);
simulannealbnd stopped because the change in best function value is less than options.FunctionTolerance.
fprintf('The best function value found was : %g\n', fval);
The best function value found was : 20.1535

停止基準の変更

simulannealbnd は、ソルバーを停止するタイミングを決定するために 6 つの異なる基準を使用します。simulannealbnd は、反復の最大回数または関数評価の最大回数を超えると停止します。デフォルトでは、反復の最大回数は Inf に設定され、関数評価の最大回数は 3000*numberOfVariables です。simulannealbnd は、関数値の平均変化を MaxStallIterations 反復にわたって追跡します。平均変化が関数の許容値 FunctionTolerance より小さい場合、アルゴリズムは停止します。目的関数の値が ObjectiveLimit に達したときにも、ソルバーは停止します。最後に、ソルバーは MaxTime 秒間実行された後に停止します。ここでは、FunctionTolerance を 1e-5 に設定します。

options.FunctionTolerance = 1e-5;

simulannealbnd ソルバーを実行します。

[x,fval,exitFlag,output] = simulannealbnd(ObjectiveFunction,startingPoint,lb,ub,options);
simulannealbnd stopped because the change in best function value is less than options.FunctionTolerance.
fprintf('The number of iterations was : %d\n', output.iterations);
The number of iterations was : 1843
fprintf('The number of function evaluations was : %d\n', output.funccount);
The number of function evaluations was : 1864
fprintf('The best function value found was : %g\n', fval);
The best function value found was : 6.90334

参考

トピック