不精确线搜索方法

  精确线搜索花费的计算量一般较大。一般问题中,特别是初始迭代点具体目标点较远时,不精确线搜索的效率往往要高于精确线搜索。并且牛顿法和拟牛顿法的收敛速度不依赖于步长的搜索,因此可以对α进行不精确线搜索。

 

  不精确线搜索包括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

 

posted @ 2018-06-08 10:19  "kisetsu  阅读(2602)  评论(0编辑  收藏  举报