采用精确线搜索的BFGS算法求解下面的无约束优化问题,minf(x)=(1/2)x1**2+x2**2-x1*x2-2*x1,取初始点[1,1],B0=I为单位矩阵
时间: 2023-10-05 12:08:45 浏览: 157
回溯直线搜索求解无约束优化问题1
首先,我们需要求出f(x)的梯度向量和Hessian矩阵:
grad_f(x) = [x1*x2 - x2 - 2, x1*x2 - x1]
Hessian_f(x) = [[x2**2 + 1, x1*x2 - 1], [x1*x2 - 1, x1**2 + 1]]
初始点为x0=[1,1],B0=I,因此,我们可以得到:
H0 = B0**(-1) = I
s0 = -grad_f(x0) = [-1, -1]
d0 = H0*s0 = [-1, -1]
我们可以使用精确线搜索来确定步长。具体地,我们需要求解下列一元二次方程:
phi(alpha) = f(x0 + alpha*d0)
其中,
f(x) = (1/2)x1**2 x2**2-x1*x2-2*x1
x0 = [1, 1]
d0 = [-1, -1]
可以将phi(alpha)展开为:
phi(alpha) = (1/2)*(x1 + alpha*d1)**2*(x2 + alpha*d2)**2 - (x1 + alpha*d1)*(x2 + alpha*d2) - 2*(x1 + alpha*d1)
其中,
d1 = -1
d2 = -1
现在,我们可以将phi(alpha)展开并化简,得到一个关于alpha的一元二次方程:
phi(alpha) = (1/2)*(alpha**2 + 2*alpha + 1)*(x2**2 + 2*x2*d2*alpha + d2**2)*(x1**2 + 2*x1*d1*alpha + d1**2) - (x1 + alpha*d1)*(x2 + alpha*d2) - 2*(x1 + alpha*d1)
phi(alpha) = (1/2)*(alpha**2 + 2*alpha + 1)*(x2**2 + 2*x2*d2*alpha + d2**2)*(x1**2 + 2*x1*d1*alpha + d1**2) - x1*x2 - (d1+d2)*alpha*(x1+x2) - 2*x1 - 2*alpha*d1
phi(alpha) = (1/2)*(x2**2*d1**2 + 2*x2*d1*d2*x1 + x1**2*d2**2)*(alpha**2 + 2*alpha + 1) - (x1*x2 + (d1+d2)*alpha*(x1+x2) + 2*x1 + 2*alpha*d1)
现在,我们可以使用标准的一元二次方程求解公式,得到phi(alpha)的最小值:
alpha_star = -g/(2*h)
其中,
g = (d1+d2)*x1*x2 + 2*(d1+x1)*d1
h = (d1+d2)*x1**2 + 2*d1**2
我们可以使用alpha_star来更新x0和B0:
x1 = x0 + alpha_star*d0
s1 = -grad_f(x1)
y1 = s1 - s0
rho1 = 1/(y1.dot(d0))
I = np.identity(2)
B1 = (I - rho1*np.outer(d0, y1)).dot(B0).dot(I - rho1*np.outer(y1, d0)) + rho1*np.outer(d0, d0)
现在,我们可以将x1作为新的x0,将B1作为新的B0,继续进行迭代,直到满足收敛条件为止。完整的代码如下所示:
import numpy as np
def f(x):
return 0.5*x[0]**2*x[1]**2 - x[0]*x[1] - 2*x[0]
def grad_f(x):
return np.array([x[0]*x[1] - x[1] - 2, x[0]*x[1] - x[0]])
def hessian_f(x):
return np.array([[x[1]**2 + 1, x[0]*x[1] - 1], [x[0]*x[1] - 1, x[0]**2 + 1]])
x0 = np.array([1, 1])
B0 = np.identity(2)
for i in range(20):
s0 = -grad_f(x0)
d0 = np.linalg.solve(B0, s0)
phi = lambda alpha: f(x0 + alpha*d0)
g = (d0[0] + d0[1])*x0[0]*x0[1] + 2*(d0[0] + x0[0])*d0[0]
h = (d0[0] + d0[1])*x0[0]**2 + 2*d0[0]**2
alpha_star = -g/(2*h)
x1 = x0 + alpha_star*d0
s1 = -grad_f(x1)
y1 = s1 - s0
rho1 = 1/(y1.dot(d0))
I = np.identity(2)
B1 = (I - rho1*np.outer(d0, y1)).dot(B0).dot(I - rho1*np.outer(y1, d0)) + rho1*np.outer(d0, d0)
if np.linalg.norm(x1 - x0) < 1e-6:
break
x0 = x1
B0 = B1
print("Minimum of f(x):", f(x0))
print("Optimal x:", x0)
阅读全文