精确线搜索花费的计算量一般较大。一般问题中,特别是初始迭代点具体目标点较远时,不精确线搜索的效率往往要高于精确线搜索。并且牛顿法和拟牛顿法的收敛速度不依赖于步长的搜索,因此可以对α进行不精确线搜索。
不精确线搜索包括Goldstein准则、Wofle准则和Armijo准则。
1. GoldStein准则
其中0<ρ<1/2,第一个不等式是充分下降条件,第二个不等式表示αk不会太小.
也可以写成
2. Wolfe准则
Goldstein准则的第二个不等式可能造成把极小点排除在可接受区间外,为了解决这个问题,提出了下面的代替条件
σ∈(ρ,1)
即
这个条件叫做曲率条件
充分下降条件与曲率条件一起构成了Wolfe准则
其中
但曲率条件的不足之处是即使σ→0时也不能精确线搜索,因此有了强Wolfe准则
3. Armijo准则
给定β∈(0,1),ρ∈(0,1/2),τ>0,mk是使不等式
成立的最小非负整数,令
上面的不等式实际上就是充分下降条件,这个方法可以令α从1开始缩小(增大m),直到满足充分下降条件
下面给出这几种算法的python实现
Goldstein准则:
1 from linear_search.Function import * 2 from numpy import * 3 4 5 def goldstein(f, val, d): 6 a = 0 7 b = 10000 8 alpha = 1 9 10 def _fi(_alpha): 11 return f(val + _alpha * array(d)) 12 13 fi = Function(_fi) 14 fi0 = fi.value(0) 15 dfi0 = fi.diff(0) 16 while True: 17 fi_alpha = fi.value(alpha) 18 if fi_alpha > fi0 + 1 / 3 * alpha * dfi0: 19 b = alpha 20 alpha = (a + b) / 2 21 elif fi_alpha < fi0 + 2 / 3 * alpha * dfi0: 22 a = alpha 23 if b == 10000: 24 alpha = 2 * alpha 25 else: 26 alpha = (a + b) / 2. 27 else: 28 return alpha
Wolfe准则:
1 from linear_search.Function import * 2 from numpy import * 3 4 5 def wolfe(_f, val, d): 6 a = 0.0 7 b = 10000.0 8 9 def _fi(_alpha): 10 return _f(val + _alpha * array(d)) 11 12 fi = Function(_fi) 13 f = Function(_f) 14 15 fi1 = f.value(val) 16 g=f.grad(val) 17 print(f.part(0,[1,2])) 18 print(f.part(1,[1,2])) 19 dfi1 = dot(g,array(d).T) 20 dfi0 = fi.diff(0) 21 alpha = 1.0 22 23 while True: 24 fi_=fi.value(alpha) 25 if fi_-fi1>1/3*alpha*dfi1: 26 alpha_=a+(alpha-a)/2/(1+(fi1-fi_)/(alpha-a)/dfi1) 27 b=alpha 28 alpha=alpha_ 29 else: 30 dfi_alpha=fi.diff(alpha) 31 if dfi_alpha<1/2*dfi1: 32 alpha_=alpha+(alpha-a)*dfi_alpha/(dfi1-dfi_alpha) 33 a=alpha 34 fi1=fi_ 35 dfi1=dfi_alpha 36 alpha=alpha_ 37 else: 38 return alpha
Armijo准则:
1 from linear_search.Function import * 2 from numpy import * 3 4 5 def armijo(_f, val, d): 6 alpha=1 7 8 def _fi(_alpha): 9 return _f(val + _alpha * array(d)) 10 11 fi = Function(_fi) 12 f = Function(_f) 13 fi_=fi.value(alpha) 14 f_=f.value(val) 15 while True: 16 if fi_>f_+1/3*alpha*dot(f.grad(val),array(d).T): 17 alpha=0.7*alpha 18 else: 19 return alpha