ドキュメンテーション センター

  • 評価版
  • 製品アップデート

最新のリリースでは、このページがまだ翻訳されていません。 このページの最新版は英語でご覧になれます。

ソルバーが失敗したとき

反復か関数評価が多すぎる

反復の回数の上の限界に到着したか、要求された許容誤差に目的関数を最小化する前に関数評価に達したため、ソルバーは停止しました。継続するには、以下の 1 つ、またはいくつかを試してください。

1. 反復表示の有効化
2. 許容誤差の緩和
3. 異なる点からソルバーを開始
4. 目的関数と制約関数の定義を確認
5. 問題のセンタリングとスケーリング
6. 勾配またはヤコビ行列の指定
7. ヘッセ行列の供給

1. 反復表示の有効化

Display オプションを 'iter' に設定します。この設定により、ソルバー反復の結果が表示されます。

反復表示を有効にするには、以下を行います。

  • 最適化アプリケーションを使用して、[表示レベル][各反復] または [各反復と詳細メッセージを表示] となるように選択します。

  • MATLAB® コマンド ラインに以下を入力します。

    options = optimoptions('solvername','Display','iter');

    options 構造体を使用して、ソルバーを呼び出します。

反復表示の例については、結果の解釈を参照してください。

反復表示内で何を探すか-  

  • 目的関数 (Fvalf(x)Resnorm) が減少するかどうかを観察します。減少すれば、進行していることを示します。

  • それが確実に 0 に減少するように、制約違反 (Max constraint) を調べます。減少すれば、進行していることを示します。

  • 1 次の最適性が 0 に向かって減少するかどうかを観察します。減少すれば、進行していることを示します。

  • Trust-region radius が小さい値に減少するかどうか観察します。この減少は、対象が滑らかでないかもしれないことを示します。

何をすべきか-  

  • ソルバーが進行するような場合:

    1. MaxIterMaxFunEvals を既定値よりも大きく設定します。最適化アプリケーションで、もしくはソルバーの関数リファレンス ページにあるオプションの表で既定値を確認できます。

    2. その最後に計算された点からソルバーを開始します。

  • ソルバーが進行しない場合は、リストされている他の推奨操作を試してください。

2. 許容誤差の緩和

たとえば、TolXTolFun が小さすぎると、いつそれが最小値に達したかをソルバーが認識しないかもしれません。無制限に無益な反復を行う可能性があります。

最適化アプリケーションを使用して許容誤差を変更するには、[オプション] ペインの上部にある [停止条件] リストを使用します。

コマンド ラインで許容誤差を変更するには、オプションの設定と変更で説明するように、関数 optimoptions を使用します。

DiffMaxChangeDiffMinChange オプションはソルバーの進行に影響する可能性があります。これらのオプションは、派生する推定用の有限差分におけるステップ サイズを制御します。

3. 異なる点からソルバーを開始

「初期点の変更」を参照してください。

4. 目的関数と制約関数の定義を確認

たとえば、目的関数と非線形制約関数が任意の点で正しい値を返すことを確認します。「目的関数と制約関数の定義を確認」を参照してください。実行不可能な点が関数のエラーを起こさないことを確認します。反復は制約に違反する可能性ありを参照してください。

5. 問題のセンタリングとスケーリング

各座標が目的関数と制約関数にほぼ同じ影響を与える場合に、ソルバーはより確実に機能します。座標軸の方向を適切なスカラーで増やすことで各座標の影響を均等化します。適切な値を一定の座標に追加し、それらのサイズを均等化します。

例: センタリングとスケーリング-  1e6*x(1)^2 + 1e-6*x(2)^2 の最小化を考えます。

f = @(x) 10^6*x(1)^2 + 10^-6*x(2)^2;

中規模 fminunc アルゴリズムを使用して、f を最小化します。

opts = optimoptions('fminunc','Display','none','Algorithm','quasi-newton');
x = fminunc(f,[0.5;0.5],opts)

x =
         0
    0.5000

結果は正しくありません。不適格なスケーリングが良い解を得ることを妨げました。

問題をスケーリングします。以下のように設定してください。

D = diag([1e-3,1e3]);
fr = @(y) f(D*y);
y = fminunc(fr, [0.5;0.5], opts)

y =
     0
     0 % the correct answer

同様に、不適格なセンタリングが解を妨げる可能性があります。

fc = @(z)fr([z(1)-1e6;z(2)+1e6]); % poor centering
z = fminunc(fc,[.5 .5],opts)

z =
  1.0e+005 *
   10.0000  -10.0000 % looks good, but...

z - [1e6 -1e6] % checking how close z is to 1e6

ans =

   -0.0071    0.0078 % reveals a distance


fcc = @(w)fc([w(1)+1e6;w(2)-1e6]); % centered

w = fminunc(fcc,[.5 .5],opts)

w =
     0     0 % the correct answer

6. 勾配またはヤコビ行列の指定

勾配またはヤコビ行列を提供しない場合は、ソルバーは有限差分によって勾配とヤコビ行列を推定します。そのため、これらの導関数を提供すると、計算時間を節約し精度を高めることができる可能性があります。

制約問題の場合は、勾配を与えることで別の利点があります。ソルバーは、x が実現可能であるような点 x に到達できますが、x の周囲の有限差分は常に実行不可能な点を導きます。この場合、ソルバーは失敗するか途中で停止する可能性があります。勾配を与えることで、ソルバーは続行できます。

目的関数と非線形制約関数用に、このファイル内に勾配またはヤコビ行列を供給します。構文についての詳細は、「スカラー目的関数の記述」、「ベクトルと行列の目的関数の記述」および「非線形制約」を参照してください。

勾配またはヤコビ行列の有効性を確認」で説明するように、勾配またはヤコビ関数が正しいことを確認するには、DerivativeCheck オプションを使用します。

Symbolic Math Toolbox™ のライセンスをおもちの場合は、プログラミングによって勾配とヘッセ行列を計算することができます。例は、「Symbolic Math Toolbox による勾配とヘッセ行列の計算」を参照してください。

勾配とヤコビ行列を使用している例は、勾配およびヘッセ行列を使った最小化勾配付き非線形制約Symbolic Math Toolbox による勾配とヘッセ行列の計算解析ヤコビ行列による非線形方程式、およびヤコビ行列を使った非線形方程式を参照してください。

7. ヘッセ行列の供給

ヘッセ行列を与えると、ソルバーはより正確かつより少ない反復で作動します。

以下のソルバーとアルゴリズムはヘッセ行列を受け入れます。

Symbolic Math Toolbox のライセンスをおもちの場合は、プログラミングによって勾配とヘッセ行列を計算することができます。例は、「Symbolic Math Toolbox による勾配とヘッセ行列の計算」を参照してください。

実現可能点がない

ソルバーは、すべての制約を満たす点を TolCon 制約許容誤差内で見つけることができませんでした。継続するには、以下の 1 つ、またはいくつかを試してください。

1. 線形制約の確認
2. 非線形制約の確認

1. 線形制約の確認

線形計画法を解くことにより、境界と線形制約を満たす点を見つけてみます。

  1. 常に 0 である目的関数で線形計画法の問題を定義します。

    f = zeros(size(x0)); % assumes x0 is the initial point
  2. 実行可能点があるかどうかを確かめるために、線形計画法を解きます。

    xnew = linprog(f,A,b,Aeq,beq,lb,ub);
  3. 実行可能点 xnew がある場合は、初期点として xnew を使用し、元の問題を再実行します。

  4. 実行可能点がない場合は、問題は適切に定式化されていません。範囲制約と線形制約の定義を確認します。

2. 非線形制約の確認

範囲制約と線形制約が実行可能である (点がすべての制約を満たす) ことを確認した後、非線形制約を確認します。

  • 目的関数を 0 に設定します。

    @(x)0

    0 の目的関数で最適化を実行します。実行可能点 xnew がある場合は、x0 = xnew を設定し、元の問題を再実行します。

  • 0 の目的関数を使用する実行可能点が見つからない場合は、複数の初期点をもつ 0 の目的関数を使用します。

    • 実行可能点 xnew がある場合は、x0 = xnew を設定し、元の問題を再実行します。

    • 実行可能点が見つからない場合は、次に検討するように、制約を緩めてみます。

非線形の不等式制約を緩め、それから厳しくしてみます。

  1. 非線形制約関数 c を変更し、c-Δ を返します。ここで、Δ は正の数値です。この変更は非線形制約をより満たしやすいくします。

  2. 元の目的関数または 0 の目的関数のどちらかを使用して、新しい制約関数のための実行可能点を探します。

    1. 実行可能点が見つかる場合は、

      1. Δ を減らします

      2. 以前に見つかった点で開始し、新しい制約関数のための実行可能点を探します。

    2. 実行可能点が見つからない場合は、Δ を増やし、再度探してみます。

実行可能点が見つからない場合は、問題が本当に実行不可能であるかもしれません。つまり、解が存在しないことを意味します。すべての制約定義を再度確認します。

非有界な問題

ソルバーは、目的関数が目的制限許容誤差以下の点に達しました。

  • 問題が非有界である可能性があります。つまり、以下をもつ連続点 xi

    lim f(xi) = –∞ があり、

    そのため、すべての xi は問題の制約を満たします。

  • 問題が正しく定式化されていることを確認します。ソルバーは、目的関数を最小化しようとします。最大を望む場合は、目的関数を負数に変更します。例は、「目的関数の最大化」を参照してください。

  • 問題をスケーリングするか、センタリングしてみます。「問題のセンタリングとスケーリング」を参照してください。

  • optimoptions を使用して目的関数の制限許容誤差を緩め、ObjectiveLimit 許容誤差の値を減らします。

fsolve が方程式を解けない

fsolve が方程式を解けない理由はいろいろあります。以下に、その対処法を挙げます。

  1. 初期点の変更」を参照してください。fsolve は初期点に依存します。異なる初期点を与えると、成功のチャンスが増えます。

  2. 方程式の定義をチェックし、それが滑らかであることを確かめます。fsolve は、絶対値のような不連続な勾配をもつ方程式の場合は収束しない可能性があります。fsolve は、不連続な関数では収束しない場合があります。

  3. 方程式が「平方」であることを確認します。これは、入力と出力 (方程式の値と同じ数の未知をもつ) に対する等次元を意味します。

  4. 許容誤差、特に TolFunTolX を変更します。許容誤差を非常に小さい値に設定することにより高精度を得ようとすると、fsolve は収束に失敗することがあります。許容誤差の設定が高すぎると、fsolve が方程式を正確に解けないことがあります。

  5. 問題の定義を確認します。x^2 + 1 = 0 のように、問題によっては実数の解をもちません。

ソルバーの時間がかかりすぎる

ソルバーの時間がかかりすぎる理由はいろいろあります。理由を診断するには、以下の 1 つか複数の手法を試します。

  1. 反復表示の有効化

  2. FunValCheck の有効化

  3. 適切な許容誤差を使用

  4. プロット関数を使用

  5. DerivativeCheck の有効化

  6. 大きな任意の境界の代わりに Inf を使用

  7. 出力関数の使い方

  8. スパース ソルバーまたは乗算関数の使い方

  9. 並列計算の使用

反復表示の有効化

Display オプションを 'iter' に設定します。この設定により、ソルバー反復の結果が表示されます。

反復表示を有効にするには、以下を行います。

  • 最適化アプリケーションを使用して、[表示レベル][各反復] または [各反復と詳細メッセージを表示] となるように選択します。

  • MATLAB コマンド ラインに以下を入力します。

    options = optimoptions('solvername','Display','iter');

    options 構造体を使用して、ソルバーを呼び出します。

反復表示の例については、結果の解釈を参照してください。詳細は、反復表示内で何を探すかを参照してください。

FunValCheck の有効化

たまに目的関数または非線形制約関数が複素数値、無限の値、または NaN を返すため、ソルバーが失敗します。その場合にソルバーの反復を停止させるには、FunValCheck オプションを有効にします。

  • 最適化アプリケーションを使用して、[関数の値のチェック] ペインの [ユーザー指定の関数が Inf、NaN、または複素数を出力した場合はエラーにする] ボックスをオンにします。

  • MATLAB コマンド ラインに以下を入力します。

    options = optimoptions('solvername','FunValCheck','on');

    options 構造体を使用して、ソルバーを呼び出します。

適切な許容誤差を使用

許容誤差、特に TolFunTolX が小さすぎると、ソルバーは収束に失敗することがあります。

最適化アプリケーションを使用して許容誤差を変更するには、[オプション] ペインの上部にある [停止条件] リストを使用します。

コマンド ラインで許容誤差を変更するには、オプションの設定と変更で説明するように、関数 optimoptions を使用します。

プロット関数を使用

プロット関数を使用して、ソルバー反復に関するより視覚的またはより詳しい情報を得ることができます。事前定義されたプロット関数のリストは、最適化アプリケーションの [オプション]、[プロット関数] を参照してください。また、ソルバーの関数リファレンス ページの「オプション」節にもプロット関数のリストがあります。

プロット関数を使用するには、以下を行います。

  • 最適化アプリケーションを使用して、使用する各プロット関数の隣にあるボックスをオンにします。

  • MATLAB コマンド ラインに以下を入力します。

    options = optimoptions('solvername','PlotFcns',{@plotfcn1,@plotfcn2,...});

    options 構造体を使用して、ソルバーを呼び出します。

プロット関数の使用例については、プロット関数の使用 を参照してください。

DerivativeCheck の有効化

導関数 (勾配またはヤコビ行列) をソルバーに与えると、その導関数が不正確な場合は、ソルバーが収束に失敗することがあります。DerivativeCheck オプションの使い方については、勾配またはヤコビ行列の有効性を確認を参照してください。

大きな任意の境界の代わりに Inf を使用

大きな任意の境界 (上限または下限) を使用すると、ソルバーで非常に時間がかかり、場合によっては収束しないことがあります。しかし、境界として Inf または -Inf を設定すれば、ソルバーでかかる時間が短縮され、うまく収束する場合があります。

この理由について説明しましょう。内点法アルゴリズムは初期点を有限範囲の中間点に設定できます。つまり、内点法アルゴリズムでは有限範囲の中ほどに「中央パス」の検出を試みることができます。このため、大きな任意の境界ではこれらの成分が不適切にサイズ変更されることがあります。一方、この目的では無限境界が無視されます。

重要性は低いですが、一部のソルバーでは各制約に対し、主に制約ヘッセ行列によってメモリを使用します。境界を Inf または -Inf に設定すると制約がないため、制約ヘッセ行列の次元が少なく、使用されるメモリも少なくなります。

出力関数の使い方

出力関数を使用して、ソルバー反復に関する詳しい情報を得ることができます。ソルバーは反復ごとに出力関数を呼び出します。出力関数で説明するように、構文を使用して出力関数を記述します。

出力関数の使用例については、例: 出力関数の使用 を参照してください。

スパース ソルバーまたは乗算関数の使い方

大きい問題は、MATLAB のメモリ不足か時間不足の原因になる可能性があります。以下に、メモリを減らす方法を挙げます。

並列計算の使用

Parallel Computing Toolbox™ ライセンスを保有する場合、並列計算を使用するとソルバーをより高速に実行できるかもしれません。詳細は、「並列計算」を参照してください。

この情報は役に立ちましたか?