在求解函数最小值时,有一种方法叫做进退法,此法又名成功失败法。它的核心思想是从指定的某个初始值出发,任意选择一个方向和步长,向前试探性地走一步,并求出该点函数值。如果该点函数值优于当前函数值,则向前走一步,并加大探测的步长继续进行探索。否则,则将步长向反方向后退一小步。如此反复探索,直到步长缩小到一定程度为止。最后搜索到的点即为极小值点,对应函数值即为极小值。
该算法可简述如下:
1.给定初始点x0,初始步长Step>0,精度Epsilon>0,k=0,步长因子0<Alpha<1,
Beta>1,并且AlphaBeta不等于1(否则容易陷入死循环),计算初始函数值f0=f(x0)
2.零试算点t=xk+Step,计算ft=f(t)
3.若fk>ft,令k=k+1,xk=t,fk=fx,Step=Steph,转第二步;否则,令Step=-Alpha*Step,转第四步。
4.如果|Step|<Epsilon(停机条件),则停止计算,xk为对应的近似最小极值点。
根据以上算法,我们编写以下程序进行测试。
```python
import math
from matplotlib import pyplot as plt
import numpy as np
#This program is used to test Advance and retreat method in the optimization
def Obj(x):
return math.pow(x,2)-x+2
#Set initial value
Epsilon=0.001 #Set accuracy
Alpha=0.3
Beta=2 #Set factors that affect steps
Step=1 # Set initial value of step
x0=-1 # Set initial point
t=x0
# The core part of the algorithm
Minimum=Obj(t)
result=[]
while abs(Step)>Epsilon:
Ft=Obj(t)
t=t+Step
Fk=Obj(t)
t=t-Step
if Fk<Ft:
t=t+Step
Minimum=Fk
Step=Beta*Step
result.append(Fk)
else:
Step=-Alpha*Step
print("最小值是:",Minimum)
print("迭代次数是{}次".format(len(result)))
plt.plot(result)
plt.title("The Process of iteration")
plt.xlabel("The number of iteration")
plt.ylabel("The function value")
以上程序运行结果为见下图,图形展示了函数值随迭代次数增加的变化。
求得的最优值约为:1.75
以下图形展示了最小值点随着迭代次数的变化情况。
读者可根据自己的需求自行该遍代码进行测试。你可以随意改变Alpha,Beta,Step和初始x0的值,你还可以更换新的优化目标函数,前提是你确认你的函数符合此方法的应用范畴。以加深对该算法的理解。