最优化问题——一维搜索(一)

最优化问题——一维搜索

1. 一维搜索的引入

1.1 从非线性规划问题到一维搜索

在前面的文章中,我们提到了基于迭代的非线性规划问题的求解思路。在求解过程中,我们提到了在每一步的迭代中都需要对计算步长因子,其计算公式为:
λ k = m i n λ f ( x k + λ p ) λ_k=min_{λ}f(x_k+λp) λk=minλf(xk+λp)
我们将 f ( x k + λ p ) f(x_k+λp) f(xk+λp)视为λ的一元函数,我们的目标就是求这个一元函数的极小值。对于这个问题,我通常的求解方式为一维搜索。

1.2 一维搜索的基本形式

一元函数求极小值以及线性的搜索均为一维搜索,求常用求:
m i n f ( x k + λ d k ) = φ ( λ ) , s . t . λ ∈ S minf(x_k+λd_k)=φ(λ),s.t. λ∈S minf(xk+λdk)=φ(λ)s.t.λS
这里我们给出对于一维搜索能够解决的问题的基本形式,我们将原来对于x的函数f看做是对于λ的函数φ。然后对于φ函数求极值。进一步。对于结果的范围λ,包括以下几个范围情况:
( − ∞ , + ∞ ) , ( 0 , + ∞ ) , [ a , b ] (-∞,+∞),(0,+∞),[a,b] (+)0+[a,b]
同时,根据我们目标值的精确度,我们可以将这种一维搜索分成精确搜索近似搜索,则本篇文章中,我们重点关注精确搜索的相关思路和算法。

通常的,我们对于参数λ的搜索是在一个在能够确定的区间内进行的,所以我们把关注点放在对于缩小区间[a,b]上的搜索。其具体的形式为:

m i n φ ( λ ) s . t . λ ∈ [ α , β ] min φ(λ)\\ s.t. λ∈[α,β] minφ(λ)s.t.λ[αβ]
注意:这里的φ函数为 R − > R R->R R>R

1.3 缩小区间的精确一维搜索

上一个小节,我们给出了对于缩小区间一维搜索的一般形式。同时,我们的搜索目标是在区间 [ α , β ] [α,β] [α,β]s上面寻找含有 φ ( λ ) φ(λ) φ(λ)最小点。为了便于搜索,我们先给出两个概念和常见的定理。

单谷和强单谷:

对于任意的 λ 1 , λ 2 λ_1,λ_2 λ1,λ2,存在 α ≤ λ 1 < λ 2 ≤ β α≤λ_1<λ_2≤β αλ1<λ2β,其满足:

  1. 如果 λ 2 ≤ λ ∗ λ_2≤λ^* λ2λ,则 φ ( λ 1 ) > φ ( λ 2 ) φ(λ_1)>φ(λ_2) φ(λ1)>φ(λ2)
  2. 如果 λ 1 ≥ λ ∗ λ_1≥λ^* λ1λ,则 φ ( λ 1 ) < φ ( λ 2 ) φ(λ_1)<φ(λ_2) φ(λ1)<φ(λ2)

则称φ(λ)在[α,β]上强单谷。下面,有图来理解一下这个概念:

在这里插入图片描述
从上面的图示中我们不难发现,当在α到β这段曲线中,只存在一个极小值点的时候,当 λ 1 , λ 2 λ_1,λ_2 λ1,λ2都在极小值点 λ ∗ λ^* λ的左侧的时候,满足第一个条件描述,都在其右侧的时候满足第二个条件描述。

进一步,当这一段曲线存在一段极小值的区域的时候,我们想要满足上述的两个条件,就需要保证的是当 φ ( λ 1 ) ≠ φ ( λ ∗ ) φ(λ_1)≠φ(λ^*) φ(λ1)=φ(λ) φ ( λ 1 ) ≠ φ ( λ ∗ ) φ(λ_1)≠φ(λ^*) φ(λ1)=φ(λ)时才能满足上面的两个描述。此时,我们称其为单谷

最后,我们给出一个关于单谷的搜索定理。

定理:设函数φ:R->R在[α,β]上单谷,α≤λ<μ≤β,则有如下:

  1. 如果φ(λ)≥φ(μ),则φ(ρ)≥φ(μ),任意的ρ∈[α,λ]。
  2. 如果φ(λ)<φ(μ),则φ(ρ)≥φ(λ),任意的ρ∈[μ,β]。

进一步,我们使用两个图来理解一下这两个条件:
在这里插入图片描述
首先,对于[α,β]内部是单谷的区域,也就是存在一片最小值的区域,并且曲线是先降后增的趋势,在此时,若 φ ( λ ) ≥ φ ( μ ) φ(λ)≥φ(μ) φ(λ)φ(μ),对于先降后增的趋势,我们可以知道对于λ左侧的区域的φ函数值是要高于在φ点的函数值的,也就是 φ ( ρ ) > φ ( λ ) ≥ φ ( μ ) φ(ρ)>φ(λ)≥φ(μ) φ(ρ)>φ(λ)φ(μ),所以有 φ ( ρ ) > φ ( μ ) φ(ρ)>φ(μ) φ(ρ)>φ(μ)

同理,我们就能够理解第二个描述。

在这里插入图片描述

2. 一维搜索相关算法

首先,在介绍这个部分之前,我们先来分析,使用搜索区间的思路来求解极小值点的基本思路。

  1. 首先,确定包含最小值的初始搜索区间。
  2. 其次,利用某些区间的分割技术或者插值技术来迭代减小该区间,直到区间的宽度小于预先设定的精度,即可以获得其近似解。
    下面我们来介绍具体的相关算法。
2.1 黄金分割法
2.1.1 算法引入和区间推导

在使用黄金分割法之前,我们需要知道的,这种方法主要是针对单谷有效的。

回顾我们上面描述的对于单谷的定理,根据定理的描述很容易知道,在区域[ α,β]内选择两个点λ和μ,满足λ<μ。通过比较φ(λ)和φ(μ),则可以去掉[α,λ]或者[μ,β]。这样就可以进一步的去缩减搜索区域。

现在有了一个新的问题,我们应该如何确定缩减之后区域的大小?基本上可以有以下两种思路:

  1. 对称选择,使得 λ-α=β-μ,通过这样选择的λ和μ可以将“坏”的区间去掉,区间的长度不小于“好”的情况。
  2. 保持缩减的比例。t=(保留的区间长度/原区间的长度)不变。通过这种思路,使得每一个保留下来的节点λ或者节点μ,在下一次的比较中称为一个相应比例位置的点。

进一步,我们从第二种思路出发,假设经过一次缩减之后,当前的保留的区域为[α,μ],则当前的缩减比例为:
t = μ − α β − α t= \frac{μ-α}{β-α} t=βαμα
同理,假设我们下一步保留的区间长度为[α,λ],则有缩减比例为:
t = λ − α μ − α t=\frac{λ-α}{μ-α} t=μαλα
由于缩减比例相同,则有:
t = μ − α β − α = λ − α μ − α t=\frac{μ-α}{β-α}=\frac{λ-α}{μ-α} t=βαμα=μαλα
最后,我们可以推导出来:
{ μ = α + t ( β − α ) λ = α + t ( μ − α ) t 2 + t − 1 = 0 \begin{cases} μ=α+t(β-α)\\ λ=α+t(μ-α)\\ t^2+t-1=0 \end{cases} μ=α+t(βα)λ=α+t(μα)t2+t1=0
获得最后的结果t≈0.618,(由于是比例,这里我们的t只需要取正值)

同理,根据t的值,我们也可以推导出来:

{ μ = α + t ( β − α ) λ = α + ( 1 − t ) ( β − α ) \begin{cases} μ=α+t(β-α)\\ λ=α+(1-t)(β-α)\\ \end{cases} {μ=α+t(βα)λ=α+(1t)(βα)

最后,我们就确定了关于λ和μ的取值,以及区间的比例为0.618。

2.1.2 算法描述

在这里插入图片描述

2.1.3 代码描述
#encoding=utf-8
'''
黄金分割法

1. φ函数为 φ(λ)= λ*λ-4λ+3
2. 给定的初始区间 α和 beta为 1.5,2.5
'''

def fai_function(par):
    return par * par - 4 * par + 3
def gold_search(alpha,beta,e):
    '''

    :param alpha: 区间开始
    :param beta: 区间结束
    :param e: 精度系数
    :return:
    '''
    t = 0.618
    lam = alpha + (1-t) * (beta - alpha)
    miu = alpha + t * (beta - alpha)

    while (beta - alpha) >= e:
        if fai_function(lam) > fai_function(miu):
            alpha = lam
            beta = miu
            miu = alpha + t * (beta - alpha)
        else:
            beta = miu
            miu = lam
            lam = alpha + (1-t) * (beta-alpha)
        print("the alpha is {}, the beta is {}".format(alpha,beta))

    best_lam = (alpha + beta) / 2
    return best_lam
if __name__ == '__main__':
    best = gold_search(1.5,2.5,0.01)
    print(fai_function(best))
2.1.4 算法扩展—斐波那契区间

和黄金分割法类似的方法还包括斐波那契算法,区别在于搜索区间长度的缩短率笔试黄金分割数,而是斐波那契数。

简单的推导一下:

假设当前的上下边界为 a k , b k a_k,b_k ak,bk,则我们要推导的下一轮迭代的区间车长度为:
b k + 1 − a k + 1 = F n − k F n − k + 1 ( b k − a k ) b_{k+1}-a_{k+1}=\frac{F_{n-k}}{F_{n-k+1}}(b_k-a_k) bk+1ak+1=Fnk+1Fnk(bkak)
同时要求,在经历了n次迭代之后,有:
b n − a n ≤ δ b_n-a_n≤δ bnanδ
实际上,当n->∞的时候,有:
l i m F n F n + 1 = 5 − 1 2 ; b n − a n = 1 F n ( b 1 − a 1 ) lim\frac{F_n}{F_{n+1}}=\frac{\sqrt{5}-1}{2};b_n-a_n=\frac{1}{F_n}(b_1-a_1) limFn+1Fn=25 1bnan=Fn1(b1a1)

2.1.5 算法扩展—中分法

假设和φ(λ)在区间[α,β]内部是可微的,并且当导数为0的时候是最优解,在取λ=(α+β)/2,那么则有:

  1. φ ′ ( λ ) = 0 φ'(λ)=0 φ(λ)=0时,λ为最小点, λ = λ ∗ λ=λ^* λ=λ
  2. φ ′ ( λ ) > 0 φ'(λ)>0 φ(λ)>0时,λ为在上升段, λ > λ ∗ λ>λ^* λ>λ,去掉[λ,β]。
  3. φ ′ ( λ ) < 0 φ'(λ)<0 φ(λ)<0时,λ为在下降段, λ < λ ∗ λ<λ^* λ<λ,去掉[α,λ]。

在这里插入图片描述
进一步,给出其实现的代码:

'''
1. φ函数为 φ(λ)= λ*λ-4λ+3
2. 给定的初始区间 α和 beta为 1.5,2.5
'''
def grad_value(x):
    return 2*x - 4
def middle_search(alpha,beta):
    lam = (alpha + beta) / 2
    while grad_value(lam) != 0:
        if grad_value(lam) > 0:
            beta = lam
        else:
            alpha = lam
        lam = (beta+alpha) / 2
    return  (beta+alpha) / 2

if __name__ == '__main__':
    best = middle_search(1.0,5.0)
    print(fai_function(best))
2.2 进退法确定初始区间

在上一个小结中,我们主要介绍了三种方法来进行搜索,在三种搜索中,我们初始都需要给点最优点所在的上下区间α和β。所有,这里来介绍如何利用进退法来确定初始的取值区间。其思路描述如下:

初始:任取 λ 0 λ_0 λ0,步长 δ > 0 δ>0 δ>0,取 λ 1 = λ 0 + δ λ_1=λ_0+δ λ1=λ0+δ

  1. 如果有: φ ( λ 0 ) < φ ( λ 1 ) φ(λ_0)<φ(λ_1) φ(λ0)<φ(λ1),令δ=2δ(步长加倍), λ 1 = λ 0 − δ λ_1=λ_0-δ λ1=λ0δ
    { 如 果 φ ( λ 2 ) < φ ( λ 0 ) , 则 令 λ 1 = λ 0 , λ 0 = λ 2 , 重 复 第 一 步 如 果 φ ( λ 2 ) > φ ( λ 0 ) , 则 停 止 , 令 α = λ 2 , β = λ 1 \begin{cases} 如果 φ(λ_2)<φ(λ_0),则令λ_1=λ_0,λ_0=λ_2,重复 第一步\\ 如果 φ(λ_2)>φ(λ_0),则停止,令α=λ_2,β=λ_1 \end{cases} {φ(λ2)<φ(λ0)λ1=λ0λ0=λ2φ(λ2)>φ(λ0)α=λ2,β=λ1
  2. 如果有: φ ( λ 0 ) > φ ( λ 1 ) , 令 δ = 2 δ ( 步 长 加 倍 ) , λ 2 = λ 1 + δ φ(λ_0)>φ(λ_1),令δ=2δ(步长加倍),λ_2=λ_1+δ φ(λ0)φ(λ1)δ=2δ()λ2=λ1+δ
    { 如 果 φ ( λ 2 ) < φ ( λ 1 ) , 则 令 λ 0 = λ 1 , λ 1 = λ 2 , 重 复 2 如 果 φ ( λ 2 ) > φ ( λ 1 ) , 则 停 止 , 令 α = λ 0 , β = λ 2 \begin{cases} 如果 φ(λ_2)<φ(λ_1),则令λ_0=λ_1,λ_1=λ_2,重复 2\\ 如果 φ(λ_2)>φ(λ_1),则停止,令α=λ_0,β=λ_2 \end{cases} {φ(λ2)<φ(λ1)λ0=λ1λ1=λ22φ(λ2)>φ(λ1)α=λ0,β=λ2

这个思路考虑起来并不是很麻烦,首先,我们需要的是一个包含最优点的区间,假设我们给定的初始 λ 0 λ_0 λ0点就在最小点的区域内,那就从初始点向左右两个方向扩展即可。对于第一种情况,说明初始点比第一个点 λ 1 λ_1 λ1更能对应最小点,则从 λ 0 λ_0 λ0向左侧扩展生成 λ 2 λ_2 λ2,进一步对于扩展生成的第二个点 λ 2 λ_2 λ2,其对应的函数值和当前更接近最优点的 λ 0 λ_0 λ0去比较也会有两种情况出现,第一种情况是 λ 2 λ_2 λ2对应的函数值更大,那就说明我们通过 λ 2 , λ 1 λ_2,λ_1 λ2,λ1,已经将最优点所在区域囊括进去了。此时可以直接确定初始的范围。第二种情况是 λ 0 λ_0 λ0对应的函数值更大,那么也就是说 λ 2 λ_2 λ2更接近与最小的区域,那就让整个区间范围左移,也就是让 λ 1 λ_1 λ1左移到 λ 0 λ_0 λ0的位置,让 λ 0 λ_0 λ0左移到 λ 2 λ_2 λ2的位置,然后继续向左侧进行扩展寻找下界。同理,当 λ 1 λ_1 λ1对应的函数值小于 λ 0 λ_0 λ0对应的函数值的时候,整个区间右移,分析方法和上面类似。不在赘述。

同样,我们也给出关于进退法的代码:

def forward_back(delta):
    lam_0 = random.uniform(0,10)
    lam_1 = lam_0 + delta
    alpha = -1
    beta = -1
    while True:
        if fai_function(lam_0) < fai_function(lam_1):
            delta = 2 * delta
            lam_2 = lam_0 - delta
            if fai_function(lam_2) > fai_function(lam_0):
                alpha = lam_2
                beta = lam_1
                return alpha,beta
            else:
                lam_1 = lam_0
                lam_0 = lam_2
        else:
            delta = 2 * delta
            lam_2 = lam_1 + delta
            if fai_function(lam_2) > fai_function(lam_1):
                alpha = lam_0
                beta = lam_2
                return alpha,beta
            else:
                lam_0 = lam_1
                lam_1 = lam_2

注意: 我们在使用进退法来 确定初始区间的时候,有以下几个点需要着重的强调:

  1. 选择合适的δ,δ太大会导致整个区域内包含多个局部的极小值,整个区间太小可能会导致迭代次数多的增加。
  2. 当φ函数是单调函数的时候,这种方法并不适用。
  3. 可以考虑和上一节描述的中点法配合使用来寻找确定。

3 总结

在本篇文章中,我们重点关注的是一维搜索的精确搜索的基本形式,相关定理和不使用梯度信息的黄金分割搜索,斐波那契搜索以及利用一阶导数的重点法搜索,在最后,我们给出了如何确定初始区间的进退法的算法描述和代码实现。

4 参考

  1. 哈工大—组合优化和凸优化
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值