共軛方向法、共軛梯度法


(FR)共軛梯度法是介於最速下降法和牛頓法之間的一個方法,相比最速下降法收斂速度快,並且不需要像牛頓法一樣計算Hesse矩陣,只需計算一階導數

 

共軛梯度法是共軛方向法的一種,意思是搜索方向都互相共軛

共軛的定義如下:

 

 

共軛梯度法是一種典型的共軛方向法,它的搜索方向是負梯度方向和上一次搜索方向的一個組合

關於βk-1,有兩種常用的計算公式

(PRP公式)

(PRP公式)

 

預處理共軛法改善了G的條件數,使算法的收斂速度加快

預處理的方法是尋找一個非奇異矩陣C,使得C-TGC-1的條件數小於G的條件數

 

再開始共軛梯度法是滿足某一條件后重新使用最速下降方向作為搜索方向,這個條件包括迭代n步,或共軛梯度方向是上升方向

 

下面給出這幾種方法的python實現

FR共軛梯度法:

# coding=utf-8
# FR-CG共軛梯度法
from linear_search.Function import *
from linear_search.wolfe import *
import numpy as np


def conjugate(_f, _x):
    fun = Function(_f)
    x = array(_x)
    d = -fun.grad(x)
    while fun.norm(x) > 0.01:
        alpha = wolfe(_f, x, d)
        g = np.mat(fun.grad(x))
        beta = 1 / np.dot(g, g.T)
        x = x + alpha * d
        g = np.mat(fun.grad(x))
        beta = beta * np.dot(g, g.T)
        d = array(-g + beta * d)[0]
    return x

 再開始共軛梯度法:

# coding=utf-8
# 再開始共軛梯度法
from linear_search.Function import *
from linear_search.wolfe import *
import numpy as np


def restart_conjugate(_f, _x, n):
    fun = Function(_f)
    x = array(_x)
    while True:
        d = -fun.grad(x)
        k=0
        if(np.linalg.norm(d)<0.01):
            break
        while fun.norm(x) > 0.01:
            g = np.mat(fun.grad(x))

            alpha = wolfe(_f, x, d)
            x = x + alpha * d
            k=k+1

            g1= np.mat(fun.grad(x))

            if np.dot(g1,g.T)/np.dot(g1,g1.T)>0.1 or k>=n:
                if np.linalg.norm(g1)<0.01:
                    return x
                break
            else:
                beta = np.dot(g1, g1.T) / np.dot(g, g.T)
                d = array(-g + beta * d)[0]
                if np.dot(mat(d),g1.T)>0:
                    break
    return x

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM