DownhillSimplex[] Functions manual
DownhillSimplex[] -Nelder-Mead法を用いた最適化
DownhillSimplex[initial,f,MaxIterations->100];
N次元の引数の関数の最小値解を得る場合に、初期状態ではN+1個の点からなる多面体、すなわち単体を選ぶ、これを逐次的に改良することで、最適解を得る。
関数の導関数が分からなくても、関数値だけ分かれば適用できる。しかし、回数が多く掛かる欠点がある。
N+1個の点の中で関数値が最大である点を、残りN個の点が定める超平面の逆側に、単体の体積を保存したまま移動させる。
4つのパラメータの場合、5個の初期値を用意する。
r1,r2,r3,r4のパラメータが与えれるので与えられたパラメータに対するsimulation結果を与える。
FFS;
d0={{-11.5, {-14,-35,-17.5,-20},
{-18.0, {-14,-20,-17.5,-40},
{-18.5, {-14,-40,-15.0,-40},
{-22.8, {-15,-20,-15.0,-20},
{-22.4, {-15,-40,-15.0,-40}};
initial=Sort[d0]; ! 初期値はSortしておく
f=[{r1_,r2_,r3_,r4_}]:=(Print["r=",{r1,r2,r3,r4}];Read[5,Real]);
! 関数値を端末入力待ちになる。
! この代わりにsimulation結果を入れてやれば良い。
result=DownhillSimplex[initial,f,MaxIteration->5];
end;
<実行例>-----------------------------------------------------------------
r={-15,-25,-13.75,-10} ! この変数に対応する関すうちが要求されている。
-20 ! 端末から値を入力
{ -22.80000, -22.40000, -20.00000, -18.50000, -18.00000} ! 1回目の更新
r={-15.5,-42.5,-11.875,-35}
-17 ! 端末から値を入力
r={-14.375,-25.625,-16.09375,-23.75}
-23 ! 端末から値を入力
{ -23.00000, -22.80000, -22.40000, -20.00000, -18.50000} ! 2回目の更新
r={-15.6875,-15.3125,-14.921875,-6.875}
-25 ! 端末から値を入力
r={-16.53125,-2.96875,-14.8828125,9.6875}
-30 ! 端末から値を入力
{ -30.00000, -23.00000, -22.80000, -22.40000, -20.00000} ! 3回目の更新
r={-15.453125,-19.296875,-16.73828125,-27.03125}
-19 ! 端末から値を入力
r={-15.11328125,-23.57421875,-14.4970703125,-14.2578125}
-29 ! 端末から値を入力
{ -30.00000, -29.00000, -23.00000, -22.80000, -22.40000} ! 4回目の更新
r={-15.509765625,3.916015625,-15.23681640625,15.83984375}
-31 ! 端末から値を入力
r={-15.7646484375,25.8740234375,-15.355224609375,43.759765625} ! 5回目の更新
!MaxIterations->5なのでこれで終了
end;
In[2]:= result
Out[2]:= {{-31,{-15.509765625,3.916015625,-15.23681640625,15.83984375}},
{-30,{-16.53125,-2.96875,-14.8828125,9.6875}},
{-29,{-15.11328125,-23.57421875,-14.4970703125,-14.2578125}},
{-23,{-14.375,-25.625,-16.09375,-23.75}},{-22.8,{-15,-20,-15,-20}}}
In[3]:=
Example2
f:=Apply[Function[{x,y},((x^2+y^2)-1)*(x^2+y^2)-(x-.5)/3.],#]&; ! 関数を定義する
v={{1.,1.},{0.,-1.},{0.,1.}}; ! 初期値
limit={{-0.5,-1.5},{0.65,1.5}}; ! 探索範囲を指定
p=Sort[Map[{f[#],#}&,v]]; ! 初期値をソートする
DownhillSimplex[p,f,MaxIteration->100,
Tolerance->1e-4,VariableRange->limit]; !極小値を探索する