PRP 共轭梯度法

PRP共轭梯度法对于正定的二次函数而言和FR共轭梯度法效果是近似的,而对于一般的函数来说的话,PRP算法一般优于FR算法

 

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 = (3/2) * pow(x1,2) + pow(x2,2)/2 - x1*x2 - 2*x1
    f = 100 * (x2 - x1 ** 2) ** 2 + (1 - x1) ** 2     # Rosenbrock函数
    return f


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

    while get_len_grad(g1) >= 0.00001:
        bt = get_biet_PRP(k,g,g1)
        d = -g1 + bt * d
        step = non_accuracy_search(x,d,get_f())   # Armijo 非精确搜索
        # step = golden_search(0,2,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(-3, 3, 0.1)
    y = np.arange(-3, 3, 0.1)
    X1, X2 = np.meshgrid(x, y)
    plt.figure(figsize=(10, 6))
    Z = (X1 ** 4)/4 + (X2 ** 2)/2 - X1*X2 + X1 - X2
    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

    bar = plt.contourf(X1, X2, Z, 5, cmap=plt.cm.Blues)
    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()


 

### 不同共轭梯度法的收敛性条件适用场景 #### FR共轭梯度法 FR共轭梯度法是最常见的共轭梯度算法之一。其β参数计算方式为: \[ \beta_k^{FR} = \frac{\|g_{k+1}\|^2}{\|g_k\|^2} \] 该方法具有全局收敛性质,在强Wolfe线搜索条件下能够保证对于一般非凸函数的有效性[^1]。 ```python def beta_FR(g_new, g_old): return np.linalg.norm(g_new)**2 / np.linalg.norm(g_old)**2 ``` #### PRP共轭梯度法 PRP共轭梯度法则通过引入当前迭代点处梯度变化量来改进搜索方向的选择策略,具体表达式如下所示: \[ \beta_k^{PRP} = \frac{g_{k+1}^T (g_{k+1}-g_k)}{\|g_k\|^2} \] 此版本通常表现出更好的数值性能,并且当目标函数接近二次型时效果更佳[^2]。 ```python def beta_PRP(g_new, g_old): numerator = np.dot(g_new.T, (g_new - g_old)) denominator = np.linalg.norm(g_old)**2 return numerator / denominator ``` #### DY共轭梯度法 DY共轭梯度法定义了另一种形式的β系数更新规则,旨在克服某些情况下可能出现的方向退化现象: \[ \beta_k^{DY} = \frac{\|g_{k+1}\|^2}{y_k^Td_k}, y_k=g_{k+1}-g_k \] 这种方法可以有效防止步长过小而导致的效率低下问题[^3]。 ```python def beta_DY(g_new, g_old, d): y = g_new - g_old numerator = np.linalg.norm(g_new)**2 denominator = np.dot(y.T, d) return numerator / denominator ``` #### HS共轭梯度法 HS共轭梯度法采用了一种混合式的β值设定方案,综合考虑了前后两次梯度差以及前一步搜索方向的影响因素: \[ \beta_k^{HS} = \frac{(g_{k+1}-g_k)^Td_k}{d_k^Ty_k} \] 这种组合使得HS算法能够在多种情形下保持良好的鲁棒性快速收敛特性[^4]。 ```python def beta_HS(g_new, g_old, d): y = g_new - g_old numerator = np.dot((g_new - g_old).T, d) denominator = np.dot(d.T, y) return numerator / denominator ``` #### DM共轭梯度法 DM共轭梯度法则是基于矩阵理论构建的一种新型变体,特别适用于处理大规模稀疏线性方程组求解等问题情境下的优化需求。它利用预条件技术改善原有CG方法中的不足之处,从而提高了整体运算速度与稳定性[^5]。 ```python def beta_DM(g_new, g_old, M): # 假设M是预条件矩阵 z = solve(M, g_new) # 解决线性系统Mz = g_new得到z w = solve(M, g_old) # 同样解决Mw = g_old获得w return np.dot(z.T, g_new) / np.dot(w.T, g_old) ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值