最適化ソルバーの出力関数
出力関数とは
"出力関数" とは、最適化関数がそのアルゴリズムの反復ごとに呼び出す関数です。一般的には、グラフの出力や、アルゴリズムが生成するデータ履歴の記録、または現在の反復処理データに基づきアルゴリズムを停止する場合に出力関数を使用します。出力関数は、関数ファイル、ローカル関数または入れ子関数として作成できます。
次の MATLAB® 最適化関数では、OutputFcn
オプションを使用できます。
出力関数の作成および使用方法
次の例は、最適化関数が出力する点をプロットする簡単な出力関数を示したものです。
function stop = outfun(x, optimValues, state) stop = false; hold on; plot(x(1),x(2),'.'); drawnow
この出力関数は、関数 fminsearch
が最適化問題を解く間に生成する点をプロットするときに使用できます。
以下の処理を行います。
上記のコードを含むファイルを作成し、
outfun.m
という名前で MATLAB パス上のフォルダーに保存します。options
構造体のOutputfcn
フィールドの値を、outfun
の関数ハンドルに設定します。options = optimset('OutputFcn', @outfun);
次のコマンドを入力します。
hold on objfun=@(x) exp(x(1))*(4*x(1)^2+2*x(2)^2+x(1)*x(2)+2*x(2)); [x fval] = fminsearch(objfun, [-1 1], options) hold off
これらのコマンドは、以下の解を返します。
x = 0.1290 -0.5323 fval = -0.5689
そして、関数
fminsearch
が生成した点が次のようにプロット表示されます。
出力関数の構造
出力関数の関数定義行は、次の形式になります。
stop = outfun(x, optimValues, state)
ここで以下のようになります。
stop
は、最適化ルーチンを停止するか継続するかによって、true
またはfalse
を表すフラグです。Stop フラグを参照してください。x
は、現在のアルゴリズムの反復処理で計算される点です。optimValues
は現在の反復からのデータを含む構造体です。optimValues のフィールドでこの構造体を詳しく説明します。state
はアルゴリズムの現在の状態です。アルゴリズムの状態では、利用可能な値が表に示されています。
最適化関数は、反復処理ごとに入力引数の値を outfun
に渡します。
入れ子構造の出力関数の例
出力関数の作成および使用方法の例では、ある反復処理から次の処理まで、出力関数がデータを保存する必要はありません。反復処理の合間にデータを保存する必要がない場合は、出力関数を関数ファイルとして作成し、最適化関数を直接コマンド ラインから呼び出すことができます。ただし、ある反復処理から次の処理までに出力関数によってデータを記録する場合は、以下の処理を行うファイルを 1 つ作成します。
出力関数を入れ子関数として含める。詳細については、『MATLAB プログラミングの基礎』ドキュメンテーションの入れ子関数を参照してください。
最適化関数を呼び出す。
次の例では、目的関数もローカル関数として関数ファイルに含まれます。目的関数は、別のファイルとして、または無名関数として作成することもできます。
入れ子関数は、周囲のファイルの変数にアクセスできます。したがって、この方法により、出力関数は、ある反復処理から次の処理まで変数を保持できます。
次の例では、出力関数を使用して、以下の式を解く際の fminsearch
の反復を記録します。
出力関数は、点を history
という行列に返します。
この例の実行は、次の手順を従います。
新規ファイルを MATLAB エディターで開きます。
次のコードをファイルにコピーし、貼り付けます。
function [x fval history] = myproblem(x0) history = []; options = optimset('OutputFcn', @myoutput); [x fval] = fminsearch(@objfun, x0,options); function stop = myoutput(x,optimvalues,state); stop = false; if isequal(state,'iter') history = [history; x]; end end function z = objfun(x) z = exp(x(1))*(4*x(1)^2+2*x(2)^2+x(1)*x(2)+2*x(2)); end end
MATLAB パス上のフォルダーにファイル名を
myproblem.m
としてファイルを保存します。MATLAB プロンプトで、次のように入力します。
[x fval history] = myproblem([-1 1]);
関数 fminsearch
は、最適な点 x
および x における目的関数の値 fval
を返します。
x,fval
x = 0.1290 -0.5323 fval = -0.5689
さらに出力関数 myoutput
は、行列 history
を MATLAB のワークスペースに返します。この行列には、各反復処理時にアルゴリズムが生成した点が含まれます。history
の最初の 4 行は、次のとおりです。
history(1:4,:)
ans = -1.0000 1.0000 -1.0000 1.0000 -1.0750 0.9000 -1.0125 0.8500
history
の点の最終行は、最適の点 x
になります。
history(end,:)
ans = 0.1290 -0.5323
objfun(history(end,:))
ans = -0.5689
optimValues のフィールド
次の表は最適化関数 fminbnd
、fminsearch
、fzero
で提供される optimValues
構造体のフィールドを示しています。
この表の "コマンド ライン表示見出し" 列は、options
の Display
パラメーターを 'iter'
に設定したときに表示される見出しを示したものです。
optimValues フィールド (optimValues.field) | 説明 | コマンド ライン表示見出し |
---|---|---|
| 関数評価の累積回数 |
|
| 現在の点での関数値 |
|
|
|
|
| 手順のメッセージ |
|
アルゴリズムの状態
次の表は、state
の値を示しています。
State | 説明 |
---|---|
| アルゴリズムは、最初の反復の前の初期状態にあります。 |
| アルゴリズムは反復処理を実行中です。この状態で、出力関数は、最適化の現在の反復を停止することができます。出力関数で反復を停止して計算効率を上げることもできます。状態が |
| アルゴリズムは、反復の最後にあります。 |
| アルゴリズムは、最後の反復の後の最終状態にあります。 |
次のコードは、現在の反復処理で実行するタスクを決めるために、出力関数が state
の値を使用する方法を説明しています。
switch state case 'init' % Setup for plots or dialog boxes case 'iter' % Make updates to plots or dialog boxes as needed case 'interrupt' % Check conditions to see whether optimization % should quit case 'done' % Cleanup of plots, dialog boxes, or final plot end
Stop フラグ
出力引数 stop
は、true
またはfalse
を示すフラグです。フラグは、最適化を停止 (true
) または続行 (false
) する必要があるかどうかを最適化関数に示します。次の例は、stop
フラグの一般的な使用方法を示したものです。
optimValues のデータに基づき最適化を停止
出力関数を使用すると、optimValues
の現在のデータに基づいて、反復処理中に最適化を停止することができます。たとえば次のコードは、目的関数の値が 5
より小さいときに stop
を true
に設定します。
function stop = myoutput(x, optimValues, state) stop = false; % Check if objective function is less than 5. if optimValues.fval < 5 stop = true; end
ダイアログ ボックスの入力に基づき最適化を停止
最適化を実行する UI を設計すれば、[停止] ボタンなどを使用して、出力関数に最適化を停止させることができます。次のコードは、このコールバックの実行方法を示しています。このコードでは、[停止] ボタンのコールバックが、appdata
に格納されている hObject
という handles
構造体の optimstop
フィールドに値 true
を格納することを前提とします。
function stop = myoutput(x, optimValues, state) stop = false; % Check if user has requested to stop the optimization. stop = getappdata(hObject,'optimstop');