**:
#匯入模組
from sympy import *
import sympy as sp #將匯入的模組重新定義乙個名字以便後續的程式進行使用
from numpy import *
import numpy as np
#定義主要的處理函式
def main():
#x1,x2:目標函式變數;alpha:步長因子;f:目標函式;a,b:目標函式不同變數的解;dif_x1,dif_x2:目標函式偏導函式
#x_solver:目標函式變數解組成的矩陣;x_fun:包含alpha的迭代解函式組成的矩陣
# dif_x11,dif_x22:目標函式偏導函式;f_x_diff:目標函式偏導函式值組成的矩陣;
# f_alpha_diff:對alpha求偏導得到的函式;alpha_solver:α的解;k:迭代的次數
#x_solver_k1:作為第k+1次迭代的解;x_solver_k:作為第k次迭代的解
k = 0
x1,x2,alpha = symbols("x1,x2,alpha",real = true)#將變數符號化,否則會出錯
f = 8*x1**2 + 4*x1*x2 + 5*x2**2 #定義目標函式
a = 10
b=10 #定義目標函式的初始解的兩維解
f_solver = 8*a**2 + 4*a*b + 5*b**2#得到給定初始解下的目標函式值
dif_x1 = sp.diff(f,x1)
dif_x2 = sp.diff(f,x2) #目標函式對不同變數進行求偏導,得到偏導函式
dif_x11 = dif_x1.subs()
dif_x22 = dif_x2.subs() # 將目標函式的初始解代入到偏導函式中得到具體的偏導函式值
print("------------------------------第次迭代------------------------------" % k)
print("目標函式解為:%s,目標函式值為:%s,梯度向量長度:\n"
% ( [[a],[b]], f_solver,(dif_x11**2 + dif_x22**2)**0.5))
while true:
k = k + 1
x_solver = np.array([[a],
[b]]) #將目標函式的初始解定義為2行1列的陣列
x_solver = np.mat(x_solver)#將陣列轉化為矩陣
dif_x11 = dif_x1.subs()
dif_x22 = dif_x2.subs()#將目標函式的初始解代入到偏導函式中得到具體的偏導函式值
f_x_diff = np.array([[dif_x11],
[dif_x22]])#將偏導函式值定義為陣列
f_x_diff = np.mat(f_x_diff)#將陣列轉化為矩陣
x_fun = x_solver - alpha*f_x_diff#迭代公式得到新的解
f = 8*x_fun[0,0]**2 + 4*x_fun[0,0]*x_fun[1,0] + 5*x_fun[1,0]**2 #將新得到的解帶入到目標函式得到只包含alpha的一元函式
f_alpha_diff = sp.diff(f,alpha) #對函式進行求導
alpha_dict = solve([f_alpha_diff],[alpha]) #由於極值點處的導數為0,因此求解其方程得到alpha,返回的是乙個字典
alpha_solver = alpha_dict[alpha]#取值操作
x_solver_k1 = x_solver - alpha_solver * f_x_diff#通過迭代得到下一步的解矩陣
a = float(x_solver_k1[0,0])
b = float(x_solver_k1[1,0])#取得解矩陣的解
f_solver = 8*a**2 + 4*a*b + 5*b**2
x_solver_k = x_solver_k1 # 將上一次解保留下來,作為終止條件的判斷
dif_x11 = dif_x1.subs()
dif_x22 = dif_x2.subs()#將目標函式的初始解代入到偏導函式中得到具體的偏導函式值
f_diff_solver = (dif_x11 ** 2 + dif_x22 ** 2) ** 0.5#得到梯度向量的模長
print("------------------------------第次迭代------------------------------" % k)
print("目標函式解為:,目標函式值為:,梯度向量長度:\n"
%(x_solver_k1,float(f_solver),float(f_diff_solver)))
if f_diff_solver < 0.01:#判斷是否滿足迭代終止條件
break
if __name__ == '__main__':
main()
結果:
------------------------------第<0>次迭代------------------------------
目標函式解為:[[10], [10]],目標函式值為:1700,梯度向量長度:<244.131112314674>
------------------------------第<1>次迭代------------------------------
目標函式解為:
[564/265]]>,目標函式值為:<24.452830188679243>,梯度向量長度:<19.898988777347018>
------------------------------第<2>次迭代------------------------------
目標函式解為:
[0.143840177580462]]>,目標函式值為:<0.3517299436684602>,梯度向量長度:<3.5115862548259504>
------------------------------第<3>次迭代------------------------------
目標函式解為:
[0.0306135321341049]]>,目標函式值為:<0.0050592897557630336>,梯度向量長度:<0.28622740794050416>
------------------------------第<4>次迭代------------------------------
目標函式解為:
[0.00206899966863635]]>,目標函式值為:<7.277291368992362e-05>,梯度向量長度:<0.050510719048299235>
------------------------------第<5>次迭代------------------------------
目標函式解為:
[0.000440345589853036]]>,目標函式值為:<1.046766882819546e-06>,梯度向量長度:<0.004117100118651557>
程序已結束,退出**0
無約束最優化二
2.1 a k合理性討論 如下將要討論關於a k需要滿足的兩個條件,當a k滿足這兩個條件後,就可以認為從x k點移動到x k 1點的步長已經確定下來了。第乙個條件為sufficient decrease condition,從直觀角度來看,該條件主要要用保證x k 1點的函式值要小於x k點的函式...
無約束最優化三
2.2 a k步長的選擇 了解了a k的合理性之後,就相當於獲得了標尺,在此基礎上我們可以選擇合適的策略來求取a k。所有的line search過程在計算每一步的a k時,均需要提供乙個初始點a 0,然後再此基礎上生成一系列的,直到a i滿足2.1節所規定的條件為止,此時該a k即被確定為a i,...
無約束最優化四
3 quasi newton method 在第2節中我們了解了步長的概念,以及從x k走到x k 1點使用line search方法計算步長的方法。不過我們在那裡忽略了乙個重要的概念,即 方向 從第2節,我們了解到從每一點x k走到下一點x k 1時,需要給出要走的 方向 只有 方向 確定好之後,...