简介
上次介绍了不精确一维搜索的概念和准则,以及采用直接法进行不精确一维搜索的实例,本次介绍采用二次插值法来进行不精确一维搜索的方法。
φ
(
λ
)
=
f
(
x
k
+
λ
s
k
)
\varphi(\lambda)=f(\bm{x}^{k}+\lambda\bm{s}^{k})
φ(λ)=f(xk+λsk),若已知点
(
λ
1
,
φ
1
)
,
(
λ
2
,
φ
2
)
,
(\lambda_1, \varphi_1),(\lambda_2,\varphi_2),
(λ1,φ1),(λ2,φ2),,则可由抛物线法进行一维搜索那节的内容可知,可采用抛物线方程
g
(
λ
)
=
a
λ
2
+
b
λ
+
c
g(\lambda)=a\lambda^{2}+b\lambda+c
g(λ)=aλ2+bλ+c来近似曲线,可推导得到近似极小点的计算公式如下:
λ
^
=
λ
1
+
1
2
(
λ
2
−
λ
2
)
/
[
1
+
φ
1
−
φ
2
(
λ
2
−
λ
2
)
φ
1
′
]
\hat{\lambda}=\lambda_1+\frac{1}{2}(\lambda_2-\lambda_2)/\lbrack1+\frac{\varphi_1-\varphi_2}{(\lambda_2-\lambda_2)\varphi_1^{'}}\rbrack
λ^=λ1+21(λ2−λ2)/[1+(λ2−λ2)φ1′φ1−φ2]
具体实施步骤如下:
- 给定 c 1 ∈ ( 0 , 1 ) , c 2 ∈ ( c 1 , 1 ) , T > 0 c_1\in(0, 1), c_2\in(c_1, 1), T>0 c1∈(0,1),c2∈(c1,1),T>0,令 λ 1 = 0 , λ 2 = 1 , λ 3 = + ∞ , i = 0 \lambda_1=0, \lambda_2=1, \lambda_3=+\infty, i=0 λ1=0,λ2=1,λ3=+∞,i=0;
- 若 λ 2 \lambda_2 λ2满足条件1、2(具体条件见不精确一维搜索),则令 λ k = λ 2 \lambda_k=\lambda_2 λk=λ2,计算终止;否则转步骤3;
- 计算 φ 1 , φ 2 , φ 1 ′ = ▽ f ( x k + λ 1 s k ) T s k \varphi_1, \varphi_2, \varphi_1^{'}=\bigtriangledown f(\bm{x}^{k}+\lambda_1\bm{s}^{k})^T\bm{s}^{k} φ1,φ2,φ1′=▽f(xk+λ1sk)Tsk和 λ ^ \hat{\lambda} λ^,令 i = i + 1 i=i+1 i=i+1;
- 若 λ 1 < λ ^ < λ 2 \lambda_1<\hat{\lambda}<\lambda_2 λ1<λ^<λ2,则令 λ 3 = λ 2 \lambda_3=\lambda_2 λ3=λ2, λ 2 = λ ^ \lambda_2=\hat{\lambda} λ2=λ^,返回步骤2;若 λ 2 ⩽ λ ^ < λ 3 \lambda_2\leqslant\hat{\lambda}<\lambda_3 λ2⩽λ^<λ3,则令 λ 1 = λ 2 , λ 2 = λ ^ \lambda_1=\lambda_2,\lambda_2=\hat{\lambda} λ1=λ2,λ2=λ^,返回步骤2;否则返回步骤5;
- 若 λ ^ ⩽ λ 1 \hat{\lambda}\leqslant\lambda_1 λ^⩽λ1,则令 λ ^ = λ 1 + T △ λ \hat{\lambda}=\lambda_1+T\triangle\lambda λ^=λ1+T△λ;若 λ ^ ⩾ λ 3 \hat{\lambda}\geqslant\lambda_3 λ^⩾λ3,则令 λ ^ = λ 3 − T △ λ , △ λ = λ 3 − λ 1 \hat{\lambda}=\lambda_3-T\triangle\lambda,\triangle\lambda=\lambda_3-\lambda_1 λ^=λ3−T△λ,△λ=λ3−λ1,令 λ 2 = λ ^ \lambda_2=\hat{\lambda} λ2=λ^,返回步骤2。
优化问题
求 f ( x ) = x 4 − 4 x 3 − 6 x 2 − 16 x + 4 f(x)=x^{4}-4x^{3}-6x^{2}-16x+4 f(x)=x4−4x3−6x2−16x+4的极小值点。设置参数 c 1 = 0.5 , c 2 = 0.7 , T = 0.1 , λ 1 = 0 , λ 2 = 1 , λ 3 = + ∞ , x = 11 , s = − 1 c_1=0.5, c_2=0.7, T=0.1, \lambda_1=0, \lambda_2=1, \lambda_3=+\infty,x=11,s=-1 c1=0.5,c2=0.7,T=0.1,λ1=0,λ2=1,λ3=+∞,x=11,s=−1,计算程序如下:
def cal_fun_f(x):
"""
函数值计算函数
"""
return x**4-4*x**3-6*x**2-16*x+4
def derivative_cal_f1(x):
"""
一阶导数计算函数
"""
return 4*x**3-12*x**2-12*x-16
def derivative_cal_f2(x):
"""
二阶导数计算函数
"""
return 12*x**2-24*x-12
def wolfe_powell_rule1(f_x, f_x_, c1, lam, d_x, s):
"""
判断准则1
:param f_x:k点函数值
:param f_x_:k+1点函数值
:param c1:给定常数
:param lam:步长
:param d_x:k点一阶导数
:param s:方向向量
:return:
"""
if (f_x-f_x_) >= (-c1*lam*d_x*s):
return True
else:
return False
def wolfe_powell_rule2(d_x_, s, c2, d_x):
"""
判断准则2
:param d_x_: k+1点一阶导数
:param s: k点方向导数
:param c2: 给定常数
:param d_x: k点一阶导数
"""
if (d_x_*s) >= (c2*d_x*s):
return True
else:
return False
def imprecise_parabolic_method(c1, c2, T, lam1, lam2, lam3, x, s):
"""
采用二次插值法进行不精确一维搜索
:param T: 大于0
:param c1:给定常数
:param c2:给定常数
:param lam1:步长区间左端点
:param lam2:步长
:param lam3:步长区间右端点
:param x:初始点
:param s:方向向量
"""
i = 0
while True:
temp_x = x
x2 = x+lam2*s
f_x = cal_fun_f(x)
f_x2 = cal_fun_f(x2)
d_x = derivative_cal_f1(x)
d_x2 = derivative_cal_f1(x2)
rule1_judge = wolfe_powell_rule1(f_x, f_x2, c1, lam2, d_x, s)
rule2_judge = wolfe_powell_rule2(d_x2, s, c2, d_x)
# print(f"第{i}迭代点,步长", x2, lam2)
if rule1_judge and rule2_judge:
return x2, lam2
else:
x1 = x + lam1 * s
f_x1 = cal_fun_f(x1)
d_x1 = derivative_cal_f1(x1)
d_lam1 = d_x1*s
lam = lam1 + 0.5*(lam2 - lam1)/(1 + (f_x1 - f_x2) / ((lam2 - lam1) * d_lam1))
i += 1
if lam < 0:
return x, lam
elif lam1 < lam < lam2:
lam3 = lam2
lam2 = lam
elif lam2 <= lam < lam3:
lam1 = lam2
lam2 = lam
elif lam <= lam1:
delta_lam = lam3-lam1
lam = lam1+T*delta_lam
lam2 = lam
else:
delta_lam = lam3 - lam1
lam = lam3-T*delta_lam
lam2 = lam
def main_loop(c1, c2, T, lam1, lam2, lam3, x, s, gap):
i = 0
while True:
x, lam = imprecise_parabolic_method(c1, c2, T, lam1, lam2, lam3, x, s)
i += 1
print(f"第{i}次迭代极小值点,迭代步长", x, lam)
if abs(derivative_cal_f1(x)) < gap or lam<0:
break
if __name__ == "__main__":
main_loop(0.5, 0.7, 0.1, 0, 1, float("inf"), 11, -1, 1e-3)
计算结果如下:
第1次迭代极小值点,迭代步长 7.608378870673952 3.3916211293260483
第2次迭代极小值点,迭代步长 6.608378870673952 1
第3次迭代极小值点,迭代步长 5.608378870673952 1
第4次迭代极小值点,迭代步长 4.608378870673952 1
第5次迭代极小值点,迭代步长 4.048639983992185 0.559738886681767
第6次迭代极小值点,迭代步长 4.000335997451437 0.04830398654074813
第7次迭代极小值点,迭代步长 4.00000001612566 0.0003359813257768087
但是这个计算结果并不稳定,更改初始点和参数之后,收敛结果改变的比较明显,读者自行甄别。