线搜索技术

线搜索技术

求解一维函数的极值点的数值迭代法称为一维搜索方法,又称为线搜索技术。实际工程优化问题的目标函数是一元函数的并不多,但是,在求解多元函数最优解的过程中,常常伴随着一系列的线搜索技术。线搜索方法对整个算法的收敛速度、精度都有较大的影响。可以说线搜索技术是优化方法的重要支柱。
在前面的优化技术理论基础中介绍了下降迭代算法的基本迭代公式
x k + 1 = x k + α k d k , ( k = 0 , 1 , 2 , ⋯   ) x_{k+1}=x_k+\alpha_k d_k, (k=0,1,2,\cdots) xk+1=xk+αkdk,(k=0,1,2,)
在这里插入图片描述

当第k步迭代的初始点 x k x_k xk及搜索方向 d k d_k dk确定后,迭代所得到的的新点 x k + 1 x_{k+1} xk+1取决于步长因子 α k \alpha_k αk,不同的 α k \alpha_k αk会得到不同的点 x k + 1 x_{k+1} xk+1和不同的函数值 f ( x k + 1 ) f(x_{k+1}) f(xk+1)。因此,在多维优化的过程中一维线搜索的目的是在既定的 x k x_k xk d k d_k dk下,寻求最优步长因子 α k \alpha_k αk,使第k步迭代产生的新点 x k + 1 x_{k+1} xk+1的函数值 f ( x k + 1 ) f(x_{k+1}) f(xk+1)为最小,即
m i n f ( x k + 1 ) = m i n f ( x k + α d k ) = m i n f ( α ) min f(x_{k+1})=minf(x_k+\alpha d_k)=minf(\alpha) minf(xk+1)=minf(xk+αdk)=minf(α)
显然,求解上式就是一维优化问题,如果一元函数是次数较低的简单函数,可以用一阶导数等于零来求解。若是高次复杂函数,其一阶导数的次数仍然比较高,难以求解,则需采用数值迭代的方法求近似解,这就是本文将要讨论的线搜索技术。
先搜索技术包括精确线搜索技术和非精确线搜索技术,线搜索技术的主要步骤分为两步:
(1)确定搜索区间(单峰区间),这是各种线搜索技术的共性问题;
(2)在搜索区间内求步长因子 α k \alpha_k αk,即选用具体的优化方法.

一、搜索区间的确定
(1)单峰区间
在进行一维搜索时,首先要在给定的方向上确定包含函数值最小值点的搜索区间,而且在该区间内,函数 f ( α ) f(\alpha) f(α)有唯一最小值点 α ∗ \alpha^* α。这种只有一个函数峰值的区间称为单峰区间,如下图所示,
在这里插入图片描述

在极小点 α ∗ \alpha^* α的左边函数值是严格下降的,而在极小值点 α ∗ \alpha^* α的右边函数值是严格上升的,其函数图形呈“高-低-高”的形状。
(2)单峰区间的确定
在进行一维搜索时,必须首先找到单峰区间。若能实现估计出极小值点的大致位置,可以直接得到单峰区间;否则,需要用试探的方法寻找单峰区间,其常用的方法是进退法;
进退法的基本思想是:按照一定的规律给出三个试算点,依次比较各试算点函数值的大小,指导找出函数值按“大-小-大”变化的区间为止,其具体算法步骤如下

算法1:进退法
步1 给定初始点 a 1 a_1 a1和初始步长 h h h;
步2 令 a 2 = a 1 + h a_2=a_1+h a2=a1+h,得到两个试算点 a 1 , a 2 a_1,a_2 a1,a2,计算它们的函数值 f 1 = f ( a 1 ) , f 2 = f ( a 2 ) f_1=f(a_1),f_2=f(a_2) f1=f(a1),f2=f(a2);
步3 比较 f 1 f_1 f1 f 2 f_2 f2的大小,存在如下两种情况
(1)若 f 1 > f 2 f_1>f_2 f1>f2,则作前进运算,为了加速计算过程,步长增大一倍 h = 2 h h=2h h=2h,取第三个试算点 a 3 = a 2 + h a_3=a_2+h a3=a2+h,计算函数值 f 3 = f ( a 3 ) f_3=f(a_3) f3=f(a3),并比较 f 2 f_2 f2 f 3 f_3 f3的大小;
f 3 > f 2 f_3>f_2 f3>f2,则找到了连续三个试算点 a 1 , a 2 , a 3 a_1,a_2,a_3 a1,a2,a3的函数值按照“大-小-大”变化,故搜索区间为 [ a , b ] = [ a 1 , a 3 ] [a,b]=[a_1,a_3] [a,b]=[a1,a3];
f 3 < f 2 f_3<f_2 f3<f2,则抛弃 a 1 a_1 a1,令 a 1 = a 2 , f 1 = f 2 , a 2 = a 3 , f 2 = f 3 a_1=a_2,f_1=f_2,a_2=a_3,f_2=f_3 a1=a2,f1=f2,a2=a3,f2=f3,返回到步3中的(1),重复该过程,直至找到连续三个试算点 a 1 , a 2 , a 3 a_1,a_2,a_3 a1,a2,a3,其函数值按“大-小-大”变化要求为止;
(2)若 f 1 < f 2 f_1<f_2 f1<f2,则作后退运算,令 h = − h h=-h h=h,将 a 1 , f 1 a_1,f_1 a1,f1 a 2 , f 2 a_2,f_2 a2,f2对调,并取第三个试算点 a 3 = a 2 + h a_3=a_2+h a3=a2+h,计算 f 3 = f ( a 3 ) f_3=f(a_3) f3=f(a3),比较对调后的函数值 f 2 f_2 f2 f 3 f_3 f3:
f 3 > f 2 f_3>f_2 f3>f2,则搜索区间 [ a , b ] = [ a 3 , a 1 ] [a,b]=[a_3, a_1] [a,b]=[a3,a1];
f 3 < f 2 f_3<f_2 f3<f2,则步长加倍,抛弃点 a 1 a_1 a1,继续作后退运算,直至找到单峰区间为止。

二、区间消去原理
各种一维搜索方法的共同点是,在找到单峰区间后,再将单峰区间逐渐缩小,从而找到极小值点的近似解;
区间消去法的基本思想是:在单峰区间 [ a , b ] [a,b] [a,b]内取两个点,通过比较该两点的函数值的大小,抛掉函数值较大的段,保留极小值点所在的段,反复比较舍弃,指导极小值点所在的单峰区间缩小到满足精度要求的长度,即 a b ‾ ≤ ϵ \overline{ab}\le\epsilon abϵ,这里 ϵ \epsilon ϵ为给定的精度,从而找到近似的极小值点,如下图所示
在这里插入图片描述

在单峰区间[a,b]内取两个点 x 1 , x 2 x_1,x_2 x1,x2,并计算对应的函数值 f 1 , f 2 f_1,f_2 f1,f2。若 f 1 > f 2 f_1>f_2 f1>f2,如上图a)所示,显然极小值点不在 a x 1 ax_1 ax1段内,取 a = x 1 a=x_1 a=x1,即消去了 a x 1 ax_1 ax1段,得到一个较小的单峰区间;同理如图b)所示若 f 1 < f 2 f_1<f_2 f1<f2,取 b = x 2 b=x_2 b=x2,即消去了 x 2 b x_2b x2b段;如图c)所示, f 1 = f 2 f_1=f_2 f1=f2,可取 a = x 1 , b = x 2 a=x_1,b=x_2 a=x1,b=x2,同时消去了 a x 1 ax_1 ax1段和 b = x 2 b=x_2 b=x2段;但往往为了简化程序,图c)所示的情况归并到前两种情况之一中去了。点 x 1 , x 2 x_1,x_2 x1,x2选取的方法不同,就得到不同的一维线搜索方法。

三、黄金分割法精确线搜索
0.618法又称黄金分割法,它是一种等比例缩短区间的搜索方法,其基本思想是:在单峰区间内取两队对称点,逐步把区间缩小,直到极小值点所在的区间缩小到给定的精度范围内,从而得到近似的最优解。
方法原理:设函数为 f ( x ) f(x) f(x),初始单峰区间为 [ a , b ] [a,b] [a,b],其长 L = b − a L=b-a L=ba,在 [ a , b ] [a,b] [a,b]内取两对称点 x 1 , x 2 , a x 2 = x 1 b = λ L x_1,x_2,ax_2=x_1b=\lambda L x1,x2,ax2=x1b=λL,计算对应的函数值 f 1 = f ( x 1 ) , f 2 = f ( x 2 ) f_1=f(x_1), f_2=f(x_2) f1=f(x1),f2=f(x2),比较它们的大小:
f 1 > f 2 f_1>f_2 f1>f2,显然,极小值点必在区间 [ x 1 , b ] [x_1, b] [x1,b]内,因而抛掉区间 [ a , x 1 ] [a,x_1] [a,x1],即取 a = x 1 a=x_1 a=x1,则新取件为 [ x 1 , b ] [x_1,b] [x1,b],为了程序循环迭代,更新区间 a = x 1 , x 1 = x 2 , f 1 = f 2 a=x_1,x_1=x_2,f_1=f_2 a=x1,x1=x2,f1=f2,然后计算新点 x 2 = a + λ ( b − a ) x_2=a+\lambda(b-a) x2=a+λ(ba);
令区间缩短率为
新 区 间 长 原 区 间 长 = λ L L = λ \frac{新区间长}{原区间长}=\frac{\lambda L}{L}=\lambda =LλL=λ
在得到的新区间内继续比较 f 1 , f 2 f_1,f_2 f1,f2的大小,若 f 1 > f 2 f_1>f_2 f1>f2,抛掉区间 [ a , x 1 ] [a,x_1] [a,x1],即取 a = x 1 a=x_1 a=x1,则新区间为 [ x 1 , b ] [x_1, b] [x1,b],作相应的更新: a = x 1 , x 1 = x 2 , f 1 = f 2 a=x_1,x_1=x_2,f_1=f_2 a=x1,x1=x2,f1=f2,然后计算新点 x 2 = a + λ ( b − a ) x_2=a+\lambda(b-a) x2=a+λ(ba)和函数值 f 2 = f ( x 2 ) f_2=f(x_2) f2=f(x2),则新区建缩短率为
新 区 间 长 原 区 间 长 = ( 1 − λ ) L λ L = 1 − λ λ \frac{新区间长}{原区间长}=\frac{(1-\lambda)L}{\lambda L}=\frac{1-\lambda}{\lambda} =λL(1λ)L=λ1λ
黄金分割法的特点是取每次的缩短率相等,于是有
λ = 1 − λ λ \lambda=\frac{1-\lambda}{\lambda} λ=λ1λ

λ 2 + λ − 1 = 0 \lambda^2+\lambda-1=0 λ2+λ1=0
由上式求解可知 λ = 5 − 1 2 ≈ 0.618 \lambda=\frac{\sqrt{5}-1}{2}\approx 0.618 λ=25 10.618,即每次缩小区间后,所得到的的新区间是原区间的0.618倍,舍弃的区间是原区间的0.382倍。在反复迭代计算过程中,除初始区间要找两个计算点外,在以后每次缩短的新区建内只需要再计算一个新点的函数值即可;对于上述过程,若 f 1 < f 2 f_1<f_2 f1<f2,应消去区间 [ x 2 , b ] [x_2,b] [x2,b]新区间为 [ a , x 2 ] [a,x_2] [a,x2],作相应的更新 b = x 2 , x 2 = x 1 , f 2 = f 1 b=x_2,x_2=x_1,f_2=f_1 b=x2,x2=x1,f2=f1,然后计算新点 x 1 = b − λ ( b − a ) x_1=b-\lambda(b-a) x1=bλ(ba)和函数值 f 1 = f ( x 1 ) f_1=f(x_1) f1=f(x1),比较 f 1 , f 2 f_1,f_2 f1,f2的大小,重复迭代

算法2 黄金分割法
步1 给定单峰区间 [ a , b ] , λ = 0.618 [a,b],\lambda=0.618 [a,b],λ=0.618及收敛精度 ϵ \epsilon ϵ;
步2 在该区间内取两对称点并计算对应的函数值:
x 1 = b − λ ( b − a ) , f 1 = f ( x 1 ) x 2 = a + λ ( b − a ) , f 2 = f ( x 2 ) x_1=b-\lambda(b-a),f_1=f(x_1)\\ x_2=a+\lambda(b-a),f_2=f(x_2) x1=bλ(ba),f1=f(x1)x2=a+λ(ba),f2=f(x2)
步3 比较函数 f 1 f_1 f1 f 2 f_2 f2的大小:
f 1 > f 2 f_1>f_2 f1>f2,则取区间[x_1,b]为新区间,而 x 2 x_2 x2则作为新区间内的第一个试算点,即令
a = x 1 , x 1 = x 2 , f 1 = f 2 a=x_1,x_1=x_2,f_1=f_2 a=x1,x1=x2,f1=f2
而另一个试算点要重新计算
x 2 = a + λ ( b − a ) , f 2 = f ( x 2 ) x_2=a+\lambda(b-a),f_2=f(x_2) x2=a+λ(ba),f2=f(x2)
f 1 ≤ f 2 f_1\le f_2 f1f2,则取 [ a , x 2 ] [a,x_2] [a,x2]为新区间,而 x 1 x_1 x1则作为新区间的第二试算点,即令
b = x 2 , x 2 = x 1 , f 2 = f 1 b=x_2,x_2=x_1,f_2=f_1 b=x2,x2=x1,f2=f1
而另外一个试算点要重新计算
x 1 = b − λ ( b − a ) , f 1 = f ( x 1 ) x_1=b-\lambda(b-a),f_1=f(x_1) x1=bλ(ba),f1=f(x1)

步4 若满足迭代精度 b − a ≤ ϵ b-a\le \epsilon baϵ,则转到下一步,否则返回步骤3,进行下一次迭代计算,进一步缩短区间
步5 输出最优解 x ∗ = 0.5 ( b + a ) , f ∗ = f ( x ∗ ) x^*=0.5(b+a),f^*=f(x^*) x=0.5(b+a),f=f(x)

黄金分割法的特点:
(1)每次区间的缩短率为0.618
(2)每一次只需要计算一个新点 x 1 x_1 x1 x 2 x_2 x2的函数值,另外利用上次旧迭代点的信息,节省计算时间
(3)方法简单,对函数没有特殊要求,适应性强
(4)没有利用函数自身的数学特性,收敛速度慢

四、Armijo准则
线搜索技术是求解许多优化问题下降算法的基本组成部分,但精确线搜索往往需要计算很多的函数值甚至梯度值,对于复杂函数而言,这种函数值以及梯度值的计算耗费较多的计算资源。特别是当迭代点远离最优点时,精确线搜索通常不是十分有效与合理的。对于许多优化算法,其收敛速度并不依赖于精确线搜索过程。因此,既能保证目标函数具有可接受的下降量又能使最终形成的迭代序列收敛的非精确线搜索变得越来越流行,本小节介绍的Armijo准则以及Wolfe准则就是非精确线搜索常用的准则。

Armijo准则:设 d k d_k dk是点 x k x_k xk处的下降方向,若
f ( x k + α d k ) ≤ f ( x k ) + c 1 α ∇ f ( x k ) T d k f(x_k+\alpha d_k)\le f(x_k)+c_1\alpha\nabla f(x_k)^Td_k f(xk+αdk)f(xk)+c1αf(xk)Tdk
则称步长 α \alpha α满足Armijo准则,其中 c 1 ∈ ( 0 , 1 ) c_1\in(0,1) c1(0,1)是一个常数.
Armijo准则有非常直观的几何含义,它指的是点 ( α , ϕ ( α ) ) (\alpha,\phi(\alpha)) (α,ϕ(α))必须在直线 l ( α ) = ϕ ( 0 ) + c 1 α ∇ f ( x k ) T d k l(\alpha)=\phi(0)+c_1\alpha\nabla f(x_k)^Td_k l(α)=ϕ(0)+c1αf(xk)Tdk的下方
在这里插入图片描述

如上图所示,区间 [ 0 , α 1 ] [0,\alpha_1] [0,α1]中的点均满足Armijo准则。在实际应用中,参数 c 1 c_1 c1通常选为一个很小的正数,这使得Armijo准则非常容易得到满足。但是仅仅使用Armijo准则并不能保证迭代的收敛性,这是因为 α = 0 \alpha=0 α=0也满足Armijo准则,但是这意味着迭代序列中的点固定不变,研究这样的步长没有意义。为此Armijo准则需要配合其他准则共同使用。在优化算法的视线中,寻找一个满足Armijo准则的步长是比较容易的,一个最常用的算法是回退法。给定初值 α ^ \hat{\alpha} α^,回退法通过不断以指数方式缩小试探步长,找到第一个满足Armijo准则的点。具体来说,回退法选取 α k = γ j 0 α ^ \alpha_k=\gamma^{j_0}\hat{\alpha} αk=γj0α^,其中
j 0 = m i n { j = 0 , 1 , ⋯ ∣ f ( x k + γ j α ^ d k ) ≤ f ( x k ) + c 1 γ j α ^ ∇ f ( x k ) T d k } j_0=min \{j=0,1,\cdots|f(x_k+\gamma^j\hat{\alpha}d_k)\le f(x_k)+c_1\gamma^j\hat{\alpha}\nabla f(x_k)^Td_k\} j0=min{j=0,1,f(xk+γjα^dk)f(xk)+c1γjα^f(xk)Tdk}
参数 γ ∈ ( 0 , 1 ) \gamma\in(0,1) γ(0,1)为一给定的实数。回退法的基本过程如下

armijo回退法:
步1 选择初始步长 α ^ \hat{\alpha} α^,参数 γ ∈ ( 0 , 1 ) \gamma\in(0, 1) γ(0,1),初始化 α = α ^ \alpha=\hat{\alpha} α=α^
步2 while f ( x k + α d k ) > f ( x k ) + c α ∇ f ( x k ) T d k f(x_k+\alpha d_k)\gt f(x_k)+c\alpha\nabla f(x_k)^Td_k f(xk+αdk)>f(xk)+cαf(xk)Tdk do
α = γ α , k = k + 1 \alpha=\gamma\alpha,k = k + 1 α=γα,k=k+1
end while
步3 输出 α k = α \alpha_k=\alpha αk=α

该算法被称为回退法是因为 α \alpha α的试验值是由大到小的,它可以确保输出的 α k \alpha_k αk能尽量地大。此外回退法不会无限进行下去,因为 d k d_k dk是一个下降方向,当 α \alpha α充分小时,Armijo准则总是成立的,在实际应用中我们通常会给 α \alpha α设置一个下界,防止步长过小。

五、Wolfe准则
Wolfe准则:设 d k d_k dk是点 x k x_k xk处的下降方向,若
f ( x k + α d k ) ≤ f ( x k ) + c 1 α ∇ f ( x k ) T d k , ∇ f ( x k + α d k ) T d k ≥ c 2 ∇ f ( x k ) T d k , \begin{aligned} &f(x_k+\alpha d_k)\le f(x_k)+c_1\alpha\nabla f(x_k)^Td_k, \\ &\nabla f(x_k+\alpha d_k)^Td_k\ge c_2\nabla f(x_k)^Td_k, \end{aligned} f(xk+αdk)f(xk)+c1αf(xk)Tdk,f(xk+αdk)Tdkc2f(xk)Tdk,
则称步长 α \alpha α满足Wolfe准则,其中 c 1 , c 2 ∈ ( 0 , 1 ) c_1,c_2\in(0,1) c1,c2(0,1)为给定的常数且 c 1 < c 2 c_1\lt c_2 c1<c2.
在该准则中,第一个不等式记为Armijo准则,而第二个不等式则是Wolfe准则的本质要求,Wolfe准则要求 ϕ ( α ) \phi(\alpha) ϕ(α)在点 α \alpha α处的斜率不能小于其在零点的斜率的 c 2 c_2 c2倍。注意到在 ϕ ( α ) \phi(\alpha) ϕ(α)的极小值点 α ∗ \alpha* α处有 ϕ ′ ( α ∗ ) = ∇ f ( x k + α ∗ d k ) T d k = 0 \phi^{'}(\alpha^*)=\nabla f(x_k+\alpha^*d_k)^Td_k= 0 ϕ(α)=f(xk+αdk)Tdk=0,因此 α ∗ \alpha* α永远满足Wolfe准则的第二式,而选择较小的 c 1 c_1 c1可使 α ∗ \alpha^* α同时满足第一式,即Wolfe准则在绝大多数情况下会包含线搜索子问题的精确解。在实际应用中,参数 c 2 c_2 c2通常选取为0.9

六、线搜索收敛性
线搜索算法的框架:
步0 初始化,选取有关参数的初始迭代点 x 0 x_0 x0,设定容许误差 ϵ \epsilon ϵ,迭代步数 k = 0 k=0 k=0
步1 检验终止判别主责,计算 g k = ∇ f ( x k ) g_k=\nabla f(x_k) gk=f(xk),若 ∣ ∣ ∣ g k ∣ ≤ ϵ |||g_k|\le\epsilon gkϵ,输出 x ∗ ≈ x k x^*\approx x_k xxk,停止计算;
步2 确定下降方向 d k d_k dk,使满足 g k T d k < 0 g_k^Td_k\lt 0 gkTdk<0;
步3 确定步长因子 α k \alpha_k αk,可以在系列“精确”与“非精确”两种线搜索技术中选用其一:
(1)用前面介绍的黄金分割法或者其他精确线搜索技术求
α k = a r g min ⁡ α > 0 f ( x k + α d k ) \alpha_k=arg\min_{\alpha>0}f(x_k+\alpha d_k) αk=argα>0minf(xk+αdk)
(2)用前面介绍的Armijo准则或者Wolfe准则等非精确线搜索技术求 α k \alpha_k αk;
步4 迭代更新点,令 x k + 1 = x k + α k d k , k = k + 1 x_{k+1}=x_k+\alpha_kd_k,k=k+1 xk+1=xk+αkdk,k=k+1,转步1

值得说明的是,为了保证这类算法的收敛性,除了在步3要选用适当的线搜索技术之外,搜索方向 d k d_k dk也需要满足一定的条件,即对于所有的 k , d k k,d_k k,dk − g k -g_k gk的夹角满足
0 ≤ θ k ≤ π 2 − μ , μ ∈ ( 0 , π 2 ) 0\le\theta_k\le\frac{\pi}{2}-\mu,\mu\in(0,\frac{\pi}{2}) 0θk2πμ,μ(0,2π)即要求 d k d_k dk与负梯度方向夹角为锐角

七、线搜索代码实现及举例
(1)进退法
进退法代码实现如下

function [a, b] = forward_backward_method(func, x0, h)

a1 = x0;
a2 = a1 + h;
f1 = feval(func, a1);
f2 = feval(func, a2);

maxIter = 1000;
iIter = 0;

while iIter < maxIter
    if f1 < f2
        h = -h;
        a3 = a1; f3 = f1;
        a1 = a2; f1 = f2;
        a2 = a3; f2 = f3;
    end
    h = 2 * h; a3 = a2 + h; f3 = feval(func, a3);
    
    if f3 > f2
        if h > 0
            a = a1; b = a3;
            break;
        else
            a = a3; b = a1;
            break
        end
    else
        a1 = a2; f1 = f2;
        a2 = a3; f2 = f3;
    end
    
    iIter = iIter + 1;
end

if iIter == 1000
    fprintf('reach maximum iteration, and not found suitable interval!\n');
    a = 0;  b = 0;
else
    fprintf('find interval: [a, b] = [%d, %d]\n', a, b);
end

end

进退法实验1
f ( x ) = x 2 − sin ⁡ ( x ) f(x)=x^2-\sin(x) f(x)=x2sin(x),初始点及步长为 x 0 = − 1 , h = 0.2 x0=-1,h=0.2 x0=1,h=0.2

>> x0 = -1;
>> h = 0.2;
>> func = inline('x.^2 - sin(x)')
>> [a, b] = forward_backward_method(func, x0, h);
find interval: [a, b] = [-4.000000e-01, 2]

进退法实验2
f ( x ) = 1 x f(x)=\frac{1}{x} f(x)=x1

> x0 = 1;
>> h = 0.01;
>> [a, b] = forward_backward_method(func, x0, h);
reach maximum iteration, and not found suitable interval!

(2)黄金分割法
黄金分割法线搜索代码实现如下:

function [xmin, fmin] = golden_line_search(func, a, b, epsilon)

lambda = ( sqrt(5) - 1 ) / 2;
L = b - a;
x1 = b - lambda * L; f1 = feval(func, x1);
x2 = a + lambda * L; f2 = feval(func, x2);

iIter = 0;
iterMax = 1000;

while iIter < iterMax
    iIter = iIter + 1;
    if f1 > f2
        a = x1; x1 = x2; f1 = f2;
        x2 = a + lambda * (b - a); f2 = feval(func, x2);
    else
        b = x2; x2 = x1; f2 = f1;
        x1 = b - lambda * (b - a); f1 = feval(func, x1);
    end
    
    if abs(b - a) <= epsilon
        break;
    end
    
end

if iIter == iterMax
    fprintf('reach maimum iteration, and not found xmin!\n');
    xmin = 0; fmin = 0;
else
    xmin = 0.5 * (a + b); fmin = feval(func, xmin);
end

end

黄金分割法实验1:
f ( x ) = x + 20 x f(x)=x+\frac{20}{x} f(x)=x+x20 [ 0.2 , 1 ] [0.2, 1] [0.2,1]上的最小值

function f = mostCheapVelocity(x)

f = x + 20 / x;

end
% golden line search test
x1 = 0.2;
x2 = 1;
epsilon = 0.0001;
[fmin, xmin] = golden_line_search('mostCheapVelocity', x1, x2, epsilon);
fprintf('fmin = %f, xmin = %f\n', fmin, xmin);


[x, fval] = fminbnd('mostCheapVelocity', x1, x2);
fprintf('matlab buildin 1d search: fmin = %f, xmin = %f\n', fval, x);

[fmin, xmin] = squareInterpSearch('mostCheapVelocity', x1, x2, epsilon);
fprintf('square interp search: fmin = %f, xmin = %f\n', fmin, xmin);

计算结果:

fmin = 0.996748, xmin = 21.062005
matlab buildin 1d search: fmin = 21.000992, xmin = 0.999948
square interp search: fmin = 23.193544, xmin = 0.897000

从实验结果来看,实现代码计算的结果与matlab内置的线搜索的结果一致

(3)Armijo准则
Armijo准则代码实现:

function [fnew, xnew, alpha] = armijo_rule(func, gfunc, x0, alpha0, dk)

c1 = 1e-3;
alpha = alpha0;
gamma = 0.8;

iIter = 0;
iterMax = 200;
alphaMin = 1e-5;

while iIter < iterMax 
    
    xnew = x0 + alpha * dk;
    fnew = feval(func, xnew);
    f0 = feval(func, x0);
    if fnew <= f0 + c1 * feval(gfunc, x0)' * dk
        break;
    end
    
    if alpha < alphaMin
        break;
    end
    
    alpha = gamma * alpha;
    iIter = iIter + 1;   
end

if iIter == iterMax
    alpha = alphaMin;
    fprintf('reach maximum iteration, and not found suitable alpha.\n');
end

xnew = x0 + alpha * dk;
fnew = feval(func, xnew);

end

(4)Wolfe准则
Wolfe准则代码实现:

function [fnew, xnew, alpha] = armijo_rule(func, gfunc, x0, alpha0, dk)

c1 = 1e-3;
alpha = alpha0;
gamma = 0.8;

iIter = 0;
iterMax = 200;
alphaMin = 1e-5;

while iIter < iterMax 
    
    xnew = x0 + alpha * dk;
    fnew = feval(func, xnew);
    f0 = feval(func, x0);
    if fnew <= f0 + c1 * feval(gfunc, x0)' * dk
        break;
    end
    
    if alpha < alphaMin
        break;
    end
    
    alpha = gamma * alpha;
    iIter = iIter + 1;   
end

if iIter == iterMax
    alpha = alphaMin;
    fprintf('reach maximum iteration, and not found suitable alpha.\n');
end

xnew = x0 + alpha * dk;
fnew = feval(func, xnew);

end

考虑无约束优化问题
min ⁡ x ∈ R 2 f ( x ) = 100 ( x 1 2 − x 2 ) 2 + ( x 1 − 1 ) 2 \min_{x\in R^2}f(x)=100(x_1^2-x_2)^2+(x_1-1)^2 xR2minf(x)=100(x12x2)2+(x11)2设当前迭代点 x k = ( − 1 , 1 ) T x_k=(-1,1)^T xk=(1,1)T,下降方向 d k = ( 1 , − 2 ) T d_k=(1,-2)^T dk=(1,2)T,利用Armijo和Wolfe准则求解步长因子 α k \alpha_k αk
函数计算

function f = func(x)
f = 100 * (x(1)^2 - x(2))^2 + (x(1) - 1)^2;
end

梯度计算

function f = func(x)
f = 100 * (x(1)^2 - x(2))^2 + (x(1) - 1)^2;
end

调用armijo准则以及wolfe准则计算下一步迭代步长:

% armijo rule test
xk = [-1, 1]';
dk = [1, -2]';
alpha0 = 10;


[fNew, xNew, alpha] = armijo_rule('func', 'gfunc', xk, alpha0, dk);
fOld = feval('func', xk);
fprintf('armijo rule: fOld = %f, fNew = %f, xNew = [%f, %f], alpha = %f\n', fOld, fNew, xNew(1), xNew(2), alpha);

[fNew, xNew, alpha] = wolfe_rule('func', 'gfunc', xk, alpha0, dk);
fOld = feval('func', xk);
fprintf('wolfe rule: fOld = %f, fNew = %f, xNew = [%f, %f], alpha = %f\n', fOld, fNew, xNew(1), xNew(2), alpha);

结果为:

armijo rule: fOld = 4.000000, fNew = 3.581038, xNew = [-0.718525, 0.437050], alpha = 0.281475
wolfe rule: fOld = 4.000000, fNew = 3.581038, xNew = [-0.718525, 0.437050], alpha = 0.281475

在这里插入图片描述

  • 8
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
多段线数据压缩是指对多段线数据进行压缩,以减少数据的存储空间和传输带宽的使用。在csdn的搜索中,可以找到关于多段线数据压缩的相关文章和技术实现。 多段线是由一系列相邻的线段组成的,表示了复杂的曲线或路径。在某些应用中,如地理信息系统、计算机辅助设计等,多段线是非常常见的数据类型。 对多段线数据进行压缩的目的是为了优化数据存储和传输效率。常见的多段线数据压缩方法包括直线段压缩和曲线插值压缩。 直线段压缩是基于直线段的特性,将连续的直线段合并为一条直线,从而减少段数和数据量。这种压缩方法适用于多段线中存在大量相邻且方向一致的直线段的情况。 曲线插值压缩是基于曲线的特性,通过插值方法将曲线转化为几个点,然后使用这些点重新表示原曲线。这种压缩方法适用于多段线中存在较多曲线段的情况。 csdn上的搜索可以提供关于多段线数据压缩的技术原理、算法实现、性能分析等方面的信息。在这些文章中,可以了解到各种多段线数据压缩方法的优缺点,选择适合自己应用场景的压缩方法。 总之,多段线数据压缩是一种重要的数据优化技术,可以在存储和传输中节省空间和带宽。在csdn的搜索结果中,可以找到关于多段线数据压缩的相关知识和技术,帮助我们更好地理解和应用多段线数据压缩。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值