最適化の解の検証
数値解を得る
関数 solve
は、問題の各変数が構造体内で 1 つのフィールドをもつ構造体として解を返します。この構造体から問題の式の数値を簡単に得るには、関数 evaluate
を使用します。
たとえば、2 変数の線形計画問題を解きます。
x = optimvar('x'); y = optimvar('y'); prob = optimproblem; prob.Objective = -x -y/3; prob.Constraints.cons1 = x + y <= 2; prob.Constraints.cons2 = x + y/4 <= 1; prob.Constraints.cons3 = x - y <= 2; prob.Constraints.cons4 = x/4 + y >= -1; prob.Constraints.cons5 = x + y >= 1; prob.Constraints.cons6 = -x + y <= 2; sol = solve(prob)
Solving problem using linprog. Optimal solution found. sol = struct with fields: x: 0.6667 y: 1.3333
解での目的関数の値が必要であるとします。問題を再実行し、今度は目的関数の値と解を要求します。
[sol,fval] = solve(prob)
Solving problem using linprog. Optimal solution found. sol = struct with fields: x: 0.6667 y: 1.3333 fval = -1.1111
時間のかかる問題の場合は代わりに、evaluate
を使用して解で目的関数を評価することで、時間を節約します。
fval = evaluate(prob.Objective,sol)
fval = -1.1111
解の質の検証
報告された解が正確であるかどうかを確認するために、solve
からの出力を確認できます。すべての solve
出力を返します。
[sol,fval,exitflag,output,lambda] = solve(prob);
終了フラグを確認します。
exitflag = OptimalSolution
は一般に、solve
が解に収束したことを示します。その他のexitflag
値の説明は、exitflag
を参照してください。コマンド ラインまたは出力構造体の終了メッセージを確認します。終了メッセージが、ソルバーが解に収束したことを示している場合、一般に解は信頼できます。このメッセージは、
exitflag = OptimalSolution
に相当します。整数制約がある場合は、終了メッセージまたは出力構造体でギャップの絶対値と相対ギャップを確認します。これらのギャップがゼロまたはゼロに近い場合は、解を信頼できます。
実行不可能解
solve
が、問題が実行不可能であることを報告した (終了フラグが NoFeasiblePointFound
である) 場合は、さまざまな点で問題の実行不可能性を調べ、どの制約が過度に限定的である可能性があるかを判別します。すべての成分について範囲が有限である x
という名前の単一の連続最適化変数と、制約 constr1
~ constr20
があるとします。
N = 100; % check 100 points infeas = zeros(N,20); % allocate L = x.LowerBound; U = x.UpperBound; S = numel(L); pthist = cell(N); for k = 1:N pt = L + rand(size(L)).*(U-L); pthist{k} = pt; for j = 1:20 infeas(k,j) = infeasibility(['constr',num2str(j)],pt); end end
関連する点 pt{a}
が制約 b
に対して実行不可能な場合は常に、結果 infeas(a,b)
の値は非ゼロになります。
解が得られるまで時間がかかりすぎる
solve
に長い時間がかかる場合は、考えられる原因と修正方法がいくつかあります。
"問題の定式化に時間がかかる"。入れ子形式のループで目的または制約の式を定義している場合は、
solve
が内部で問題を行列形式に変換するために長い時間がかかることがあります。解を迅速に得るには、ベクトル化された形式での定式化を試みてください。詳細については、効率的な最適化問題の作成を参照してください。"混合整数線形計画法の解が得られるまでに時間がかかる"。オプションを設定することで、整数問題を高速化できる場合があります。また、より迅速に解くために問題を定式化し直すこともできます。詳細については、整数線形計画法の調整を参照してください。
"非線形計画法の解が得られるまでに時間がかかる"。ヒントについては、ソルバーの時間がかかりすぎるを参照してください。より詳しいヒントについては、ソルバーが失敗する場合を参照してください。
"ソルバーの制限を超えている"。一部の問題を解くために、
solve
が既定数を超えて解のステップを実行することがあります。整数制約のある問題の場合は、LPMaxIterations
、MaxNodes
、MaxTime
、またはRootLPMaxIterations
のいずれかのオプションを既定より大きい値に増やすことで許容ステップ数を増やします。これらのオプションを設定するには、optimoptions('intlinprog',...)
を使用します。非整数問題の場合は、optimoptions('linprog','MaxIterations',...)
を使用してMaxIterations
オプションを増やします。オプション
を参照してください。
参考
evaluate
| infeasibility
| solve