重开始的FR共轭梯度法

共轭梯度法是共轭方向法的一种。 共轭方向法是在牛顿法和最速下降法之间取了一个折中。每次计算没有牛顿法计算量那么大,收敛的速度又快于最速下降法。

至于为什么重新开始 是因为在靠近解空间的时候,目标函数近似一个正定的二次函数,这时如果不取负梯度方向,即便对于正定二次函数往往也不能产生n个共轭梯度方向,说变量就是为了在靠近解时加速以下,提高算法的效率。

代码实现:

from 实用优化算法.helper import*    # 单独写博客介绍
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D


x1,x2,a = symbols('x1,x2,a')

k = 0

def get_f():
    # f = pow(1 - x1,2) + 2*pow(x2 - pow(x1,2),2)
    # f = (x1 ** 4)/4 + (x2 ** 2)/2 - x1*x2 + x1 - x2
    f = 100 * (x2 - x1 ** 2) ** 2 + (1 - x1) ** 2
    return f

def do_work(x):
    g = get_grad(x,get_f())
    g1 = g
    d = -g
    k = 0
    n = 5
    cnt = 0
    steps_x1 = [x[0][0]]
    steps_x2 = [x[1][0]]

    while get_len_grad(g1) >= 0.00001:
        if k == 0 or k % n == 0:
            d = -g1
        else:
            bt = get_biet(g, g1)
            d = -g1 + bt * d
        step = non_accuracy_search(x,d,get_f())
        # step = golden_search(0,1,x,d,get_f())  # 调用实验一的黄金分割法进行精确搜索
        next_x = x + step*d
        steps_x1.append(next_x[0][0])
        steps_x2.append(next_x[1][0])
        k += 1
        g = g1
        g1 = get_grad(next_x,get_f())
        x = next_x
        cnt += 1
        print(cnt,' ',x,',',end = '\n\n')
    print('\n','最终结果x*:',x,'\n','f(x*):',get_f().subs(x1,x[0][0]).subs(x2,x[1][0]))
    return steps_x1,steps_x2



if __name__ == '__main__':
    x0 = [[0],[0]]
    x0 = np.array(x0)
    step_x1,step_x2 = do_work(x0)


    fig = plt.figure()
    ax = Axes3D(fig)
    x = np.arange(0, 2.5, 0.1)
    y = np.arange(0, 2.5, 0.1)
    X1, X2 = np.meshgrid(x, y)
    plt.figure(figsize=(10, 6))
    Z = (X1 ** 4)/4 + (X2 ** 2)/2 - X1*X2 + X1 - X2  # 设置二维函数的表达式
    # Z = (1 - X1)**2 + 2 * (X2 - X1**2)**2
    step_x1 = np.array(step_x1)
    step_x2 = np.array(step_x2)
    step_x3 = (step_x1 ** 4) / 4 + (step_x2 ** 2) / 2 - step_x1 * step_x2 + step_x1 - step_x2
    # step_x3 = (1 - step_x1) ** 2 + 2 * (step_x2 -   step_x1 ** 2) ** 2
    bar = plt.contourf(X1, X2, Z, 25, cmap=plt.cm.hot)
    plt.plot(step_x1, step_x2, marker='*')
    ax.plot_surface(X1, X2, Z, rstride=1, cstride=1)
    ax.plot(step_x1, step_x2, step_x3, c='r',marker = '*')
    plt.colorbar(bar)
    plt.show()


发布了341 篇原创文章 · 获赞 32 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/weixin_41514525/article/details/103225103