Fletcher-Reeves法サンプルプログラム
無制約最適化問題で使われる(?)Fletcher-Reeves法のプログラム例を載せます.アルゴリズム習得用で組んだものです.
手法自体は適当に調べました.
http://people.equars.com/~marco/poli/phd/node54.html
例:天井からばね定数1のばねによって連結された4つの重量1の質点の平衡点を求める.ポテンシャルエネルギーを目的関数とする最小化問題.
global k mg L
mg=1;%おもりの重量
L=1;%ばね自然長
y=[1 2 3 4]';%初期値
k=1;%ばね定数
gF=zeros(4,2);%betaを計算するために2列用意
gF(:,1)=gradF(y);
%↓目的関数Fの定義
F=@(y) (k/2)**1/(gF(:,1)'*gF(:,1));%betaが定義される
s=-gF(:,2)+beta*s;
end
%y_{i+1}=y_{i}+alpha*s;
%ここでalhpaはF(y_{i+1})を最小化する値
%alphaを少しずつ大きくしながら探索する
num_roop2=100;%Fを最小化するalphaに到着するのに十分な値
step=0.1;%探索の歩幅
F_temp=zeros(2,1);%一時的な目的関数
F_temp(1)=F(y);%出発点
for ii=1:num_roop2;%ループするよ
F_temp(2)=F(y+step*ii*s);%1歩先のF
if F_temp(2)>=F_temp(1);%もし1歩先のFの方が大きいなら
break%繰り返し計算を終了する
else%まだFが小さくなりそうなら
F_temp(1)=F_temp(2);%参照するFを置き換える
end
end
y=y+step*(ii-1)*s;%この半直線上でFを最小化するy
gF(:,1)=gF(:,2);%繰り返しのために勾配を置き換え
end
if jj==num_roop1;%もし収束していないなら
fprintf('計算は収束していない')%その旨を表示
end====================================================
====gradF.m=========================================
====================================================
function out=gradF(y)
global k mg L
out(1)=k*(y(1) -L)-k*(y(2)-y(1)-L)-mg;
out(2)=k*(y(2)-y(1)-L)-k*(y(3)-y(2)-L)-mg;
out(3)=k*(y(3)-y(2)-L)-k*(y(4)-y(3)-L)-mg;
out(4)=k*(y(4)-y(3)-L) -mg;
これによって,最適解[5 9 12 14]が得られます.もちろん力のつり合い等で求めた解と一致します.
*1:y(1)-L)^2+(y(2)-y(1)-L)^2+(y(3)-y(2)-L)^2+(y(4)-y(3)-L)^2)-mg*sum(y); count=0;%カウント(一周目かどうかが分かればよい) num_roop1=100;%収束するのに十分な値 for jj=1:num_roop1; gF(:,2)=gradF(y);%勾配 if max(abs(gF(:,2)))<=1e-3;%収束判定 break end %探索方向sを決定する if count==0;%もし一周目なら s=-gF(:,2);%betaは0; else%2周目以降なら beta=(gF(:,2)'*gF(:,2