目录
本文开始,我们介绍利用目标函数解析性质求解无约束化问题的解析法。
算法分析:
基本思想:从任意一点出发,沿该点负梯度方向进行一维搜索,设,令为的新的近似最优解,再从新点出发,沿该点负梯度方向进行一维搜索,进一步求出新的近似最优解,如此迭代,直到某点的梯度为零向量或梯度的范数小于事先给定的精度为止。
算法步骤:
步骤1:选定某一初始点,,并令k=1;
步骤2:计算,若,则转步骤4;否则进行精确一维搜索确定最佳步长,求出
步骤3:令,转步骤2
步骤4:停止,输出
例题分析:
例题:利用最速下降法求解,取
解:函数的梯度为:
第一次迭代:
,,
令
第二次迭代:
,,
令
经过17迭代,在精度为时,得到近似最优解:
特征分析:
1,相邻两次迭代的搜索方向互相正交。
- 最速下降法在两个相邻点之间的搜索方向是正交的
- 最速下降法向极小点逼近是曲折前进的,这种现象被称之为锯齿现象
- 除特殊的目标函数和极特殊的初始点外,锯齿现象都会发生
2,对二元正定二次函数,用最速下降法产生的点列:偶数点列均在一条直线上,奇数点列均在一条直线上,且都过最优点。
收敛性分析:
设 : 具有一阶连续偏导数, ,记 ,假设水平集 有界,令 {} 是由最速下降法产生的点列,则:
(1)当 {} 是有穷点列时,其中最后一个点是 的驻点;
(2)当 {} 是无穷点列时,它必有极限点,并且任一极限点都是 的驻点。
补充:
设 ,其中 是 n 维实对称正定矩阵,,,如果用最速下降法求解 的最小值时,则一维搜索的步长必为 。
证明:
,,
正交
代码解释:
'''
最速下降法
2023.10.18
'''
from sympy import symbols, diff, solve, init_printing
import numpy as np
init_printing()
x1 = symbols("x1")
x2 = symbols("x2")
λ = symbols("λ")
f = x1**2 + 2*x2**2 - 2*x1*x2 - 4*x1
def gradient_descent(x1_init, x2_init, ε):
grad_1 = diff(f, x1)
grad_2 = diff(f, x2)
x1_curr = x1_init
x2_curr = x2_init
count = -1
while True:
count = count +1
grad_1_value = grad_1.subs({x1: x1_curr, x2: x2_curr})
grad_2_value = grad_2.subs({x1: x1_curr, x2: x2_curr})
d1 = -grad_1_value
d2 = -grad_2_value
k = np.array([d1,d2],dtype=float)
norm_result = np.linalg.norm(k,ord=2,axis=0)
x1_new = x1_curr + λ * d1
x2_new = x2_curr + λ * d2
f_new = f.subs({x1: x1_new, x2: x2_new})
grad_3 = diff(f_new, λ)
λ_value = solve(grad_3, λ)[0]
print("第{}次迭代".format(count),"λ的值为{}".format(λ_value))
x1_curr = x1_new.subs(λ, λ_value)
x2_curr = x2_new.subs(λ, λ_value)
print("当前x的值为[%f, %f]" % (float(x1_curr), float(x2_curr)))
if norm_result < ε:
print("该精度下的最优解是[%f, %f]" % (float(x1_curr), float(x2_curr)))
break
return x1_curr, x2_curr
result = gradient_descent(x1_init=1, x2_init=1, ε=0.01)
该代码的运行结果:
第0次迭代 λ的值为1/4
当前x的值为[2.000000, 0.500000]
第1次迭代 λ的值为1/2
当前x的值为[2.500000, 1.500000]
第2次迭代 λ的值为1/4
当前x的值为[3.000000, 1.250000]
第3次迭代 λ的值为1/2
当前x的值为[3.250000, 1.750000]
第4次迭代 λ的值为1/4
当前x的值为[3.500000, 1.625000]
第5次迭代 λ的值为1/2
当前x的值为[3.625000, 1.875000]
第6次迭代 λ的值为1/4
当前x的值为[3.750000, 1.812500]
第7次迭代 λ的值为1/2
当前x的值为[3.812500, 1.937500]
第8次迭代 λ的值为1/4
当前x的值为[3.875000, 1.906250]
第9次迭代 λ的值为1/2
当前x的值为[3.906250, 1.968750]
第10次迭代 λ的值为1/4
当前x的值为[3.937500, 1.953125]
第11次迭代 λ的值为1/2
当前x的值为[3.953125, 1.984375]
第12次迭代 λ的值为1/4
当前x的值为[3.968750, 1.976562]
第13次迭代 λ的值为1/2
当前x的值为[3.976562, 1.992188]
第14次迭代 λ的值为1/4
当前x的值为[3.984375, 1.988281]
第15次迭代 λ的值为1/2
当前x的值为[3.988281, 1.996094]
第16次迭代 λ的值为1/4
当前x的值为[3.992188, 1.994141]
第17次迭代 λ的值为1/2
当前x的值为[3.994141, 1.998047]
该精度下的最优解是[3.994141, 1.998047]
总结:
最速下降法算法非常简单,对初始点要求不高,并且通常对凸解析函数也有良好的收敛性。最速下降法采用负梯度方向进行一维搜索,总体上来看搜索速度是比较快的,但是当迭代到靠近最优点时,会由于锯齿现象而导致偏差,大大降低搜索效率。经过研究,我们发现可以有以下三种方法对最速下降法进行改进:
- 选择不同的初始点
- 采用不精确的一维搜索
- 采用加速梯度法,由特征2可以确定
(行文中若有纰漏,希望大家指正)