1. 程式人生 > >MATLAB學習筆記05——無約束一維極值問題(二)斐波那契法、基本牛頓法和全域性牛頓法

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;

牛頓法的缺陷是當初始點與極小值點之間存在極大值點時,收斂速度將變得很慢甚至不收斂。