MATLAB學習筆記05——無約束一維極值問題(二)斐波那契法、基本牛頓法和全域性牛頓法
一、斐波那契法
1.斐波那契法與黃金分割法不同的是,黃金是單向縮小區間的演算法,斐波那契是雙向收縮。
斐波那契數列指的是 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233,377,610,987,1597,2584,4181,6765,10946,17711,28657,46368。第三項開始,每一項為前兩個數的和。
2.演算法步驟:
1.Fn為斐波那契數列,區間[a1,b1],精度e,使Fn>=(b1-a1)/e,計算r1和u1,
r1=a1+Fn-2/Fn*(b1-a1)
u1=a1+Fn-1/Fn*(b1-a1)
令k=1
2.若f(rk)>f(uk)則轉3,否則轉4
3.
ak+1=rk
bk+1=bk
rk+1=uk
uk+1=ak+1+Fn-k-1/Fn-k*(bk+1-ak+1)
若k=n-2,轉6,否則轉5
4.
ak+1=ak
bk+1=uk
uk+1=rk
rk+1=ak+1+Fn-k-2/Fn-k*(bk+1-ak+1)
若k=n-2,轉6,否則轉5
5.令k=k+1,轉2
6.令rn=rn-1,un=rn-1+g(g>0)
若f(rn)>f(un),令an=rn,bn=bn-1
否則令an=an-1,bn=rn,停止計算,極小值點包含於[an,bn]
實現程式碼
function [x,minf]=minFBNQ(f,a,b,delta,eps)
format long;
%斐波那契法
%目標函式f
%極值區間左右,a,b
%演算法結束引數delta
%精度eps
%目標函式最小值點x
%目標函式最小值minf
if nargin==4
eps=1.0e-6;
end
F=ones(2,1);
N=(b-a)/eps;
c=F(2)-N;
n=2;
while c<0 %求出n
n=n+1;
F(n)=F(n-1)+F(n-2);
c=F(n)-N;
end
l=a+F(n-2)*(b-a)/F(n);%試探點
u=a+F(n-1)*(b-a)/F(n);%試探點
k=1;
while 1
fl=subs(f,symvar(f),l);%試探點函式值
fu=subs(f,symvar(f),u);%試探點函式值
if fl>fu
a=l;%改變區間左端點
l=u;
u=a+F(n-k-1)*(b-a)/F(n-k);%縮小區間
if(k==n-3)
break;
else
k=k+1;
end
else
b=u;%改變區間右端點
u=l;
l=a+F(n-k-2)*(b-a)/F(n-k);%縮短搜尋區間
if(k==n-3)
break;
else
k=k+1;
end
end
end
if k==1000000
disp('找不到最小值');
x=NaN;
minf=NaN;
return;
end
u=l+delta;
fl=subs(f,symvar(f),l);
fu=subs(f,symvar(f),u);
if fl>fu
a=1;
else
b=1;
end
x=(a+b)/2;
minf=subs(f,symvar(f),x);
minf=double(minf);
format short;
當初始試驗點接近無窮大時,斐波那契的區間收縮率接近0.618。這與斐波那契數列極限值接近0.618有關。
二、牛頓法
基本牛頓法是一種利用倒數的演算法,它每一步迭代方向都朝向最小值方向。
實現程式碼如下:
function [x,minf]=minNiudun(f,x0,eps)
%目標函式:f
%初始點:x0
%精度:eps
%目標函式最小值時變數:x
%目標函式最小值:minf
format long;
if nargin==0
eps=1.0e-6;
end
df=diff(f); %一階導數
d2f=diff(df);%二階導數
k=0;
tol=1;
while tol>eps
dfx=subs(df,symvar(f),x0);%一階導數值
d2fx=subs(d2f,symvar(f),x0);%二階導數值
x1=x0-dfx/d2fx;%步長
k=k+1;
tol=abs(dfx);
x0=x1;
end
x=x1;
minf=subs(f,symvar(f),x);
minf=doule(minf);
format short;
三、全域性牛頓法
基本牛頓法使用的前提條件是初始點要充分靠近極小值點,而全域性牛頓法沒有此要求。
function [x,minf]=minGlbNiudun(f,x0,eps)
format long;
if nargin==2
eps=1.0e-6;
end
var=varsym(f);
df=diff(f);%一介導
d2f=diff(df);%二介導
bConti=1;
while bConti
fx0=subs(f,var,x0);%函式值
dfx=subs(df,var,x0);%一介導數值
d2fx=subs(d2f,var,x0);%二階導數值
if dfx==0
if d2fx>=0
x=x0;
bConti=0;
end
delta=eps;
while 1
fd=subs(f,var,x0+delta);%向前搜尋
if fd>=fx0 %函式值變大則增加步長繼續搜尋
delta=delta*2;
continue;
else
x0=x0+delta; %確定新的搜尋點
break;
end
end
else
beta=d2fx;
if beta<=0
beta=1;
end
alpha=1;
while 1
x1=x0-alpha*dfx/beta;%判斷新的點是否可接受
fx1=subs(f,var,x1);
tol=fx1-fx0+(dfx)^2*alpha/4/beta;
if tol<=0;
if abs(x1-x0)<=eps
bConti=0;
x=x1;
break;
else
x0=x1;
break;
end
else
alpha=alpha/2;%縮短步長
end
end
end
end
minf=subs(f,var,x);
x=double(x);
minf=double(minf);
format short;
牛頓法的缺陷是當初始點與極小值點之間存在極大值點時,收斂速度將變得很慢甚至不收斂。