全CSDN最拉跨的最速下降法,懒得写注释,自己看,复杂度爆炸
import numpy as np
import sympy as sympy
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
def f(x):
return 3*x[0]**2/2 + x[1]**2/2 - x[0]*x[1] -2*x[0]
def grad(x,f):
gd = np.zeros(x.shape)
m = np.zeros(x.shape)
epsilon = 1e-9
# print(f(x[0],x[1]))
# gd[0] = (f(x[0]+epsilon,x[1]) - f(x[0],x[1]))/epsilon
# gd[1] = (f(x[0] , x[1]+ epsilon) - f(x[0], x[1])) / epsilon
for i in range(0,len(x)):
m = x.copy()
m[i] = m[i]+epsilon
gd[i] = (f(m) - f(x))/epsilon
return np.around(gd,10)
x = np.asarray([-2.0,4.0])
h = np.zeros((100,2))
sv = np.zeros((100,))
h1 = []
h2 = []
sv1 = []
h[0] = x
sv[0] = f(h[0])
i = 0
h1.append(list(h[0])[0])
h2.append(list(h[0])[1])
while True:
try:
i += 1
alpha = sympy.Symbol("alpha")
gd = grad(h[i-1],f)
solve = sympy.solve( 3*(h[i-1][0] - alpha*gd[0])**2/2 + (h[i-1][1] - alpha*gd[1])**2/2 - (h[i-1][0] - alpha*gd[0])*(h[i-1][1] - alpha*gd[1]) -2*(h[i-1][0] - alpha*gd[0]), alpha)
solve = round((solve[0]+solve[1])/2,10)
h[i] = h[i-1] - solve*grad(h[i-1],f)
sv[i] = f(h[i])
h1.append(list(h[i])[0])
h2.append(list(h[i])[1])
sv1.append(sv[i])
print("第%d次迭代得到的坐标为"%i,h[i])
print("第%d次迭代得到的最小值为"%i,sv[i])
except:
break
plt.rcParams['font.sans-serif'] = ['Microsoft YaHei']
plt.plot(h1,h2,'*--r')
plt.title('迭代过程坐标')
plt.show()