斐波那契法(Fibonacci method)又称斐波那契分数法,是一种一维搜索的区间消去法(区间消去法(interval elimination method)求单变量函数无约束极值的较实用的一类直接搜索方法.其特点是在搜索过程中,不断缩小最优点所在的 区间,即通过搜索区间的逐步缩小来确定最优点.)。
【另外】:优化方法除了区间消去法,还有进退法。

斐波那契法(Faboncci Method)


什么是斐波那契查找

斐波那契数列,又称黄金分割数列,指的是这样一个数列:1、1、2、3、5、8、13、21、····,在数学上,斐波那契被递归方法如下定义:F(1)=1,F(2)=1,F(n)=f(n-1)+F(n-2) (n>=2)。该数列越往后相邻的两个数的比值越趋向于黄金比例值(0.618)。
斐波那契查找就是在二分查找的基础上根据斐波那契数列进行分割的。在斐波那契数列找一个等于略大于查找表中元素个数的数F(n),将原查找表扩展为长度为F(n)(如果要补充元素,则补充重复最后一个元素,直到满足F(n)个元素),完成后进行斐波那契分割,即F(n)个元素分割为前半部分F(n-1)个元素,后半部分F(n-2)个元素,找出要查找的元素在那一部分并递归,直到找到。
斐波那契查找的时间复杂度还是O(log 2 n ),但是与二分查找相比,斐波那契查找的优点是它只涉及加法和减法运算,而不用除法,而除法比加减法要占用更多的时间,因此,斐波那契查找的运行时间理论上比二分查找小,但是还是得视具体情况而定。
对于斐波那契数列:1、1、2、3、5、8、13、21、34、55、89……(也可以从0开始),前后两个数字的比值随着数列的增加,越来越接近黄金比值0.618。比如这里的89,把它想象成整个有序表的元素个数,而89是由前面的两个斐波那契数34和55相加之后的和,也就是说把元素个数为89的有序表分成由前55个数据元素组成的前半段和由后34个数据元素组成的后半段,那么前半段元素个数和整个有序表长度的比值就接近黄金比值0.618,假如要查找的元素在前半段,那么继续按照斐波那契数列来看,55 = 34 + 21,所以继续把前半段分成前34个数据元素的前半段和后21个元素的后半段,继续查找,如此反复,直到查找成功或失败,这样就把斐波那契数列应用到查找算法中了。

从图中可以看出,当有序表的元素个数不是斐波那契数列中的某个数字时,需要把有序表的元素个数长度补齐,让它成为斐波那契数列中的一个数值,当然把原有序表截断肯定是不可能的,不然还怎么查找。然后图中标识每次取斐波那契数列中的某个值时(F[k]),都会进行-1操作,这是因为有序表数组位序从0开始的,纯粹是为了迎合位序从0开始。

斐波那契算法步骤

斐波拉契法是一维搜索中压缩比最高的搜索算法。斐波拉契法基于斐波拉契数列产生比例值,斐波拉契数列{Fn}的定义如下:





参考:【python】最优化方法之一维搜索(黄金分割法+斐波那契法)

示例

上面没有看懂,可以结合示例来看

斐波那契数列的代码

F = [1, 1]
while F[-1] < 10000:  #获得小于10000的斐波那契数列F.append(F[-2] + F[-1])
print(F)

结果:

[1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181, 6765, 10946]

斐波那契法一维搜索求极值例题

题目:
求函数A = 4*sinx *(1+cosx) 的最大值(x是角度)
x的范围是0~90°
收敛精度ε = 0.05
代码:

#求函数最大值
from sympy import *a = 0  #区间下限
b = 90  #区间上限
dx = 0.05  #迭代精度def f(x):A = 4*sin(x*pi.evalf()/180)*(1+cos(x*pi.evalf()/180))return AN = (b-a)/dx
#获得斐波那契数列
F = [1, 1]
while F[-1] < N:  #获得小于10000的斐波那契数列F.append(F[-2] + F[-1])
print(F)n = len(F) - 1  # 获取斐波那契数列的长度(计数从0开始)
if n < 3:print("精度过低,无法进行斐波那契一维搜索")
else:passx1 = a + F[n - 2] / F[n] * (b - a)
x2 = a + F[n - 1] / F[n] * (b - a)
t = n
i = 0
while (t > 3):i += 1if f(x1) < f(x2):  # 如果f(x1)<f(x2),则在区间(x1,b)内搜索a = x1x1 = x2x2 = a + F[t - 1] / F[t] * (b - a)elif f(x1) > f(x2):  # 如果f(x1)>f(x2),则在区间(a,x2)内搜索b = x2x2 = x1x1 = a + F[t - 2] / F[t] * (b - a)else:  # 如果f(x1)=f(x2),则在区间(x1,x2)内搜索a = x1b = x2x1 = a + F[t - 2] / F[t] * (b - a)x2 = a + F[t - 1] / F[t] * (b - a)t -= 1#当t<3时
x1 = a + 0.5 * (b - a)  # 斐波那契数列第3项和第2项的比
x2 = x1 + 0.1 * (b - a)  # 偏离一定距离,人工构造的点
if f(x1) < f(x2):  # 如果f(x1)<f(x2),则在区间(x1,b)内搜索a = x1
elif f(x1) > f(x2):  # 如果f(x1)>f(x2),则在区间(a,x2)内搜索b = x2
else:  # 如果f(x1)=f(x2),则在区间(x1,x2)内搜索a = x1b = x2
#打印结果
print(f'迭代第{i}次,迭代精度小于等于{dx},最终的搜索区间为:{min(a, b), max(a, b)}')
print(f'A的最大值:{f((a + b) / 2)}')
print('确定最大值的两端值为:', f(a), f(b))

结果:

[1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584]
迭代第14次,迭代精度小于等于0.05,最终的搜索区间为:(59.97130178171193, 60.035878108471216)
A的最大值:5.19615240230772
确定最大值的两端值为: 5.19615111897465 5.19615038546139

对比黄金分割法:
用黄金分割法(Golden Section Search Method)求函数最大值的python程序

斐波那契法迭代+绘图

from sympy import *
import matplotlib.pyplot as plt  # 绘图模块
from pylab import *  # 绘图辅助模块
#处理中文乱码
plt.rcParams['font.sans-serif'] = ['Microsoft YaHei']def f(x):A = 4*sin(x*pi/180)*(1+cos(x*pi/180))return A# 绘图f(x)函数图像:给定闭区间(绘图间隔),绘图间隔默认为0.05,若区间较小,请自行修改
def drawf(a,b,dx):x = [a + ele * dx for ele in range(0, int((b - a) / dx))]y = [f(ele) for ele in x]plt.figure(1)plt.plot(x, y,color = 'steelblue', # 折线颜色marker = 'o', # 折线图中添加圆点markersize = 0.01, # 点的大小)xlim(a, b)# 添加图形标题plt.title('f(x)函数图像')plt.show()#斐波那契一维搜索
def Fabonaci_search(a,b,dx):N = (b-a)/dx#获得斐波那契数列F = [1, 1]while F[-1] < N:  #获得小于10000的斐波那契数列F.append(F[-2] + F[-1])print(F)n = len(F) - 1  # 获取斐波那契数列的长度(计数从0开始)if n < 3:print("精度过低,无法进行斐波那契一维搜索")else:passx_values = []x_values.append(a)x_values.append(b)x1 = a + F[n - 2] / F[n] * (b - a)x2 = a + F[n - 1] / F[n] * (b - a)t = ni = 0while (t > 3):i += 1if f(x1) < f(x2):  # 如果f(x1)<f(x2),则在区间(x1,b)内搜索a = x1x1 = x2x2 = a + F[t - 1] / F[t] * (b - a)elif f(x1) > f(x2):  # 如果f(x1)>f(x2),则在区间(a,x2)内搜索b = x2x2 = x1x1 = a + F[t - 2] / F[t] * (b - a)else:  # 如果f(x1)=f(x2),则在区间(x1,x2)内搜索a = x1b = x2x1 = a + F[t - 2] / F[t] * (b - a)x2 = a + F[t - 1] / F[t] * (b - a)t -= 1x_values.append(a)x_values.append(x1)x_values.append(x2)x_values.append(b)#当t<3时x1 = a + 0.5 * (b - a)  # 斐波那契数列第3项和第2项的比x2 = x1 + 0.1 * (b - a)  # 偏离一定距离,人工构造的点if f(x1) < f(x2):  # 如果f(x1)<f(x2),则在区间(x1,b)内搜索a = x1elif f(x1) > f(x2):  # 如果f(x1)>f(x2),则在区间(a,x2)内搜索b = x2else:  # 如果f(x1)=f(x2),则在区间(x1,x2)内搜索a = x1b = x2x_values.append(a)x_values.append(x1)x_values.append(x2)x_values.append(b)#打印结果print(f'迭代第{i}次,迭代精度小于等于{dx},最终的搜索区间为:{min(a, b), max(a, b)}')print(f'A的最小值:{f((a + b) / 2)}')print('确定最大值的两端值为:', f(a), f(b))draw(x_values)#绘迭代图
def draw(x_values):#设置绘图风格plt.style.use('ggplot')#处理中文乱码plt.rcParams['font.sans-serif'] = ['Microsoft YaHei']#坐标轴负号的处理plt.rcParams['axes.unicode_minus']=False#横坐标是区间#纵坐标是函数值y_values = []x_values.sort()  #默认列表中的元素从小到大排列for x in x_values:y_values.append(f(x))#绘制折线图plt.plot(x_values,y_values,color = 'steelblue', # 折线颜色marker = 'o', # 折线图中添加圆点markersize = 3, # 点的大小)# 修改x轴和y轴标签plt.xlabel('区间')plt.ylabel('函数值')# 添加图形标题plt.title('Faboncci Method求函数最大值')# 显示图形plt.show()if __name__ == '__main__':a = 0  # 区间下限b = 90  # 区间上限dx = 0.05  # 迭代精度drawf(a,b,dx)  #绘制f(x)函数图像Fabonaci_search(a, b, dx)

结果:

[1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584]
迭代第14次,迭代精度小于等于0.05,最终的搜索区间为:(59.97130178171193, 60.035878108471216)
A的最小值:5.196152402307721
确定最大值的两端值为: 5.196151118974646 5.196150385461393


斐波那契法(Faboncci Method)求函数最大值的Python程序相关推荐

  1. 用等步长分割法(Equal Interval Search Method)求函数最大值的Python程序

    一维搜索方法:一维搜索,又称一维优化,是指求解一维目标函数 f(X) 最优解的过程,分为试探法和插值法.一维搜索最优化是优化方法中最简单.最基本的方法. 常用的方法有:等步长分割法.黄金分割法(0.1 ...

  2. 用黄金分割法(Golden Section Search Method)求函数最大值的python程序

    一维搜索方法:一维搜索,又称一维优化,是指求解一维目标函数 f(X) 最优解的过程,分为试探法和插值法.一维搜索最优化是优化方法中最简单.最基本的方法. 常用的方法有:等步长分割法.黄金分割法(0.1 ...

  3. 二维搜索求函数极值的python程序

    二维搜索,也就是优化两个未知变量,通常将二维搜索转化为一维搜索进行求解. 例题 二维搜索转一维--黄金分割 求函数二维函数A在某区间的最大值 A=( 6 - 2×l + l×cos(θ) ) × l× ...

  4. 遗传算法求函数最大值实验_小知识:什么是遗传算法

    1 什么是遗传算法 遗传算法(GeneticAlgorithm, GA)是模拟达尔文生物进化论的自然选择和遗传学机理的生物进化过程的计算模型,是一种通过模拟自然进化过程搜索最优解的方法. 其主要特点是 ...

  5. 导数求函数最大值和最小值习题

    前置知识:导数求函数最大值和最小值 例1 f(x)=∣x2−3x+2∣f(x)=|x^2-3x+2|f(x)=∣x2−3x+2∣,求f(x)f(x)f(x)在[−10,10][-10,10][−10, ...

  6. 用标准遗传算法求函数最大值

    题:用标准遗传算法求函数f(x)=x+10sin(5x)+7cos(4x)的最大值,其中x的取值范围为[0,10].只是一个有多个局部极值的函数 仿真过程: (1)初始化种群数目NP=50,染色体二进 ...

  7. 读书笔记:求函数梯度的Python代码 numerical_gradient.py ← 斋藤康毅

    由多元函数全部变量的偏导数汇总而成的向量称为梯度(gradient). 梯度指示的方向是各点处的函数值减小最多的方向. 下文给出了求函数  的梯度的 Python 代码. [求函数梯度的Python代 ...

  8. python求三角形面积步骤_通过求三角形面积步入python程序世界.pdf

    通过求三角形面积步入python程序世界 第一章 通过求三角形面积步入 Python 程序世界 本章通过一个求三角形面积的案例带领读者快速进入 Python 世界,案例涉及一些编程必 须知道的内容,包 ...

  9. python 求函数最大值_遗传算法与Python图解

    import matplotlib.pyplot as plt import numpy as np import random import pandas as pd 遗传算法求函数最值 遗传算法的 ...

最新文章

  1. mysql数据库查询缓存_MySQL查询缓存与数据库管理
  2. 谷歌最新论文:从图像中进行3-D目标检测
  3. static关键字的作用?
  4. TeskLink—增加一种需求类型(业务流程)(version1.9.8)
  5. Oracle统计信息不准(谓词越界)造成的性能问题
  6. boost::local_time模块实现自纪元以来的秒数的测试程序
  7. latch.await java有什么作用_java相关:CountDownLatch源码解析之await()
  8. Linux网络配置的基本方法
  9. 十分钟带你理解Kubernetes核心概念
  10. linux java 多线程_Java多线程:Linux多路复用,Java NIO与Netty简述
  11. 汽车底盘线控与动力学域控制技术
  12. 芯片验证学习-设计知识补充学习2-38译码器
  13. excel下拉列表值的设定方式
  14. 德拜方程及matlab实现
  15. 本周最新文献速递20220410
  16. java的发展(8-17新特性整理)
  17. HDU 6441 Find Integer(数论)
  18. A股上市公司财报披露时间
  19. Chrome浏览器设置黑色模式
  20. 取消RadioButton前面小圆圈的方法

热门文章

  1. 【技术综述】最全人脸数据集收录
  2. cif和cip的区别_CIF和CIP到底有什么区别啊?
  3. Windows 7 和 Windows Server 2008 R2 Service Pack 1下载
  4. Mac book air MD231连接DLink的无线路由时连接超时问题
  5. 汇编指令对应的机器码_二进制如何变成汇编语言
  6. 中小企业上网行为管理解决方案
  7. diy 格力空调arduino遥控器
  8. 接口报params province error_Python3+requests搭建接口自动化测试框架
  9. 请你讲讲分布式系统中分布式环境中的数据是如何管理的?
  10. linux切换盘符,挂载Windows盘符