最優化作業第6章 無約束多維非線性規劃方法

2021-10-05 17:05:14 字數 3582 閱讀 6112

**:

#匯入模組

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時,需要給出要走的 方向 只有 方向 確定好之後,...