无约束优化问题就是没有任何的约束限制的优化问题, 如求最小值 min f ( x ) \min \ f(x) min f(x), 其中 f : R n → R f: \mathbb{R}^{n} \rightarrow \mathbb{R} f:Rn→R. 求解无约束优化问题的迭代算法有最速下降 (SD) 法和 Newton 法等.
f ( x ) = 0 ⇔ 等价变换 x = φ ( x ) ( 迭代函数 ) f (x) = 0 \xLeftrightarrow{\text{等价变换}} x=\varphi(x) \ (\text { 迭代函数 }) f(x)=0等价变换 x=φ(x) ( 迭代函数 )
f ( x ) 的零点 x ∗ ⟺ φ ( x ) 的不动点 x ∗ f(x) \text { 的零点 } x^{*} \Longleftrightarrow \varphi(x) \text { 的不动点 } x^{*} f(x) 的零点 x∗⟺φ(x) 的不动点 x∗
不动点迭代: x k + 1 = φ ( x k ) x_{k+1}=\varphi\left(x_{k}\right) xk+1=φ(xk)
从一个给定的初值 x 0 x_{0} x0 出发, 计算 x 1 = φ ( x 0 ) , x 2 = φ ( x 1 ) , … , x_{1}=\varphi\left(x_{0}\right), x_{2}=\varphi\left(x_{1}\right), \ldots, x1=φ(x0),x2=φ(x1),…, 若 { x k } k = 0 ∞ \left\{x_{k}\right\}_{k=0}^{\infty} {xk}k=0∞ 收玫, 即存在 x ∗ x^{*} x∗ 使得 lim k → ∞ x k = x ∗ \lim_{k \rightarrow \infty} x_{k}=x^{*} limk→∞xk=x∗, 则由 φ \varphi φ 的连续性和 lim k → ∞ x k + 1 = lim k → ∞ φ ( x k ) \lim_{k \rightarrow \infty} x_{k+1}=\lim_{k \rightarrow \infty} \varphi\left(x_{k}\right) limk→∞xk+1=limk→∞φ(xk) 可得 x ∗ = φ ( x ∗ ) x^{*}=\varphi\left(x^{*}\right) x∗=φ(x∗), 即 x ∗ x^{*} x∗ 是 φ \varphi φ 的不 动点, 也就是 f ( x ) f(x) f(x) 的零点。
求曲线 y = φ ( x ) y=\varphi(x) y=φ(x) 与直线 y = x y=x y=x 的交点
定理 (不动点原理, 压缩映像定理) 设 φ ( x ) \varphi(x) φ(x) 在 [ a , b ] [a, b] [a,b] 上连续, 且一阶导数连续, 若:
(1) a ≤ φ ( x ) ≤ b a \leq \varphi(x) \leq b a≤φ(x)≤b 对 一切 x ∈ [ a , b ] x \in[a, b] x∈[a,b] 都成立; (封闭性)
(2) 存在 0 ≤ L < 1 0 \leq L<1 0≤L<1, 使得 ∣ φ ′ ( x ) ∣ ≤ L \left|\varphi^{\prime}(x)\right| \leq L ∣φ′(x)∣≤L 对 ∀ x ∈ [ a , b ] \forall x \in[a, b] ∀x∈[a,b] 成立, (压缩性)
则函数 f ( x ) = x − φ ( x ) f(x)=x-\varphi(x) f(x)=x−φ(x) 在 [ a , b ] [a, b] [a,b] 中有唯一的零点 x ∗ x^{*} x∗, 即 φ ( x ) \varphi(x) φ(x) 存在唯一的的不动点 x ∗ x^{*} x∗, s.t. φ ( x ∗ ) = x ∗ \varphi\left(x^{*}\right)=x^{*} φ(x∗)=x∗.
证明思路 : 存在性: f ( a ) = a − φ ( a ) ≤ 0 , f ( b ) = b − φ ( b ) ≥ 0 f(a)=a-\varphi(a) \leq 0, \ f(b)=b-\varphi(b) \geq 0 f(a)=a−φ(a)≤0, f(b)=b−φ(b)≥0 ⟹ \Longrightarrow ⟹ f ( x ) f(x) f(x) 在 [ a , b ] [a, b] [a,b] 上有零点.
唯一性: 用反证法, 假设存在 x ∗ , y ∗ ∈ [ a , b ] x^{*}, y^{*} \in[a, b] x∗,y∗∈[a,b] 使得
{ x ∗ = φ ( x ∗ ) y ∗ = φ ( y ∗ ) \left\{\begin{array}{l}x^{*}=\varphi\left(x^{*}\right) \\ y^{*}=\varphi\left(y^{*}\right)\end{array}\right. {x∗=φ(x∗)y∗=φ(y∗)
⟹ \Longrightarrow ⟹ ∣ x ∗ − y ∗ ∣ = ∣ φ ( x ∗ ) − φ ( y ∗ ) ∣ = ∣ φ ′ ( ξ ) ∣ ⋅ ∣ x ∗ − y ∗ ∣ ≤ L ∣ x ∗ − y ∗ ∣ \left|\boldsymbol{x}^{*}-\boldsymbol{y}^{*}\right|=\left|\varphi\left(\boldsymbol{x}^{*}\right)-\varphi\left(\boldsymbol{y}^{*}\right)\right|=\left|\varphi^{\prime}(\xi)\right| \cdot\left|\boldsymbol{x}^{*}-\boldsymbol{y}^{*}\right| \leq {L}\left|\boldsymbol{x} *-\boldsymbol{y}^{*}\right| ∣x∗−y∗∣=∣φ(x∗)−φ(y∗)∣=∣φ′(ξ)∣⋅∣x∗−y∗∣≤L∣x∗−y∗∣, 推出矛盾.
无约束优化问题就是没有任何的约束限制的优化问题, 如求最小值 min f ( x ) \min \ f(x) min f(x), 其中 f : R n → R f: \mathbb{R}^{n} \rightarrow \mathbb{R} f:Rn→R.
∇ f ( x ) = [ ∂ f ( x ) ∂ x 1 ∂ f ( x ) ∂ x 2 ⋯ ∂ f ( x ) ∂ x n ] T = g ( x ) \nabla f(x)=\left[\begin{array}{llll} \frac{\partial f(x)}{\partial x_{1}} & \frac{\partial f(x)}{\partial x_{2}} & \cdots & \frac{\partial f(x)}{\partial x_{n}} \end{array}\right]^{\mathrm{T}}=g(x) ∇f(x)=[∂x1∂f(x)∂x2∂f(x)⋯∂xn∂f(x)]T=g(x)
∇ 2 f ( x ) = [ ∂ 2 f ( x ) ∂ x 1 2 ∂ 2 f ( x ) ∂ x 1 ∂ x 2 ⋯ ∂ 2 f ( x ) ∂ x 1 ∂ x n ∂ 2 f ( x ) ∂ x 2 ∂ x 1 ∂ 2 f ( x ) ∂ x 2 2 ⋯ ∂ 2 f ( x ) ∂ x 2 ∂ x n ⋮ ⋮ ⋮ ∂ 2 f ( x ) ∂ x n ∂ x 1 ∂ 2 f ( x ) ∂ x n ∂ x 2 ⋯ ∂ 2 f ( x ) ∂ x n 2 ] = G ( x ) \nabla^{2} f(x)=\left[\begin{matrix} \frac{\partial^{2} f(x)}{\partial x_{1}^{2}} & \frac{\partial^{2} f(x)}{\partial x_{1} \partial x_{2}} & \cdots & \frac{\partial^{2} f(x)}{\partial x_{1} \partial x_{n}} \\ \frac{\partial^{2} f(x)}{\partial x_{2} \partial x_{1}} & \frac{\partial^{2} f(x)}{\partial x_{2}^{2}} & \cdots & \frac{\partial^{2} f(x)}{\partial x_{2} \partial x_{n}} \\ \vdots & \vdots & & \vdots \\ \frac{\partial^{2} f(x)}{\partial x_{n} \partial x_{1}} & \frac{\partial^{2} f(x)}{\partial x_{n} \partial x_{2}} & \cdots & \frac{\partial^{2} f(x)}{\partial x_{n}^{2}} \end{matrix}\right]=G(x) ∇2f(x)=⎣⎢⎢⎢⎢⎢⎡∂x12∂2f(x)∂x2∂x1∂2f(x)⋮∂xn∂x1∂2f(x)∂x1∂x2∂2f(x)∂x22∂2f(x)⋮∂xn∂x2∂2f(x)⋯⋯⋯∂x1∂xn∂2f(x)∂x2∂xn∂2f(x)⋮∂xn2∂2f(x)⎦⎥⎥⎥⎥⎥⎤=G(x)
步 1: 给出 x 0 ∈ R n , ε > 0 , k : = 0 x_{0} \in \mathbb{R}^{n}, \varepsilon>0, k:=0 x0∈Rn,ε>0,k:=0;
步 2: 若满足终止条件 ∥ ∇ f ( x k ) ∥ ≤ ε \left\|\nabla f\left(x_{k}\right)\right\| \leq \varepsilon ∥∇f(xk)∥≤ε, 则迭代停止;
步 3: 计算 d k = − g k d_{k}=-g_{k} dk=−gk ;
步 4: 一维精确线搜索求 α k \alpha_{k} αk;
步 5: x k + 1 : = x k + α k d k , k : = k + 1 x_{k+1}:=x_{k}+\alpha_{k} d_{k}, k:=k+1 xk+1:=xk+αkdk,k:=k+1, 转步 2.
其中一维精确线搜索确定最优步长的方法如下
min α > 0 f ( x k − α g k ) \min _{\alpha>0} f\left(x_{k}-\alpha g_{k}\right) α>0minf(xk−αgk)
其中
f ( x k − α g k ) = 1 2 ( x k − α g k ) T G ( x k − α g k ) + b T ( x k − α g k ) = 1 2 g k T G g k α 2 − g k T g k α + f ( x k ) \begin{aligned} f\left(x_{k}-\alpha g_{k}\right) &=\frac{1}{2}\left(x_{k}-\alpha g_{k}\right)^{\mathrm{T}} G\left(x_{k}-\alpha g_{k}\right)+b^{\mathrm{T}}\left(x_{k}-\alpha g_{k}\right) \\ &=\frac{1}{2} g_{k}^{\mathrm{T}} G g_{k} \alpha^{2}-g_{k}^{\mathrm{T}} g_{k} \alpha+f\left(x_{k}\right) \end{aligned} f(xk−αgk)=21(xk−αgk)TG(xk−αgk)+bT(xk−αgk)=21gkTGgkα2−gkTgkα+f(xk)
得最速下降方法的步长
α k = g k T g k g k T G g k \alpha_{k}=\frac{g_{k}^{\mathrm{T}} g_{k}}{g_{k}^{\mathrm{T}} G g_{k}} αk=gkTGgkgkTgk
#最速下降法 (负梯度方法)
import numpy as np #导入numpy模块
import matplotlib.pyplot as plt #导入matplotlib.pyplot模块
from sympy import*
from scipy.interpolate import griddata
import numpy.linalg as LA
#目标函数
def nf(x1,x2):
y=1/2*(21*x1*x1+4*x2*x1+4*x1*x2+15*x2*x2)+2*x1+3*x2+10
return y
#目标函数求梯度
def ndfx(x1,x2):
fx=np.array([diff(nf(x1,x2),x1),diff(nf(x1,x2),x2)])
#分别就目标函数对x1,x2一阶偏导, array数组
# sympy.diff(func,x,n) 求导
# func是要求导的函数; x是要对其求导的变量; n是求导阶数, 缺省为1(可选)
return fx
#初始化参数
n=100 #设置最大迭代次数
x=np.zeros((n,2)) #迭代点xk
x[0,:]=[-30,100]
xk=[]
xk.append(x[0,:])
d=np.zeros((n,2)) #下降方向dk
df=np.zeros((n,2)) #梯度, 建立array数组的形式
#--------------------------------------
def main():
x1,x2=var('x1 x2') # sympy.var 将字符串变成变量
eps=1e-5 #精度要求
k=1
#设置初始迭代点:
A=np.arange(4*n).reshape(n,2,2)
fx=ndfx(x1,x2)#梯度
alpha=0.1
for i in range(n-2):
#二阶导数矩阵
#计算一阶导数值
f1x=fx[0].subs({x1:x[i][0],x2:x[i][1]})#截取xk
f2x=fx[1].subs({x1:x[i][0],x2:x[i][1]})
df[i,:]=[f1x,f2x]
b=-df[i,:].T#负梯度方向
#subs函数只能应用于sympy类型的符号函数,并非array数组类型
A[i,:,:]=[[21,4],[4,15]]#SD方法
alpha=(b*b)/(21*b[0]*b[0]+4*b[1]*b[0]+4*b[0]*b[1]+15*b[1]*b[1])#步长公式
d[i,:]=alpha*b#负梯度方向
x[i+1,:]=x[i,:]+d[i,:]
xk.append(x[i+1,:])#存储迭代点
if np.abs(x[i+1][0]-x[i][0])<eps and np.abs(x[i+1][1]-x[i][1])<eps :
break
i=i+1
print(nf(x[i][0],x[i][1]))
print('-----------------------------------')
print('最后迭代 The result is:',i)
print('最优解:x*=',x[i,:])
print('最优目标值:y=%.3f'%( nf(x[i][0],x[i][1]) ) )
#--------------------------------------
main()
plt.rc('font',size=16);plt.rc('font',family='SimHei');plt.rc('text',usetex=True)
xh0=np.arange(-100,100.1,0.1)#区域横坐标
yh0=np.arange(-100,100.1,0.1)#区域纵坐标
xh,yh=np.meshgrid(xh0,yh0)
contr=plt.contour(xh,yh,nf(xh,yh),20)
plt.clabel(contr)#等高线
plt.xlabel('$x_1$');plt.ylabel('$x_2$',rotation=90)
xk=np.reshape(xk,(1,-1))
xk=np.reshape(xk,(int(xk.size/2),2))
xtk=np.array(xk.T[0,:])
ytk=np.array(xk.T[1,:])
#print(xtk)
#print(ytk)
plt.plot(xtk,ytk,c='r',marker='H')
plt.show()
步 1: 给出 x 0 ∈ R n , ε > 0 , k : = 0 x_{0} \in \mathbb{R}^{n}, \varepsilon>0, k:=0 x0∈Rn,ε>0,k:=0;
步 2: 若满足终止准则 ∥ ∇ f ( x k ) ∥ ≤ ε \left\|\nabla f\left(x_{k}\right)\right\| \leq \varepsilon ∥∇f(xk)∥≤ε, 则输出有关信息, 停止迭代;
步 3: 由 G k d = − g k G_{k} d=-g_{k} Gkd=−gk ⇒ \Rightarrow ⇒ d k = − G k − 1 g k d_{k}=-G_{k}^{-1} g_{k} dk=−Gk−1gk;
步 4: x k + 1 : = x k + d k , k : = k + 1 x_{k+1}:=x_{k}+d_{k}, k:=k+1 xk+1:=xk+dk,k:=k+1, 转步 2.
# Newton 法
import numpy as np #导入numpy模块
import matplotlib.pyplot as plt #导入matplotlib.pyplot模块
from sympy import*
from scipy.interpolate import griddata
import numpy.linalg as LA
#目标函数
def nf(x1,x2):
y=3*x1**2+3*x2**2-x1**2*x2
#y=1/2*(21*x1*x1+4*x2*x1+4*x1*x2+15*x2*x2)+2*x1+3*x2+10
return y
#目标函数求梯度 (一阶偏导)
def ndfx(x1,x2):
fx=np.zeros(2)#二维向量
fx=[diff(nf(x1,x2),x1),diff(nf(x1,x2),x2)]#分别就目标函数对x1,x2一阶偏导,列表类型
fx=np.array(fx)#转换为array数组类型
return fx
#目标函数求 Hesse 矩阵 (二阶偏导)
def ndfxx(x1,x2):
fx=ndfx(x1,x2)#梯度
fxx=[[],[]]
fxx[0]=[diff(fx[0],x1),diff(fx[0],x2)]
fxx[1]=[diff(fx[1],x1),diff(fx[1],x2)]
fxx=np.array(fxx) #转换为数组类型
return fxx
#初始化参数
n=100 #设置最大迭代次数
x=np.zeros((n,2))#迭代点xk
x[0,:]=[-2,4]#设置初始迭代点
d=np.zeros((n,2))#下降方向dk
df=np.zeros((n,2))#梯度,建立array数组的形式
A=np.arange(4*n).reshape(n,2,2)#建立array数组的形式
xk=[]
xk.append(x[0,:])
#--------------------------------------
def main():
x1,x2=var('x1 x2') #转化为sympy变量
eps=1e-6 #精度要求
fx=ndfx(x1,x2)#梯度
z1=ndfxx(x1,x2)#hesse矩阵
for i in range(n-2):
#计算一阶导数值
f1x=fx[0].subs({x1:x[i][0],x2:x[i][1]})#梯度在xk点值
f2x=fx[1].subs({x1:x[i][0],x2:x[i][1]})
df[i,:]=[f1x,f2x]
#subs函数只能应用于sympy类型的符号函数, 并非array数组类型
#为二阶导数矩阵每个元素循环赋值
z2=np.arange(4).reshape(2,2)#建立array数组的形式
for j in range(2):
for k in range(2):
z2[j][k]=z1[j][k].subs({x1:x[i][0],x2:x[i][1]})#Hesse矩阵不同分量取值
#A[i,:,:]=z1 #Gk Hesse矩阵在xk点处值
#----------------------------------
#d[i,:]=-np.dot(LA.inv(A[i,:,:]),df[i,:]) #G*d=-g
d[i,:]=-np.dot(LA.inv(z2[:,:]),df[i,:]) #G*d=-g 改成z2形式之后Newton有二阶速度
#基本newton
alpha=1.0 #全步长=1
x[i+1,:]=x[i,:]+alpha*d[i,:]
xk.append(x[i+1,:])
if LA.norm(df[i,:])<eps :
break
i=i+1
print('-----------------------------------')
print('最后迭代 The result is:',i)
print('最优解:x*=',x[i,:])
print('最优目标值:y=%.3f'%( nf(x[i][0],x[i][1]) ) )
#--------------------------------------
if __name__ == '__main__':
main()
plt.rc('font',size=16);plt.rc('font',family='SimHei');plt.rc('text',usetex=True)
xh0=np.arange(-6,6.01,0.01)#区域横坐标
yh0=np.arange(-6,6.01,0.01)#区域纵坐标
xh,yh=np.meshgrid(xh0,yh0)
contr=plt.contour(xh,yh,nf(xh,yh),20)
plt.clabel(contr)#等高线
plt.xlabel('$x1$')#x,y坐标轴
plt.ylabel('$x2$',rotation=90)
xk=np.reshape(xk,(1,-1))
xk=np.reshape(xk,(int(xk.size/2),2))
xtk=np.array(xk.T[0,:])
ytk=np.array(xk.T[1,:])
#print(xtk)
#print(ytk)
plt.plot(xtk,ytk,c='r',marker='H')
plt.show()