包含区间搜索以及黄金分割法的介绍
上一篇教程:自动求导、数值微分 ↑
下一篇教程:多维无约束最优化方法 ↓
\def\red#1{\color{red}{#1}} \def\teal#1{\color{teal}{#1}} \def\green#1{\color{green}{#1}} \def\transparent#1{\color{transparent}{#1}} \def\orange#1{\color{orange}{#1}} \def\fml#1{\text{(#1)}}
在使用一维优化方法搜索目标函数的极小值点时,首先要确定搜索区间 [a,b],这个搜索区间要包含目标函数的极小值点,而且是单峰区间,即在这个区间内,目标函数只有一个极小值点。
在单峰区间内,函数值具有“高—低—高”的特点。根据这一特点,可以采用进退法来找到搜索区间。
进退法分为
两步,其步骤如下
f_1=f(\alpha_1),\quad f_2=f(\alpha_1+h)
f_1=f(\alpha_1+h),\quad f_2=f(\alpha_1+3h)
若 f_1< f_2,则初始搜索区间端点为a=\alpha_1,\quad b=\alpha_1+3h
若 f_1=f_2,则初始搜索区间端点为a=\alpha_1+h,\quad b=\alpha_1+3h
若 f_1>f_2,则要继续做前进运算,且步长再加大两倍,取第 4 个点 \alpha_1+7h,再比较第 3 和第 4 个点处的函数值……如此反复循环,直到在连续的 3 个点的函数值出现“两头大、中间小”的情况为止。f_1=f(\alpha_1-h),\quad f_2=f(\alpha_1)
若 f_1>f_2,则初始搜索区间端点为a=\alpha_1-h,\quad b=\alpha_1+h
若 f_1=f_2,则初始搜索区间端点为a=\alpha_1-h,\quad b=\alpha_1
若 f_1< f_2,则要继续做后退运算,且步长再加大两倍,取第 4 个点 \alpha_1-3h,再比较第 3 和第 4 个点处的函数值……如此反复循环,直到在连续的 3 个点的函数值出现“两头大、中间小”的情况为止。示例
试用进退法确定目标函数 f(\alpha)=\alpha^2-5\alpha+8的一维优化初始搜索区间 [a,b]。设初始点 \alpha_1=0,初始步长 h=1
解: 由初始点 \alpha_1=0,初始步长 h=1,得
f_1=f(\alpha_1)=8,\quad f_2=f(\alpha_1+h)=4
因为 f_1>f_2,所以执行前进运算,将步长加大 2 倍,取新点 \alpha_1+3h=3,令
f_1=f(\alpha_1+h)=4,\quad f_2=f(\alpha_1+3h)=2
因为 f_1>f_2,应继续做前进运算,且步长再加大 2 倍,取第 4 个点 \alpha_1+7h=7。令
f_1=f(\alpha_1+3h)=2,\quad f_2=f(\alpha_1+7h)=22
此时 f_1< f_2,在连续的 3 个点 \alpha_1+h, \alpha_1+3h, \alpha_1+7h的函数值出现了“两头大、中间小”的情况,则初始搜索区间端点为
a=\alpha_1+h=1,\quad b=\alpha_1+7h=7
黄金分割法是利用区间消去法的原理,通过不断缩小单峰区间长度,即每次迭代都消去一部分不含极小值点的区间,使搜索区间不断缩小,从而逐渐逼近目标函数极小值点的一种优化方法。黄金分割法是直接寻优法,通过直接比较区间上点的函数值的大小来判断区间的取舍。这种方法具有计算简单、收敛速度快等优点。
如图 1(b) 所示,在已确定的单峰区间[a,b]内任取 \alpha_1, \alpha_2两点,计算并比较两点处的函数值 f(\alpha_1)和 f(\alpha_2),可能出现3种情况:
根据上述方法,可在新搜索区间里再取两个新点比较函数值来继续缩小区间,但这样做效率较低,应该考虑利用已经计算过的区间内剩下的那个点。对于以上的 (1)、(2) 两种情况,可以在新搜索区间内取一点 x_3和该区间内剩下的那个点(第 (1) 种情况的 \alpha_1点或第 (2) 种情况的 \alpha_2点)进行函数值的比较来继续缩短搜索区间。而第 (3) 种情况则要取两个新点进行比较,为统一起见,将前面 3 种情况综合为以下两种情况:
黄金分割法就是基于上述原理来选择区间内计算点的位置的,它有以下要求:
\frac lL=\frac{L-l}l\tag{2-1}
令
\lambda=\frac lL
将上式代入式 \fml{2-1},有
\lambda^2+\lambda-1=0\tag{2-2}
求解式 \fml{2-2},得
\lambda=\frac{\sqrt5-1}2\approx0.618
该方法保证每次迭代都以同一比率缩小区间,缩短率为 0.618,故黄金分割法又称为 0.618法。保留的区间长度为整个区间长度的 0.618倍,消去的区间长度为整个区间长度的 0.382倍。
黄金分割法的计算步骤如下:
\begin{align}\alpha_1&=a+0.382(b-a)\\\alpha_2&=a+0.618(b-a)\end{align}
令 f_1=f(\alpha_1), f_2=f(\alpha_2)。RMVL 中提供了一维寻优的函数 rm::fminbnd ,以下展示了一维寻优的例子。
main.cpp
CMakeLists.txt
在项目根目录打开终端,输入
可以看到运行结果