在最优化问题中,为求函数的最小值点,通常分两步进行:首先确定函数的搜索区间;然后不断缩短区间,直至区间收缩为一点为止。为此,本文介绍一个搜索区间的方法——成功-失败算法。
成功-失败算法又称为进退法,是试探法的一种,用以求单峰函数的搜索区间。那么什么是单峰函数?
单峰函数:
下面给出单峰函数的定义:
设是定义在[a,b]上的函数,若:
- ∃x*
[a,b],是
在[a,b]上的最小点;
- 若对∀
,
,a
b,满足:
- 若x*
,则
- 若x*
,则
则称是为[a,b]上的单峰函数。
那下面来看看那些图像可以称之为单峰函数:
![](https://img-blog.csdnimg.cn/30b5bcf182e94196af084f18058ddf77.png)
![](https://img-blog.csdnimg.cn/56e0c9df5f034c908460aa316788b474.png)
![](https://img-blog.csdnimg.cn/0b88529491794e5eb5979cb95c8fec3f.png)
再来一个非单峰的函数来对比一下:
![](https://img-blog.csdnimg.cn/bcaf7d3171ff4b168dac30798e575367.png)
这下好理解什么是单峰函数了吧。
成功-失败法:
由单峰函数的性质可知,函数值在极小点左边严格下降,在右边严格上升。那么我们的基本思想就可以确定了:从某个初始点出发,沿函数值下降的方向前进,直至满足终止条件。
算法步骤:
步骤1:选取初始点 x∈R , 初始步长h > 0及精度ε> 0,
步骤2:计算比较:=
和
:=
.
步骤3:若,搜索成功, 转步骤4;否则,搜索失败,转步骤5。
步骤4:令 x:= x + h,:=
,h:=2h,转步骤 2。
步骤5:判断|h|ε ? 若|h|
ε,停止迭代,x* = x ;否则令h:=-h/4,转步骤 2。
缺点:效率低。优点:可以求搜索区间。
例题分析:
下面我们通过一道例题加深一下对步骤的理解:
解:
取初始点x=,步长h=
=
=
,
=
=1,
,搜索成功,步长加倍;
计算=
=
=0,
,搜索成功,步长加倍;
计算=
=
=22,
,搜索失败,停止迭代;
得到搜索区间为【x+h,x+7h】= [0,3]
算法代码:
'''
成功-失败算法(进退算法)
2023.10.8
'''
def fun(x):
return x**3-2*x+1
def run(x,h,ε):
count = 0
left = x
right = x+h
while abs(h) > ε:
count = count + 1
print("第{}次搜索".format(count))
if fun(left) > fun(right):
print("前进,步长加倍")
h = h *2
temp = right
right = left+3*h
left = temp
print("得到的新的区间为:[%f,%f]" %(left,right))
else:
print("后退,步长缩短")
h = -0.25*h
temp = left
right = left+3*h
left = temp +h
print("得到的新的区间为:[%f,%f]" %(left,right))
return left,right
run(-0.5,0.5,0.00001)
用该代码所运算的结果为:
'''
第27次搜索
前进,步长加倍
得到的新的区间为:[0.816650,0.818604]
第28次搜索
后退,步长缩短
得到的新的区间为:[0.816406,0.815918]
第29次搜索
后退,步长缩短
得到的新的区间为:[0.816467,0.816589]
第30次搜索
后退,步长缩短
得到的新的区间为:[0.816452,0.816422]
第31次搜索
后退,步长缩短
得到的新的区间为:[0.816456,0.816463]
总结:
成功-失败算法虽然可以用来求函数在某区间上的最小值点,但相对来说,该算法效率比较低,但是该算法无需计算梯度,是一种简单直接的方法,所以在对计算速度要求不是很高的时候,也是一种不错的选择。
(行文中若有纰漏,希望大家指正)