1.模型介绍
斐波那契数列又称为兔子数列,其数值为:1、1、2、3、5、8、13、21、34……在数学上,这一数列以如下递推的方法定义:
F(0)=1,F(1)=1, F(n)=F(n - 1)+F(n - 2)(n ≥ 2,n ∈ N*)。
本篇文章就是将fibonacci数列引入到最优化的一维搜索之中,求解最优化。
2.模型原理
2.1模型的优势
斐波那契数列用于一维探索的单峰函数之中,用于求解最优值的方法。其主要优势为,在第一次迭代的时候求解两个函数值,之后每次迭代只需求解一次。模型定义:
如图所示:根据模型定义给定初始值得出:
(1).当:
(2).当:
当满足第一种条件时,带入化简得出:
,我们只需求出
即可
当满足第二种条件是,带入化简得出:
,我们只需求出
即可。
2.2算法设计步骤
(1)给定初始区间,和最终区间长度(精度)epsilon,求计算函数值的次数n,使
随后计算试探点
计算函数值置k=1
(2) 如果a-b是小于epsion,则返回,否则判断
,若
则转步骤(3),否则转步骤(4)
(3) k自增,令a = x_1, x_1 = x_2,重新计算x_2
,转到步骤(2)
(4)k自增,令b = x_2,x_2 = x_1, 重新计算x_1
,转到步骤(2)
3.代码实现
3.1输入参数和相应方程
from pylab import *
#输入参数
a = float(input("初始左端点"))
b = float(input("初始右端点"))
epsilon = float(input("输入精度"))
#定义参数
def function(a):
fx = str_fx.replace("x", "a") # 所有的"x"换为"%(x)function"
return eval(fx) # 字典类型的格式化字符串,将所有的"x"替换为变量x
init_str = input("请输入一个函数,默认变量为x:\n") # 输入的最初字符串
str_fx = init_str.replace("^", "**") # 将所有的“^"替换为python的幂形式"**"
例:输入 a=-10,b=10,epsilon=0.01
function = x^2 + 5*x + 5
3.2定义Fibonacci数列生成的方法
#生成fibonacci数列,注意这是列表的形式
def fibonacci(n):
if n <= 0:
return [0]
elif n == 1:
return [0, 1]
else:
sequence = [0, 1]
while len(sequence) <= n:
next_number = sequence[-1] + sequence[-2]
sequence.append(next_number)
return sequence
注意生成的为列表
3.3求得n值
#求得n值
n = 2
while (b - a) / epsilon > fibonacci(n)[-1]:
n += 1
print(n)
3.4 定义斐波那契数列搜索方法
#进行Fibonacci优化搜素
def fibonacci_search(a, b):
k = 1
x1 = a + (fibonacci(n - k -1)[-1] / fibonacci(n-k+1)[-1]) * (b - a)
x2 = a + (fibonacci(n - k)[-1] / fibonacci(n-k+1)[-1]) * (b - a)
f1 = function(x1)
f2 = function(x2)
while abs(b - a) > epsilon:
k += 1
if f1 < f2:
b = x2
x2 = x1
f2 = f1
x1 = a + (fibonacci(n - k-1)[-1] / fibonacci(n-k+1)[-1]) * (b - a)
f1 = function(x1)
else:
a = x1
x1 = x2
f1 = f2
x2 = a + (fibonacci(n - k)[-1] / fibonacci(n-k+1)[-1]) * (b - a)
f2 = function(x2)
return (a + b) / 2
#定义绘制我们给定的函数图像模块
3.5 绘制我们所给的函数图像
def drawf(a, b, interp):
x = [a+ele*interp for ele in range(0, int((b-a)/interp))]
y = [function(ele) for ele in x]
# y = [function(x)]
plt.figure(1)
plt.plot(x, y)
xlim(a, b)
#title(color="b")
plt.show()
调用方法绘制出图像 drawf(a,b,0.05),在此我们定义间隔为0.05。
3.6调用定义的方法,得出最优解最优值
result = fibonacci_search(a, b)
print("最小值点的 x 坐标:", result)
print("最小值:", function(result))
drawf(a,b,0.05)
得结果如图所示