码迷,mamicode.com
首页 > 编程语言 > 详细

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

时间:2015-05-19 22:37:25      阅读:493      评论:0      收藏:0      [点我收藏+]

标签:优化算法   dfp   拟牛顿法   

一、牛顿法

    在博文“优化算法——牛顿法(Newton Method)”中介绍了牛顿法的思路,牛顿法具有二阶收敛性,相比较最速下降法,收敛的速度更快。在牛顿法中使用到了函数的二阶导数的信息,对于函数技术分享,其中技术分享表示向量。在牛顿法的求解过程中,首先是将函数技术分享技术分享处展开,展开式为:

技术分享

其中,技术分享,表示的是目标函数在技术分享的梯度,是一个向量。技术分享,表示的是目标函数在技术分享处的Hesse矩阵。省略掉最后面的高阶无穷小项,即为:

技术分享

上式两边对技术分享求导,即为:

技术分享

    在基本牛顿法中,取得最值的点处的导数值为技术分享,即上式左侧为技术分享。则:

技术分享

求出其中的技术分享
技术分享

从上式中发现,在牛顿法中要求Hesse矩阵是可逆的。  
    当技术分享时,上式为:

技术分享

此时,是否可以通过技术分享技术分享技术分享技术分享模拟出Hesse矩阵的构造过程?此方法便称为拟牛顿法(QuasiNewton),上式称为拟牛顿方程。在拟牛顿法中,主要包括DFP拟牛顿法,BFGS拟牛顿法。

二、DFP拟牛顿法

1、DFP拟牛顿法简介

        DFP拟牛顿法也称为DFP校正方法,DFP校正方法是第一个拟牛顿法,是有Davidon最早提出,后经FletcherPowell解释和改进,在命名时以三个人名字的首字母命名。
对于拟牛顿方程:

技术分享

化简可得:

技术分享

技术分享,可以得到:

技术分享

DFP校正方法中,假设:

技术分享

2、DFP校正方法的推导

    令:技术分享,其中技术分享均为技术分享的向量。技术分享技术分享
    则对于拟牛顿方程技术分享可以简化为:

技术分享

技术分享代入上式:

技术分享

技术分享代入上式:

技术分享

技术分享

已知:技术分享为实数,技术分享技术分享的向量。上式中,参数技术分享技术分享解的可能性有很多,我们取特殊的情况,假设技术分享技术分享。则:

技术分享

代入上式:

技术分享

技术分享

技术分享技术分享,则:

技术分享

技术分享


则最终的DFP校正公式为:

技术分享

3、求解具体的优化问题

    求解无约束优化问题

技术分享

其中,技术分享

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. dfp.py
    #coding:UTF-8
    '''
    Created on 2015年5月19日
    
    @author: zhaozhiyong
    '''
    
    from numpy import *
    from function import *
    
    def dfp(fun, gfun, x0):
        result = []
        maxk = 500
        rho = 0.55
        sigma = 0.4
        m = shape(x0)[0]
        Hk = eye(m)
        k = 0
        while (k < maxk):
            gk = mat(gfun(x0))#计算梯度
            dk = -mat(Hk)*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
            
            #DFP校正
            x = x0 + rho ** mk * dk
            sk = x - x0
            yk = gfun(x) - gk
            if (sk.T * yk > 0):
                Hk = Hk - (Hk * yk * yk.T * Hk) / (yk.T * Hk * yk) + (sk * sk.T) / (sk.T * yk)
            
            k = k + 1
            x0 = x
            result.append(fun(x0))
        
        return result
    

  3. testDFP.py
    #coding:UTF-8
    '''
    Created on 2015年5月19日
    
    @author: zhaozhiyong
    '''
    
    from bfgs import *
    from dfp import dfp
    
    import matplotlib.pyplot as plt  
    
    x0 = mat([[-1.2], [1]])
    result = dfp(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()
    

4、实验结果

技术分享





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

标签:优化算法   dfp   拟牛顿法   

原文地址:http://blog.csdn.net/google19890102/article/details/45848439

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!