DFP算法是一种拟牛顿算法,它的好处是在于 继承了牛顿法的快速,又克服了牛顿法中每次求取G的逆矩阵的困难,且保证了Hk的正定,也就克服了牛顿法的G可能正定的缺点。
from 实用优化算法.helper import* # 单独博客介绍
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
x1,x2 = symbols('x1,x2')
f = 100 * (x2 - x1 ** 2) ** 2 + (1 - x1) ** 2
def do_work(x0,h):
k = 1
step_x1 = [x0[0][0]]
step_x2 = [x0[1][0]]
while get_len_grad(get_grad(x0,f)) > 0.00001:
d = -1 * np.dot(h, get_grad(x0,f))
step = golden_search(0, 2, x0, d, f)
x1 = x0 + step * d
s = x1 - x0
y = get_grad(x1,f) - get_grad(x0,f)
t1 = np.dot(h,y)
t2 = np.dot(t1,y.T)
t3 = np.dot(t2,h) # 分子
t4 = np.dot(y.T,h)
t5 = np.dot(t4,y) # 分母
t6 = np.dot(s,s.T) # 分子
t7 = np.dot(y.T, s) # 分母
h = h - t3*(1/t5[0][0]) + (1/t7[0][0]) * t6
x0 = x1
step_x1.append(x0[0][0])
step_x2.append(x0[1][0])
print(k,' ',x0)
k += 1
print('\n结束',x0)
return step_x1,step_x2
if __name__ == '__main__':
x0 = [[0],[0]]
x0 = np.array(x0)
h = [[1,0],[0,1]]
h = np.array(h)
step_x1,step_x2 = do_work(x0,h)
fig = plt.figure()
ax = Axes3D(fig)
x = np.arange(-0.1, 1.5, 0.1)
y = np.arange(-1, 2.1, 0.1)
X1, X2 = np.meshgrid(x, y)
plt.figure(figsize=(10, 6))
Z = 100 * (X2 - X1 ** 2) ** 2 + (1 - X1) ** 2
step_x1 = np.array(step_x1)
step_x2 = np.array(step_x2)
step_x3 = 100 * (step_x2 - step_x1 ** 2) ** 2 + (1 - step_x1) ** 2
bar = plt.contourf(X1, X2, Z, 45, cmap=plt.cm.Blues)
plt.plot(step_x1, step_x2, marker='*')
ax.plot_surface(X1, X2, Z, rstride=1, cstride=1)
ax.plot(step_x1, step_x2, step_x3, c='r',marker = '*')
plt.colorbar(bar)
plt.show()