最優化之共軛梯度法

共軛梯度法是利用目標函數的梯度逐步產生共軛方向並將其作爲搜索方向的方法。

1. 共軛方向與共軛方向法

定義:設H是n*n方陣且對稱正定

(1)若對n維非零向量p和q,有p^THq = 0,則稱p和q是H-共軛的;

(2)若對n維非零向量組d1,...,dm,對任意的i != j,di與dj是H-共軛的,則稱d1,...,dm是H-共軛方程組。


當H = I,p^Tq = 0,即p與q相互正交,可見共軛是正交的推廣。


定理:設H是n*n方陣且對稱正定。若n維非零向量組d1,...,dm是H-共軛方程組,則d1,...,dm也是線性無關方程組。


將一組共軛方向作爲搜索方向對無約束非線性規劃問題(UNP)進行求解的方法稱爲共軛方向法。


2. 無約束凸二次規劃問題的共軛梯度法

min f(x) = 1/2 * x^T * H * x + c^T * x + b

其中矩陣H是n*n方陣,且對稱正定,f(x)是嚴格凸函數。顯然,▽f(x) = Hx + c,▽^2f(x) = H,並且x是UQP的最優解條件是▽f(x) = 0。

若用一組共軛方向作爲搜索方向求解UQP,那麼最多迭代n次即可得到其最優解,因此共軛方向法具有二次終止性。

算法如下:

①選定初始數據。給定初始點x,令k = 1。

②最優性判別。若▽f(x) = 0,停止,得到最優解x。否則轉3。

③構造搜索方向。當k = 1時令d(1) = - ▽f(x),當k>1時令d(k) = -g(k) + β*d(k-1),其中β = ||g(k)||^2 / ||g(k-1)||^2確定。

g(k) = ▽f(x_k)。

④確定新的迭代點。令λ = - g(k)^T * d(k) / d(k)^T * H * d(k),x = x + λ*d(k)。若k = n,停止,得最優解爲x;否則k = k +1,轉2。


求解代碼如下:

'''
1/2 x^ * H * x + c^ * x + b
'''
import numpy as np

def algo(H, c, b, x0):
    x = x0
    k = 1
    d, d_pre = None, None
    g, g_pre = None, None
    beta = None
    while(True):
        g = np.dot(H, x) + c
        norm = np.linalg.norm(g)
        if(norm == 0):
            break
        if(k == 1):
            d = -g
        else:
            beta = (float) (np.linalg.norm(g)**2 / np.linalg.norm(g_pre)**2)
            d = -g + beta * d_pre
        lambda_ = -np.sum(float(g.transpose().dot(d)) / (d.transpose().dot(H).dot(d)))
        x = x + lambda_ * d
        print 'k = %s;g = %s;norm = %s;beta = %s;lambda = %s' %(str(k), str(g), str(norm), str(beta), str(lambda_))
        if(k == H.shape[0]):
            break
        else:
            k += 1
            d_pre = d
            g_pre = g
    return x



發佈了57 篇原創文章 · 獲贊 0 · 訪問量 4萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章