最优化作业第6章——无约束多维非线性规划方法
代码:
#导入模块
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({x1: a, x2: b})
dif_x22 = dif_x2.subs({x1: a, x2: b}) # 将目标函数的初始解代入到偏导函数中得到具体的偏导函数值
print("------------------------------第<%s>次迭代------------------------------" % k)
print("目标函数解为:%s,目标函数值为:%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({x1:x_solver[0,0],x2:x_solver[1,0]})
dif_x22 = dif_x2.subs({x1:x_solver[0,0],x2:x_solver[1,0]})#将目标函数的初始解代入到偏导函数中得到具体的偏导函数值
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: 149/2650}
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({x1:a,x2:b})
dif_x22 = dif_x2.subs({x1:a,x2:b})#将目标函数的初始解代入到偏导函数中得到具体的偏导函数值
f_diff_solver = (dif_x11 ** 2 + dif_x22 ** 2) ** 0.5#得到梯度向量的模长
print("------------------------------第<%s>次迭代------------------------------" % k)
print("目标函数解为:<%s>,目标函数值为:<%s>,梯度向量长度:<%s>\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>次迭代------------------------------
目标函数解为:<[[-66/53]
[564/265]]>,目标函数值为:<24.452830188679243>,梯度向量长度:<19.898988777347018>
------------------------------第<2>次迭代------------------------------
目标函数解为:<[[0.143840177580469]
[0.143840177580462]]>,目标函数值为:<0.3517299436684602>,梯度向量长度:<3.5115862548259504>
------------------------------第<3>次迭代------------------------------
目标函数解为:<[[-0.0179121730571876]
[0.0306135321341049]]>,目标函数值为:<0.0050592897557630336>,梯度向量长度:<0.28622740794050416>
------------------------------第<4>次迭代------------------------------
目标函数解为:<[[0.00206899966863705]
[0.00206899966863635]]>,目标函数值为:<7.277291368992362e-05>,梯度向量长度:<0.050510719048299235>
------------------------------第<5>次迭代------------------------------
目标函数解为:<[[-0.000257649015339521]
[0.000440345589853036]]>,目标函数值为:<1.046766882819546e-06>,梯度向量长度:<0.004117100118651557>
进程已结束,退出代码0