场景:已知f(x1,x2)=-x1^2-3*x2^2+2*x1*x2+6,求当f(x1,x2)取得最大值时,x1和x2的值分别是多少?
f(x1,x2)对x1的偏导:f_x1=-2*x1+2*x2,令f_x1=0,=》x1=x2;
f(x1,x2)对x2的偏导:f_x2=-6*x2+2*x1,令f_x2=0,=》x2=1/3*x1。
在坐标上升的过程中,当每次沿着某个坐标轴寻找多元函数f的最大值时,该坐标轴对应的变量被更新为偏导为0时对应的值,其余坐标轴对应的变量保持不变。
绘制函数f(x1,x2)=-x1^2-3*x2^2+2*x1*x2+6的图像:
# 导入相关包
%matplotlib notebook
from matplotlib import pyplot as plt
import numpy as np
# 绘制函数图像
fig = plt.figure()
ax = plt.axes(projection='3d')
X1 = np.arange(-4, 4, 0.25)
X2 = np.arange(-4, 4, 0.25)
X1, X2 = np.meshgrid(X1, X2)
Z = -X1**2-3*X2**2+2*X1*X2+6
ax.plot_surface(X, Y, Z, rstride=1, cstride=1, cmap='rainbow')
ax.set(xlabel='x',ylabel='y',zlabel='z')
函数图像如下图所示:
采用坐标上升法求解f(x1,x2)取得最大值时,x1和x2的值:
plt.figure()
CS=plt.contour(X,Y,Z)#画等高线
#初始化X1和X2的值
X1_list = []
X2_list = []
X1_list.append(2.0)
X2_list.append(2.0)
j = 1
for i in range(200):
X1_tmp = X2_list[j-1] # 沿着X1轴对X1和X2进行更新
X1_list.append(X1_tmp)
X2_list.append(X2_list[j-1])
j = j+1
X2_tmp = X1_list[j-1] / 3 # 沿着X2轴对X1和X2进行更新
X1_list.append(X1_list[j-1])
X2_list.append(X2_tmp)
plt.plot(X1_list,X2_list)
max_x1=X1_list[-1]
max_x2=X2_list[-1]
print('当取最大值的时候,x1的取值为:', max_x1)
print('当取最大值的时候,x2的取值为:', max_x2)
print('max f:',-(max_x1**2)-3*(max_x2**2)+2*max_x1*max_x2+6)
plt.title('Coordinate Descent')
plt.xlabel('x')
plt.ylabel('y')
迭代过程如图下所示:
上图黄色椭圆曲线中的蓝色阶梯状折线展示了坐标上升的迭代过程。
除此之外,上述代码还输出:
当取最大值的时候,x1的取值为: 0.6666666666666666
当取最大值的时候,x2的取值为: 0.2222222222222222
max f: 5.703703703703704
参考: