斐波那契法(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. SPI FLASH 分区情况
  2. java 泛型集合应用_Java泛型集合的应用和方法
  3. SAP屏幕设计器专题:编写控件代码(三)
  4. C/C++中善用大括号
  5. 正则匹配减号_2020年这些正则应该被收藏(64条)
  6. Redis Sentinel机制与用法说明【转】
  7. 2的10次方-1的python表达式_第1章 语言处理与Python
  8. JavaWeb如何学?
  9. 基于android的个人记账系统,android平台的个人记账系统的设计与实现.docx
  10. 经典场景试题,测试用例编写
  11. 怎么把程序内部坐标转为屏幕坐标_各位老大,如何把屏幕坐标转换成游戏的坐标...
  12. 小程序获取oppenid
  13. 5分钟让你整明白美国金融危机爆发的原因
  14. 三个表内连接查询创建视图
  15. ardupilot 中关键坐标系
  16. JS 调用打印机,打印HTML中的部分内容
  17. 软件测试就业前景怎么样?
  18. 高德地图添加安全密钥
  19. 安装maven时安照说明配置环境变量JAVA_HOME
  20. 认认真真推荐10个顶级技术公众号

热门文章

  1. soap linux php 拓展,linux carry php Soap 扩展
  2. Unite’17 开发者大会经验分享
  3. windows系统下采用向日葵远程连接Ubuntu系统的服务器
  4. sql 把某一列拼接_关于Sql写法的一些规范
  5. LaTeX不显示页码_Ubuntu(20.04 LTS) OS 下 VS Code + LaTeX 快速配置指南
  6. win7 xp win8 系统驱动安装说明,万能驱动下
  7. golang websocket绑定用户_Golang(五)最佳Web框架对比
  8. 该如何使用MySQL的存储过程?
  9. 【建议收藏】刷完这9套Java面试题,2021金三银四跳槽面试30K没问题
  10. ArcGIS转KML