0%

最速下降法(二)

使用 Jupyter Notebook

Python 实现 最速下降法 求解无约束非线性规划问题

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
import random
import numpy as np
import matplotlib.pyplot as plt
import math

def mo_length(x):
"""
求二维向量模长
x: [1.5, 2.7]
"""
result = (x[0]**2 + x[1]**2)**0.5 # **0.5开平方根
return result

# f(x) = x_1^2 + 25 * x_2^2

# 梯度g = (2x_1, 50x_2)
# 初始点
x_0 = [2, 2]
# 固定步长
step = 0.01

# 路径点列表
x = []

# 迭代
x_1 = x_0[0]
x_2 = x_0[1]

# f(x) = x_1^2 + 25 * x_2^2
f = x_1**2 + x_2**2 * 25
# 画出函数的20条轮廓线
#plt.contour(x_1, x_2, f, 20)

# 容许误差: 当梯度方向=0.00001时退出迭代
allow_e = 0.01
# 迭代次数
k = 0
while True:
# 此时梯度
g = [2 * x_1, 50 * x_2]
# 终止条件
if mo_length(g) < allow_e:
break
# 此时下降搜索方向
# d(k) = g * x(k-1) g为梯度
d = [-g[0], -g[1]]
x_1 += step * d[0]
x_2 += step * d[1]
k = k + 1
# 记录下来路径点
x.append([x_1, x_2])


i = 0
for x_1,x_2 in x:
i += 1
#print("%s, %s" % (x_1, x_2))
min = x_1**2 + 25*(x_2**2)
print("最小值: %s" % min)
print("共迭代: %s 次" % k)

# 画出迭代点收敛的轨迹
# 2行i+1列矩阵 (全0) +1 : 加上初始点
# 第一行 x_1 列表 # 第二行 x_2 列表
list = np.zeros((2, i+1))
i = 1
# 初始点 (2,2)
list[0, 0] = 2
list[1, 0] = 2
for x_1,x_2 in x:
list[0, i] = x_1
list[1, i] = x_2
i += 1

plt.plot(list[0], list[1], 'g*-')
plt.show()

1
2
3
4
5
6
7
8
9
10
11
X1 = np.arange(-1.5, 2.5 + 0.05, 0.05)
X2 = np.arange(-3.5, 2.5 + 0.05, 0.05)
[x1, x2] = np.meshgrid(X1, X2)

f = 2*x1**2+x2**2
plt.contour(x1, x2, f, 20) # 画出函数的20条轮廓线

# 画出迭代点收敛的轨迹
plt.plot(list[0], list[1], 'g*-')

plt.show()