简介
前面介绍的一维搜索算法都是精确搜索,实际计算中一般没有必要做到精确的一维搜索。相比于精确的一维搜索方法,不精确的一维搜素方法收敛的更快,并且计算压力更小。不精确一维搜索基本思想即
m
i
n
φ
(
λ
)
=
f
(
x
(
k
)
+
λ
s
(
k
)
)
min \varphi(\lambda)=f(\bm{x}^{(k)}+\lambda \bm{s}^{(k)})
minφ(λ)=f(x(k)+λs(k)),要求
f
(
x
(
k
+
1
)
)
f(\bm{x}^{(k+1)})
f(x(k+1))比
f
(
x
(
k
)
)
f(\bm{x}^{(k)})
f(x(k))下降一定的数量,同时在新点
x
(
k
+
1
)
=
x
(
k
)
+
λ
k
s
(
k
)
\bm{x}^{(k+1)}=\bm{x}^{(k)}+\lambda_k\bm{s}^{(k)}
x(k+1)=x(k)+λks(k)处沿方向
s
(
k
)
\bm{s}^{(k)}
s(k)的方向导数值比在
x
(
k
)
\bm{x}^{(k)}
x(k)点沿
s
(
k
)
\bm{s}^{(k)}
s(k)方向的方向导数值大一定的数量,采用
−
▽
f
(
x
(
k
)
)
T
s
(
k
)
>
0
-\bigtriangledown f(\bm{x}^{(k)})^{T}\bm{s}^{(k)}>0
−▽f(x(k))Ts(k)>0来度量。
常用的不精确搜索准则为Wolfe-Powell准则,对于给定的常数
c
1
,
c
2
,
0
<
c
1
<
c
2
<
1
c_1,c_2,0<c_1<c_2<1
c1,c2,0<c1<c2<1,要求满足如下两个条件:
- f ( x ( k ) ) − f ( x ( k + 1 ) ) ⩾ − c 1 λ k ▽ f ( x ( k ) ) T s ( k ) f(\bm{x}^{(k)})-f(\bm{x}^{(k+1)})\geqslant-c_1\lambda_k\bigtriangledown f(\bm{x}^{(k)})^{T}\bm{s}^{(k)} f(x(k))−f(x(k+1))⩾−c1λk▽f(x(k))Ts(k)
- ▽ f ( x ( k + 1 ) ) T s ( k ) ⩾ c 2 ▽ f ( x ( k ) ) T s ( k ) \bigtriangledown f(\bm{x}^{(k+1)})^{T}\bm{s}^{(k)}\geqslant c_2\bigtriangledown f(\bm{x}^{(k)})^{T}\bm{s}^{(k)} ▽f(x(k+1))Ts(k)⩾c2▽f(x(k))Ts(k)
假设 f ( x ) f(x) f(x)的一阶导数函数为 g ( x ) g(x) g(x),则不精确搜索算法直接法的计算步骤如下:
- 给定 c 1 ∈ ( 0 , 1 ) , c 2 ∈ ( c 1 , 1 ) c_1\in(0, 1), c_2\in(c_1, 1) c1∈(0,1),c2∈(c1,1),令 a = 0 , b = + ∞ a=0, b=+\infty a=0,b=+∞, λ = 1 \lambda=1 λ=1, i = 0 i=0 i=0;
- 令 x ( k + 1 ) = x ( k ) + λ k s ( k ) \bm{x}^{(k+1)}=\bm{x}^{(k)}+\lambda_k\bm{s}^{(k)} x(k+1)=x(k)+λks(k),计算 f ( x k + 1 ) f(\bm{x}^{k+1}) f(xk+1)和 g ( x k + 1 ) g(\bm{x}^{k+1}) g(xk+1),若 λ \lambda λ满足条件1和2,则计算结束,令 λ k = λ \lambda_k=\lambda λk=λ;否则令 i = i + 1 i=i+1 i=i+1,若 λ \lambda λ不满足条件1,则转到步骤3;若 λ \lambda λ满足条件1,不满足条件2,则步骤4;
- 令 b = λ , λ = ( λ + a ) / 2 b=\lambda, \lambda=(\lambda+a)/2 b=λ,λ=(λ+a)/2,返回步骤2;
- 令 a = λ , λ = m i n ( 2 λ , ( λ + b ) / 2 ) a=\lambda, \lambda=min({2\lambda, (\lambda+b)/2}) a=λ,λ=min(2λ,(λ+b)/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的极小值点。由于这是一个一维问题,需要明白的是我们搜索方向是沿着x轴正向还是负向即设置 s s s为正还是为负,设置 c 1 = 0.1 , c 2 = 0.7 , a = 0 , b = + ∞ , λ = 1 , x 0 = 10.5 , s = − 1 c_1=0.1, c_2=0.7, a=0, b=+\infty, \lambda=1, x_0=10.5, s=-1 c1=0.1,c2=0.7,a=0,b=+∞,λ=1,x0=10.5,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_direct_method(c1, c2, a, b, lam, x, s):
"""
采用直接法进行不精确搜索
:param x: 初始点列向量
:param s: 方向向量,列向量
:param c1: 给定常数
:param c2: 给定常数
:param a: 区间左端点
:param b: 区间右端点
:param lam: 步长
"""
i = 0
while True:
f_x = cal_fun_f(x)
d_x = derivative_cal_f1(x)
x_ = x+lam*s # 下一个迭代点
f_x_ = cal_fun_f(x_)
d_x_ = derivative_cal_f1(x_)
rule1_judge = wolfe_powell_rule1(f_x, f_x_, c1, lam, d_x, s)
rule2_judge = wolfe_powell_rule2(d_x_, s, c2, d_x)
if rule1_judge and rule2_judge:
return x_, lam
else:
i += 1
if not rule1_judge:
b = lam
lam = (lam+a)/2
if rule1_judge and rule2_judge == False:
a = lam
lam = min(2*lam, (lam+b)/2)
def main_loop(c1, c2, a, b, lam, x, s, gap):
"""
将不精确搜索得到的迭代点和搜索步长进行循环,求解极小值
:param x: 初始点列向量
:param s: 方向向量,列向量
:param c1: 给定常数
:param c2: 给定常数
:param a: 区间左端点
:param b: 区间右端点
:param lam: 步长
"""
i = 0
while True:
x, lam = imprecise_direct_method(c1, c2, a, b, lam, x, s)
i += 1
print(f"第{i}次迭代极小值点,迭代步长", x, lam)
if abs(derivative_cal_f1(x)) < gap:
break
if __name__ == "__main__":
main_loop(0.1, 0.7, 0, float('inf'),
1, 10.5, -1, 1e-3)
输出结果如下:
第1次迭代极小值点,迭代步长 8.5 2
第2次迭代极小值点,迭代步长 6.5 2
第3次迭代极小值点,迭代步长 4.5 2
第4次迭代极小值点,迭代步长 4.0 0.5
可以看到收敛速度还是比较快的,但是有个问题是, c 1 , c 2 c_1,c_2 c1,c2的取值对收敛效果影响较大,很可能不收敛于极小值点。