最优化方法——BGFS变尺度算法

目录

 1、BGFS基本思想

2、BGFS变尺度算法的计算公式 

3、BGFS变尺度算法Python实现

4、结果 


关于下面的部分,请看我的另一篇博客 

最优化方法——最速下降法,阻尼牛顿法,共轭梯度法

1、不精确一维搜素

1.1 Wolfe-Powell 准则 

 2、不精确一维搜索算法计算步骤

 1、BGFS基本思想

2、BGFS变尺度算法的计算公式 

3、BGFS变尺度算法Python实现

'''
wolfe powell 不精确一维搜索准则
1、f(x_(k)) - f(x_(k+1)) >= -c_1 * lamda * inv(g_k) * s_(k)
2、inv(g_(k+1)) * s_(k) >= c_2 * inv(g_(k)) * s_(k)
根据计算经验,常取c_1 = 0.1, c_2 = 0.5
0 < c_1 < c_2 < 1
'''

"""
函数 f(x)=100*(x(1)^2-x(2))^2+(x(1)-1)^2
梯度 g(x)=(400*(x(1)^2-x(2))*x(1)+2*(1-x(1)),-200*(x(1)^2-x(2)))
"""
from numpy import *
import sys
import matplotlib.pyplot as plt

def object_function(xk):
    f = 100 * (xk[0, 0] ** 2 - xk[1, 0]) ** 2 + (xk[0, 0] - 1) ** 2
    return f

def gradient_function(xk):
    gk = mat(
            [
                [400 * xk[0, 0] * (xk[0, 0] ** 2 - xk[1, 0]) + 2 * (xk[0, 0] - 1)],
                [-200 * (xk[0, 0] ** 2 - xk[1, 0])]
            ]
    )
    return gk

def wolfe_powell(xk, sk):

    alpha = 1.0
    a = 0.0
    b = -sys.maxsize
    c_1 = 0.1
    c_2 = 0.5
    k = 0
    while k < 100:
        k += 1
        if object_function(xk) - object_function(xk + alpha * sk) >= -c_1 * alpha * gradient_function(xk).T * sk:
            #print('满足条件1')
            if (gradient_function(xk + alpha * sk)).T * sk >= c_2 * gradient_function(xk).T * sk:
                #print('满足条件2')
                return alpha
            else:
                a = alpha
                alpha = min(2 * alpha, (alpha + b) / 2)

        else:
            b = alpha
            alpha = 0.5 * (alpha + a)
    return alpha

# BFGS变尺度算法
def BFGS(x0, eps):
    xk = x0
    gk = gradient_function(xk)
    sigma = linalg.norm(gk)
    m = shape(x0)[0]
    HK = eye(m)  # 初始HK为二阶单位阵

    sk = -1 ** HK * gk

    step = 0
    w = zeros((2, 10 ** 3))# 保存迭代把变量xk

    while sigma > eps and step < 10000:
        # w[:, step] = xk

        step += 1
        alpha = wolfe_powell(xk, sk)

        x0 = xk
        xk = xk + alpha * sk
        print(alpha)
        delta_x = xk - x0

        g0 = gk
        gk = gradient_function(xk)
        delta_g = gk - g0
        # print('delta_x为:{}, delta_g为:{}'.format(delta_x, delta_g))
        if (delta_g.T * delta_x > 0):
            # HK = HK - (HK * delta_x * delta_x.T * HK) / (delta_x.T * HK * delta_x) + (delta_g * delta_g.T) / (delta_g.T * delta_x)
            miu = ([[1, 1], [1, 1]] + delta_g.T * HK * delta_g / (delta_x.T * delta_g))
            fenzi = miu * delta_x * delta_x.T - HK * delta_g * delta_x.T - delta_x * delta_g.T * HK
            fenmu = delta_x.T * delta_g
            HK = HK + fenzi / fenmu

        sk = -1 * HK * gk
        sigma = linalg.norm(delta_x)

        print('--The {}-th iter,sigma is {}, the result is {},object value is {:.4f}'.format(step, sigma, xk.T, object_function(xk)))
    return w

if __name__ == '__main__':
    eps = 1e-5
    x0 = mat([[0.001], [0]])

    # 变尺度算法
    W = BFGS(x0, eps)

4、结果 

--The 1-th iter,sigma is 1.4129404873242466, the result is [[1.0000998 0.9990998]],object value is 0.0001
--The 2-th iter,sigma is 0.000836649284267688, the result is [[0.99926534 0.99903935]],object value is 0.0000
--The 3-th iter,sigma is 0.0, the result is [[0.99926534 0.99903935]],object value is 0.0000

猜你喜欢

转载自blog.csdn.net/hushaoqiqimingxing/article/details/89389170
今日推荐