目录

  • 迭代法求零点
  • 基本思想
  • 具体做法
  • 几何含义
  • 重要定理
  • 迭代法求解无约束优化问题
  • 1. 最速下降 (SD) 法 (负梯度方法)
  • 梯度和 Hesse 矩阵
  • SD 法
  • 一维精确线搜索
  • Python 实现
  • 2. Newton 法


无约束优化问题就是没有任何的约束限制的优化问题, 如求最小值 pytorch如何求解非线性优化 python非线性约束优化_概率论, 其中 pytorch如何求解非线性优化 python非线性约束优化_数据分析_02. 求解无约束优化问题的迭代算法有最速下降 (SD) 法和 Newton 法等.

迭代法求零点

基本思想

pytorch如何求解非线性优化 python非线性约束优化_数据分析_03

pytorch如何求解非线性优化 python非线性约束优化_python_04

不动点迭代: pytorch如何求解非线性优化 python非线性约束优化_数据分析_05

具体做法

从一个给定的初值 pytorch如何求解非线性优化 python非线性约束优化_pytorch如何求解非线性优化_06 出发, 计算 pytorch如何求解非线性优化 python非线性约束优化_概率论_07pytorch如何求解非线性优化 python非线性约束优化_python_08 收玫, 即存在 pytorch如何求解非线性优化 python非线性约束优化_概率论_09 使得 pytorch如何求解非线性优化 python非线性约束优化_pytorch如何求解非线性优化_10, 则由 pytorch如何求解非线性优化 python非线性约束优化_概率论_11 的连续性和 pytorch如何求解非线性优化 python非线性约束优化_算法_12 可得 pytorch如何求解非线性优化 python非线性约束优化_算法_13, 即 pytorch如何求解非线性优化 python非线性约束优化_概率论_09pytorch如何求解非线性优化 python非线性约束优化_概率论_11 的不 动点, 也就是 pytorch如何求解非线性优化 python非线性约束优化_算法_16

几何含义

求曲线 pytorch如何求解非线性优化 python非线性约束优化_pytorch如何求解非线性优化_17 与直线 pytorch如何求解非线性优化 python非线性约束优化_算法_18

重要定理

定理 (不动点原理, 压缩映像定理) 设 pytorch如何求解非线性优化 python非线性约束优化_算法_19pytorch如何求解非线性优化 python非线性约束优化_概率论_20 上连续, 且一阶导数连续, 若:
(1) pytorch如何求解非线性优化 python非线性约束优化_数据分析_21 对 一切 pytorch如何求解非线性优化 python非线性约束优化_概率论_22 都成立; (封闭性)
(2) 存在 pytorch如何求解非线性优化 python非线性约束优化_概率论_23, 使得 pytorch如何求解非线性优化 python非线性约束优化_pytorch如何求解非线性优化_24pytorch如何求解非线性优化 python非线性约束优化_python_25 成立, (压缩性)
则函数 pytorch如何求解非线性优化 python非线性约束优化_算法_26pytorch如何求解非线性优化 python非线性约束优化_概率论_20 中有唯一的零点 pytorch如何求解非线性优化 python非线性约束优化_概率论_09, 即 pytorch如何求解非线性优化 python非线性约束优化_算法_19 存在唯一的的不动点 pytorch如何求解非线性优化 python非线性约束优化_概率论_09, s.t. pytorch如何求解非线性优化 python非线性约束优化_数据分析_31.

证明思路 : 存在性: pytorch如何求解非线性优化 python非线性约束优化_python_32 pytorch如何求解非线性优化 python非线性约束优化_python_33 pytorch如何求解非线性优化 python非线性约束优化_算法_16pytorch如何求解非线性优化 python非线性约束优化_概率论_20 上有零点.
唯一性: 用反证法, 假设存在 pytorch如何求解非线性优化 python非线性约束优化_python_36

pytorch如何求解非线性优化 python非线性约束优化_python_37

pytorch如何求解非线性优化 python非线性约束优化_python_33 pytorch如何求解非线性优化 python非线性约束优化_数据分析_39, 推出矛盾.

迭代法求解无约束优化问题

无约束优化问题就是没有任何的约束限制的优化问题, 如求最小值 pytorch如何求解非线性优化 python非线性约束优化_概率论, 其中 pytorch如何求解非线性优化 python非线性约束优化_数据分析_02.

1. 最速下降 (SD) 法 (负梯度方法)

梯度和 Hesse 矩阵

pytorch如何求解非线性优化 python非线性约束优化_数据分析_42

pytorch如何求解非线性优化 python非线性约束优化_概率论_43

SD 法

步 1: 给出 pytorch如何求解非线性优化 python非线性约束优化_数据分析_44;
步 2: 若满足终止条件 pytorch如何求解非线性优化 python非线性约束优化_数据分析_45, 则迭代停止;
步 3: 计算 pytorch如何求解非线性优化 python非线性约束优化_pytorch如何求解非线性优化_46 ;
步 4: 一维精确线搜索求 pytorch如何求解非线性优化 python非线性约束优化_算法_47;
步 5: pytorch如何求解非线性优化 python非线性约束优化_pytorch如何求解非线性优化_48, 转步 2.

其中一维精确线搜索确定最优步长的方法如下

一维精确线搜索

pytorch如何求解非线性优化 python非线性约束优化_python_49

其中
pytorch如何求解非线性优化 python非线性约束优化_算法_50

得最速下降方法的步长
pytorch如何求解非线性优化 python非线性约束优化_python_51

Python 实现
#最速下降法 (负梯度方法)
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()

2. Newton 法

步 1: 给出 pytorch如何求解非线性优化 python非线性约束优化_数据分析_44;
步 2: 若满足终止准则 pytorch如何求解非线性优化 python非线性约束优化_数据分析_45, 则输出有关信息, 停止迭代;
步 3: 由 pytorch如何求解非线性优化 python非线性约束优化_pytorch如何求解非线性优化_54 pytorch如何求解非线性优化 python非线性约束优化_数据分析_55 pytorch如何求解非线性优化 python非线性约束优化_python_56;
步 4: pytorch如何求解非线性优化 python非线性约束优化_数据分析_57, 转步 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()