涉及到知识点
- 进退法
- 黄金分割法
进退法
基本思想:从一点出发,按一定的步长,试图确定出函数值呈现出”高-低-高“的三个点。一个方向不成功,就退回来沿相反方向搜索。
思路很简单,python很好写。
以函数
python实现代码如下:
def func(x):
y = pow(x,2) - 7*x + 10
return y
# 进退法AR:f为计算函数,a为初始点,h为步长
def AR(f,a,h):
a1 = a
a2 = a + h
# 前进运算
if f(a2) < f(a1):
a3 = a2 + h
while 1:
# 满足“高低高”,返回a1,a3
if f(a2) < f(a3):
return a1, a3
# 否则步长乘2,继续前进
elif f(a2) >= f(a3):
h = 2*h
a1 = a2
a2 = a3
a3 = a2 + h
# 后退运算
elif f(a2) > f(a1):
# 步长反号,交换a1,a2位置
h = -h
a1,a2 = a2,a1
a3 = a2 + h
while 1:
# 满足“高低高”,返回a1,a3
if f(a2) < f(a3):
return a1, a3
# 否则步长乘2, 继续后退
elif f(a2) >= f(a3):
h = 2*h
a1 = a2
a2 = a3
a3 = a2 + h
黄金分割法
黄金分割法(Golden Section Method)又称为0.618法,是用于在单峰函数区间上求极小的一种方法。
基本思想:通过取试探点和进行函数值比较,使包含极小点的搜索区间不断减少,当区间长度缩短到一定程度时,就得到函数极小点的近似值。
python实现代码如下:
r = 0.618034 # 黄金分割率
e = 0.0001 # 精度
# 黄金分割法Gold,f为计算函数,a,b为搜索区间,e为精度
def Gold(f,a,b,e):
# 计算左右试探点
a1 = a + (1-r)*(b-a)
a2 = a + r*(b-a)
# 循环搜索
while 1:
# 极小点在[a1,b],消去[a,a1]
if f(a1) > f(a2):
a = a1
a1 = a2
a2 = a + r*(b-a)
# 极小点在[a,a2],消去[a2,b]
elif f(a1) < f(a2):
b = a2
a2 = a1
a1 = a + (1-r)*(b-a)
# 如果b-a在精度内,那么得到极小点
if(b-a) <= e:
minPoint = (a+b)/2
return minPoint
进退法确定搜素区间+黄金分割法求极小值完整过程代码:
def func(x):
y = pow(x,2) - 7*x + 10
return y
# 进退法AR:f为计算函数,a为初始点,h为步长
def AR(f,a,h):
a1 = a
a2 = a + h
# 前进运算
if f(a2) < f(a1):
a3 = a2 + h
while 1:
# 满足“高低高”,返回a1,a3
if f(a2) < f(a3):
return a1, a3
# 否则步长乘2,继续前进
elif f(a2) >= f(a3):
h = 2*h
a1 = a2
a2 = a3
a3 = a2 + h
# 后退运算
elif f(a2) > f(a1):
# 步长反号,交换a1,a2位置
h = -h
a1,a2 = a2,a1
a3 = a2 + h
while 1:
# 满足“高低高”,返回a1,a3
if f(a2) < f(a3):
return a1, a3
# 否则步长乘2, 继续后退
elif f(a2) >= f(a3):
h = 2*h
a1 = a2
a2 = a3
a3 = a2 + h
r = 0.618034 # 黄金分割率
e = 0.0001 # 精度
# 黄金分割法Gold,f为计算函数,a,b为搜索区间,e为精度
def Gold(f,a,b,e):
# 计算左右试探点
a1 = a + (1-r)*(b-a)
a2 = a + r*(b-a)
# 循环搜索
while 1:
# 极小点在[a1,b],消去[a,a1]
if f(a1) > f(a2):
a = a1
a1 = a2
a2 = a + r*(b-a)
# 极小点在[a,a2],消去[a2,b]
elif f(a1) < f(a2):
b = a2
a2 = a1
a1 = a + (1-r)*(b-a)
# 如果b-a在精度内,那么得到极小点
if(b-a) <= e:
minPoint = (a+b)/2
return minPoint
s = AR(func,0,1)
print("进退法求得搜索区间为:",s)
a = s[0]
b = s[1]
m = Gold(func,a,b,e)
print("极小点为:%.3f" %m)
print("最小值为:%.3f" %func(m))