Optimization Toolbox の関数における目的関数と非線形制約関数の呼び出し順序はどうなっていますか?
6 views (last 30 days)
Show older comments
MathWorks Support Team
on 3 Aug 2016
Edited: MathWorks Support Team
on 21 Aug 2017
非線形制約を持つ関数の最適化を Optimization Toolbox の関数で行っています。非線形制約関数は、目的関数の現在の入力値である "x" に依存しています。目的関数では、既に x に対して出力値が計算されているため、制約関数内では、再計算させずに、目的関数で計算されたものを継承させたいのですが、最適化関数では制約関数の実行前に必ず目的関数が評価されるかどうか、分かりません。
例えば、以下のような入れ子関数で定義された FMINCON 関数による最適化について考えます。
function [x,fval] = runsharedvalues(a,b,c,d,lower)
objval = []; % 共有させたい値の初期値
xcheck = [];
x0 = [-1 1]; % 最適化パラメータの初期値
options = optimset('LargeScale','off');
[x,fval] = fmincon(@objfun,x0,[],[],[],[],[],[],@constrfun,options);
% 目的関数
function f = objfun(x)
% 制約関数 constrfun 内で使用したい objval 変数の計算
objval = exp(x(1))*(a*x(1)^2+b*x(2)^2+c*x(1)*x(2)+d*x(2)+1);
f = objval;
end
% 制約関数
function [c,ceq] = constrfun(x)
c(1) = -objval + lower;
c(2:3) = [1.5 + x(1)*x(2) - x(1) - x(2); -x(1)*x(2) - 10];
ceq = [];
end
end
このとき、制約関数は、目的関数内で計算された "objval" を使用しています。しかし、制約関数を呼び出す前に入力の "x" の値が最適化関数内で更新されたとき、本来使用したい "objval" ではない値を使用してしまうことになります。
制約関数内で使用される "objval" が現在の目的関数で使用されている "x" に対する値であるように設定するにはどうすればよいか、教えてください。
Accepted Answer
MathWorks Support Team
on 21 Aug 2017
Edited: MathWorks Support Team
on 21 Aug 2017
一般に、Optimization Toolbox の関数は、非線形制約関数を評価する前に、目的関数を評価します。しかし、非線形制約関数が、同じ "x" の値で目的関数が評価される前に、ある特定の "x" の値を渡される可能性も考えられます。
目的関数の "x" の値に対応する値を確実に共有するためには、以下のように修正する必要があります。
function [x,fval] = runsharedvalues(a,b,c,d,lower)
objval = []; % 共有させたい値の初期値
xcheck = [];
x0 = [-1 1]; % 最適化パラメータの初期値
options = optimset('LargeScale','off');
[x,fval] = fmincon(@objfun,x0,[],[],[],[],[],[],@constrfun,options);
% 目的関数
function f = objfun(x)
% Variable objval shared with constrfun
objval = exp(x(1))*(a*x(1)^2+b*x(2)^2+c*x(1)*x(2)+d*x(2)+1);
f = objval;
xcheck = x; % cnstrfun で共有するxcheck
end
% 制約関数
function [con,ceq] = constrfun(x)
% 現在の x が objfun 関数で評価された objval で使われている x と
% 一致しない場合を除き、objval の値を再利用する。
% 一致しなければ、objval の値は再計算する。
if any(x ~= xcheck)
objval = exp(x(1))*(a*x(1)^2+b*x(2)^2+c*x(1)*x(2)+d*x(2)+1);
end
con(1) = -objval + lower;
con(2:3) = [1.5 + x(1)*x(2) - x(1) - x(2); -x(1)*x(2) - 10];
ceq = [];
end
end
"x" の値は、テンポラリ変数 "xcheck" に代入されています。これにより、非線形制約関数が呼び出されたとき、"objval" が現在の "x" の値に基づいた値であるかどうかを確認することができます。もし、現在の値 "x" の値で評価されていない場合には、制約関数内にて、再度 objval を計算しなおします。
0 Comments
More Answers (0)
See Also
Categories
Find more on Optimization Toolbox in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!