Fibonacci法与黄金分割法
Fibonacci法与黄金分割法
Fibonacci法与黄金分割法均适用于求解单峰函数的极小值问题。
单峰函数
定义:
设f(x)f(x)f(x)是定义在某实数集合D上的实值函数。
如果存在x0∈Dx_0\in Dx0∈D,对任意的x1,x2∈Dx_1,x_2 \in Dx1,x2∈D,
当x1≤x2≤x0x_1 \leq x_2 \leq x_0x1≤x2≤x0时,有f(x1)≤f(x2)f(x_1)\leq f(x_2)f(x1)≤f(x2)
当x0≤x1≤x2x_0\leq x_1 \leq x_2x0≤x1≤x2时,有f(x1)≥f(x2)f(x_1)\geq f(x_2)f(x1)≥f(x2)
则称f(x)f(x)f(x)为单峰函数(如下图所示,函数图像只有一个峰)
如果在下单峰函数的定义域[a,b][a,b][a,b]中,任取两点a1、b1,a1<b1a_1、b_1,a_1 <b_1a1、b1,a1<b1,对于该函数的极小值点位置可能出现两种情况:
- f(a1)<f(b1)f(a_1) < f(b_1)f(a1)<f(b1),则极小值点xxx位于[a,b1][a,b_1][a,b1]
- f(a1)≥f(b1)f(a_1) \geq f(b_1)f(a1)≥f(b1),则极小值点x位于[a1,b][a_1, b][a1,b]
通过这种方式,我们就可以将含有极小值点的区间不断缩短,当缩短到一定程度时,就可以将区间端点作为极小值点的近似值。
Fibonacci法和黄金分割法就是通过这种思想逐步缩短区间的长度,从而得到极小值点的近似值
Fibonacci法
Fibonacci法通过Fibonacci数列得到每一次迭代的区间缩短率。
算法描述
具体的算法步骤如下:
输入区间[a,b][a,b][a,b],相对精度ϵ\epsilonϵ
根据Fn≥1ϵF_n\geq \frac{1}{\epsilon}Fn≥ϵ1,得到最少的试点个数nnn
令k=0k=0k=0
根据Fibonacci数列确定试点的位置,t1=a+Fn−kFn−k+1(a−b),t2=a+Fn−kFn−k+1(b−a)t_1=a+\frac{F_{n-k}}{F_{n-k+1}}(a-b),t_2=a+\frac{F_{n-k}}{F_{n-k+1}}(b-a)t1=a+Fn−k+1Fn−k(a−b),t2=a+Fn−k+1Fn−k(b−a)
比较两试点的函数值大小。若f(t1)<f(t2)f(t_1)<f(t_2)f(t1)<f(t2),令a=a,b=t2,t2=t1a=a,b=t_2,t_2=t_1a=a,b=t2,t2=t1;若f(t1)≥f(t2)f(t_1)\geq f(t_2)f(t1)≥f(t2),令a=t1,b=b,t1=t2a=t_1,b=b,t_1=t_2a=t1,b=b,t1=t2;k=k+1k=k+1k=k+1,转至第4步,直到k=n−1k=n-1k=n−1,转第6步
当k=n−1k=n-1k=n−1时,有t1=t2=12(a+b)t_1=t_2=\frac{1}{2}(a+b)t1=t2=21(a+b),此时无法根据f(t1)、f(t2)f(t_1)、f(t_2)f(t1)、f(t2)的大小确定极小值点,为此,取
t1=12(a+b)t2=a+(12+δ)(b−a),常取δ=0.01t_{1}=\frac{1}{2}(a+b) \\ t_2 = a + (\frac{1}{2}+\delta)(b-a),常取\delta=0.01 \\ t1=21(a+b)t2=a+(21+δ)(b−a),常取δ=0.01
比较f(t1)、f(t2)f(t_1)、f(t_2)f(t1)、f(t2)的值,将较小者作为函数极小值的近似值,对应的点作为近似的极小值点。算法结束。
注意,虽然算法迭代了n次,但使用的试点数并不是2n个,而是n个。因为在每一迭代中,有一个试点是上一步迭代中得到的。
具体实例及代码实现
对于函数f(t)=et+e−t,t∈[−1,1]f(t)=e^t+e^{-t},t\in [-1,1]f(t)=et+e−t,t∈[−1,1]。其函数图像如下:
代码实现如下:
import math
"""
Fibonacci法求解凸函数极小值
"""
class Fibonacci():def __init__(self, a0, b0, delta, epsilon):""":param a0: 区间左端点:param b0: 区间右端点:param delta: 相对精度:param epsilon: 误差"""self.delta = deltaself.a0 = a0self.b0 = b0self.epsilon = epsilondef Fib(self, n):"""生成长度为n的Fibonacci数列:param n: Fibonacci数列长度:return: Fibonacci数列"""result = []result.append(0)result.append(1)result.append(1)for i in range(3, n + 1):result.append(result[i - 1] + result[i - 2])return resultdef get_n(self, delta):"""根据给定的相对精度返回所需Fibonacci数列的长度:param delta: 相对精度:return: Fibonacci数列的长度"""F = self.Fib(1000)for i in range(1, len(F)):if F[i] > 1 / delta or F[i] == 1 / delta:print("试点数为{0}".format(i))return iprint("the length of fib is low")def fibonacci(self):"""求解凸函数的极小值点以及极小值,并检验是否满足相对精度:return: 函数的极小值点和极小值,以及检验结果"""a = self.a0b = self.b0n = self.get_n(delta)F = self.Fib(n)for i in range(1, n - 1):t1 = b + (F[n - i] / F[n - i + 1]) * (a - b)t2 = a + (F[n - i] / F[n - i + 1]) * (b - a)if f(t1) < f(t2):b = t2t2 = t1else:a = t1t1 = t2t1 = 0.5 * (a + b)t2 = a + (0.5 + epsilon) * (b - a)if f(t1) < f(t2):b = t2print("最优点为{0},最优值为{1}".format(t1, f(t1)))print("检验结果为{0}".format((b - a) / (self.b0 - self.a0) < self.delta))else:a = t1print("最优点为{0},最优值为{1}".format(t2, f(t2)))print("检验结果为{0}".format((b - a) / (self.b0 - self.a0) < self.delta))# 待求解的下单峰函数
def f(t):""":param t: 自变量:return: 待求解函数"""return math.exp(t) + math.exp(-t)# return -1 * ((math.sin(t) ** 6) * (math.tan(1 - t) * math.exp(30 * t)))if __name__ == "__main__":# 实例演练delta = 0.00001epsilon = 0.01a0 = 0b0 = 1fib = Fibonacci(a0, b0, delta, epsilon)fib.fibonacci()
求解结果为:
黄金分割法
黄金分割法的思路与Fibonacci法类似,只不过Fibonacci法的区间缩短率是通过Fibonacci数列来得到。而黄金分割法的区间缩短率是固定的,为0.618.
算法描述
具体实例及代码实现
对于下单峰函数f(t)=sin(t)6tan(1−t)e30t,t∈[0,1]f(t)=sin(t)^6tan(1-t)e^{30t},t\in [0,1]f(t)=sin(t)6tan(1−t)e30t,t∈[0,1];其函数图像为:
具体代码如下:
import math
"""
黄金分割法法求解凸函数极小值
"""
class GoldenSection():def __init__(self, a0, b0, delta, epsilon):"""初始化参数:param a0: 区间左端点:param b0: 区间右端点:param delta: 相对精度:param epsilon:"""self.delta = deltaself.a0 = a0self.b0 = b0self.epsilon = epsilondef solve(self):"""求解凸函数的 满足相对精度 极小值点以及极小值:return: 函数的极小值点和极小值"""a = self.a0b = self.b0# n = self.get_n(delta)while True:if (b - a) / (self.b0 - self.a0) < self.delta:breakt1 = a + 0.382 * (b - a)t2 = a + 0.618 * (b - a)if f(t1) < f(t2):b = t2else:a = t1t1 = 0.5 * (a + b)t2 = a + (0.5 + epsilon) * (b - a)if f(t1) < f(t2):print("最优点为{0},最优值为{1}".format(t1, f(t1)))else:print("最优点为{0},最优值为{1}".format(t2, f(t2)))# 待求解的上单峰函数
def f(t):""":param t: 自变量:return: 待求解函数"""#return math.exp(t) + math.exp(-t)return -1 * ((math.sin(t) ** 6) * (math.tan(1 - t) * math.exp(30 * t))) # 乘以-1,转换为下单峰函数if __name__ == "__main__":# 实例演练delta = 0.00001a0 = -1b0 = 1epsilon = 0.01fib = GoldenSection(a0, b0, delta, epsilon)fib.solve()
求解结果为:
Fibonacci法与黄金分割法相关推荐
- 【最优化】C++实现0.618法、Fibonacci法、二分法
参考课本:最优化方法 - 孙文瑜等 根据课本P110算法3.2.1(0.618法计算步骤)编写C++代码,例题为P137第4题(1)(2) 0.618法代码 #include <iostream ...
- Fibonacci法的matlab实现
推导过程看百度文库中的ppt Fibonacci法的基本步骤: 测试程序:try_FibonacciOpt.m clear all;clc %% the original conditions f=@ ...
- 【最优化】黄金分割法与Fibonacci法
(1)黄金分割法(0.618法) 基本思想: 它通过对试探点的函数值进行比较,使得包含极小点的区间不断缩短,当区间长度小到精度范围之内时,可以粗略地认为区间上各点的函数值均接近于极小值. 算 ...
- matlab三点确定抛物线,[转]matlab编写的进退法,黄金分割法,抛物线法(二次插值法),wolfe不精确一维搜索...
这是我最优化方法课程的编程作业,贴来和大家分享,后续会继续发来一些最优化的程序.. 以下程序由matlab编写 程序简介 jintuifa.m 进退法,用于确定下单峰区间.根据最优化方法(天津大学出版 ...
- matlab用进退法写程序,matlab编写的进退法,黄金分割法,抛物线法(二次插值法),wolfe不精确一维搜索...
这是我最优化方法课程的编程作业,贴来和大家分享,后续会继续发来一些最优化的程序.. 以下程序由matlab编写 程序简介 jintuifa.m 进退法,用于确定下单峰区间.根据最优化方法(天津大学出版 ...
- matlab无约束最优化的一般算法流程图及代码(进退法,Fibonacci,黄金分割法,抛物线法)
本实验中函数用单独function计算 %函数[fx]=f(x) function fx=f(x) fx=x.^4-4*x.^3-6*x.^2-16*x+4; 一,进退法,Fibonacci,黄金分割 ...
- 黄金分割点c的坐标c语言,黄金分割法与进退法的C语言程序
<黄金分割法与进退法的C语言程序>由会员分享,可在线阅读,更多相关<黄金分割法与进退法的C语言程序(5页珍藏版)>请在人人文库网上搜索. 1.基本思想:对f(x)任选一个初始点 ...
- 用等步长分割法(Equal Interval Search Method)求函数最大值的Python程序
一维搜索方法:一维搜索,又称一维优化,是指求解一维目标函数 f(X) 最优解的过程,分为试探法和插值法.一维搜索最优化是优化方法中最简单.最基本的方法. 常用的方法有:等步长分割法.黄金分割法(0.1 ...
- 黄金分割(0.618)法求解函数极值(附代码)
目录 黄金分割法 迭代公式 算法步骤: 例题 C++代码: 黄金分割法也称为中外比,指把一条线段分割为两部分,使其中一部分与全长之比等于另一部分与这部分之比.其比值是一个无理数,取其前三位数字的近似值 ...
- 用黄金分割法(Golden Section Search Method)求函数最大值的python程序
一维搜索方法:一维搜索,又称一维优化,是指求解一维目标函数 f(X) 最优解的过程,分为试探法和插值法.一维搜索最优化是优化方法中最简单.最基本的方法. 常用的方法有:等步长分割法.黄金分割法(0.1 ...
最新文章
- golang内存分配概述
- 【c语言】蓝桥杯算法训练 十进制数转八进制数
- crontab中运行python程序出错,提示ImportError: No module named解决全过程
- 有关OCS监控软件安装在windows上, 服务端显示乱码的问题
- 二、先在SD卡上启动U-boot,再烧写新的U-boot进Nandflash
- c语言动态规划公共字符串,最长公共子串 C语言 动态规划
- Python通过Zabbix API获得数据
- python中html.replace()_HTML DOM replace() 方法
- 【报告分享】2020情趣用品线上消费趋势报告.pdf(附下载链接)
- JavaScript实现按字典排序进行md5加密, 以及个人在小程序也可以实现
- centos 并发请求数_jmeter 实战分析并发、RPS、RT 公式换算
- Python3 色情图片识别
- 华三路由交换配置命令_h3c路由器配置命令
- EventBus源码解析 1
- 计算机实验报告双绞线制作,双绞线的制作实验报告.docx
- 2022视力矫正展,2022青少年眼睛健康展会,护眼产品展
- 教程篇(6.4) 05. 集成 ❀ SD-WAN ❀ Fortinet 网络安全架构师 NSE7
- Mac连接网线能够接收微信消息,浏览器不能访问网页
- 软件项目管理作业(一):如何学好项目管理课程
- 金闪PDF编辑器:Windows端最好用的免费PDF编辑器上线了
热门文章
- xcrun: error: invalid active developer path (/Library/Developer/CommandLineTools), missing xcrun at:
- 牛郎织女都见面,而你却在吃狗粮---男士星座脱单指南
- 针对rnnoise vad 分享
- 某云盘下载工具(IDM,Aria2)速度测试
- opencv物体识别-识别水果
- tenacity 报错_Tenacity
- 对象存储 Object Storage
- Java 实战:桌球小游戏
- 基于SSM的医院管理系统
- 华为HCNA综合实验