优化算法——拟牛顿法之BFGS算法

一、BFGS算法简介

    BFGS算法是使用较多的一种拟牛顿方法,是由Broyden,Fletcher,Goldfarb,Shanno四个人分别提出的,故称为BFGS校正。
    同DFP校正的推导公式一样,DFP校正见博文“ 优化算法——拟牛顿法之DFP算法”。对于拟牛顿方程:
可以化简为:
,则可得:
在BFGS校正方法中,假设:

二、BFGS校正公式的推导

    令 ,其中 均为 的向量。
    则对于拟牛顿方程 可以化简为:
代入上式:
代入上式:
    已知: 为实数, 的向量。上式中,参数 解的可能性有很多,我们取特殊的情况,假设 。则
代入上式:
,则:
则最终的BFGS校正公式为:

三、BFGS校正的算法流程

    设 对称正定, 由上述的BFGS校正公式确定,那么 对称正定的充要条件是
    在博文“ 优化算法——牛顿法(Newton Method)”中介绍了非精确的线搜索准则:Armijo搜索准则,搜索准则的目的是为了帮助我们确定学习率,还有其他的一些准则,如Wolfe准则以及精确线搜索等。在利用Armijo搜索准则时并不是都满足上述的充要条件,此时可以对BFGS校正公式做些许改变:
BFGS拟牛顿法的算法流程:

四、求解具体优化问题

   求解无约束优化问题
其中,
python程序实现:
  1. function.py
    #coding:UTF-8
    '''
    Created on 2015年5月19日
    
    @author: zhaozhiyong
    '''
    
    from numpy import *
    
    #fun
    def fun(x):
        return 100 * (x[0,0] ** 2 - x[1,0]) ** 2 + (x[0,0] - 1) ** 2
    
    #gfun
    def gfun(x):
        result = zeros((2, 1))
        result[0, 0] = 400 * x[0,0] * (x[0,0] ** 2 - x[1,0]) + 2 * (x[0,0] - 1)
        result[1, 0] = -200 * (x[0,0] ** 2 - x[1,0])
        return result
    
  2. bfgs.py
    #coding:UTF-8
    
    from numpy import *
    from function import *
    
    def bfgs(fun, gfun, x0):
        result = []
        maxk = 500
        rho = 0.55
        sigma = 0.4
        m = shape(x0)[0]
        Bk = eye(m)
        k = 0
        while (k < maxk):
            gk = mat(gfun(x0))#计算梯度
            dk = mat(-linalg.solve(Bk, gk))
            m = 0
            mk = 0
            while (m < 20):
                newf = fun(x0 + rho ** m * dk)
                oldf = fun(x0)
                if (newf < oldf + sigma * (rho ** m) * (gk.T * dk)[0,0]):
                    mk = m
                    break
                m = m + 1
            
            #BFGS校正
            x = x0 + rho ** mk * dk
            sk = x - x0
            yk = gfun(x) - gk
            if (yk.T * sk > 0):
                Bk = Bk - (Bk * sk * sk.T * Bk) / (sk.T * Bk * sk) + (yk * yk.T) / (yk.T * sk)
            
            k = k + 1
            x0 = x
            result.append(fun(x0))
        
        return result
    
  3. testBFGS.py
    #coding:UTF-8
    '''
    Created on 2015年5月19日
    
    @author: zhaozhiyong
    '''
    
    from bfgs import *
    
    import matplotlib.pyplot as plt  
    
    x0 = mat([[-1.2], [1]])
    result = bfgs(fun, gfun, x0)
    
    n = len(result)
    ax = plt.figure().add_subplot(111)
    x = arange(0, n, 1)
    y = result
    ax.plot(x,y)
    
    plt.show()

五、实验结果

最速下降算法: 最速下降法是一种基本的迭代算法,也叫做梯度下降法。该算法通过不断地朝着函数的梯度方向进行搜索,来找到函数的最小值。 在MATLAB中,可以使用fminunc函数来实现最速下降算法: ```matlab options = optimoptions('fminunc','Algorithm','quasi-newton','Display','iter'); x0 = [1;1]; fun = @(x)100*(x(2)-x(1)^2)^2 + (1-x(1))^2; [x,fval] = fminunc(fun,x0,options); ``` 其中,options参数用于设置算法选项,x0是初始点,fun是目标函数,[x,fval]为最优解和最优值。 阻尼牛顿法: 阻尼牛顿法是一种基于牛顿法的迭代算法,旨在解决牛顿法中Hessian矩阵可能不正定导致算法无法收敛的问题。该算法采用了阻尼因子来控制步长,从而避免了牛顿法中可能出现的问题。 在MATLAB中,可以使用fminunc函数来实现阻尼牛顿法: ```matlab options = optimoptions('fminunc','Algorithm','trust-region','HessianFcn','objective','Display','iter'); x0 = [1;1]; fun = @(x)100*(x(2)-x(1)^2)^2 + (1-x(1))^2; [x,fval] = fminunc(fun,x0,options); ``` 其中,options参数用于设置算法选项,HessianFcn参数用于设置Hessian矩阵的计算方法,objective表示使用目标函数计算Hessian矩阵,x0是初始点,fun是目标函数,[x,fval]为最优解和最优值。 BFGS方法: BFGS方法是一种基于梯度的优化算法,用于寻找目标函数的最小值。该算法通过不断地更新近似的Hessian矩阵来进行迭代,从而找到最优解。 在MATLAB中,可以使用fminunc函数来实现BFGS方法: ```matlab options = optimoptions('fminunc','Algorithm','quasi-newton','HessUpdate','bfgs','Display','iter'); x0 = [1;1]; fun = @(x)100*(x(2)-x(1)^2)^2 + (1-x(1))^2; [x,fval] = fminunc(fun,x0,options); ``` 其中,options参数用于设置算法选项,HessUpdate参数用于设置Hessian矩阵的更新方法,bfgs表示使用BFGS方法,x0是初始点,fun是目标函数,[x,fval]为最优解和最优值。
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值