最优化-斐波那契数列(fibonacci)优化方法 算法原理及代码实现

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模型的优势

斐波那契数列用于一维探索的单峰函数之中,用于求解最优值的方法。其主要优势为,在第一次迭代的时候求解两个函数值,之后每次迭代只需求解一次。模型定义:

如图所示:根据模型定义给定初始值a_k,b_k得出:

\lambda_k = a_k + \frac{f_n-k-1}{f_n-k+1}*(b_k-a_k)

\mu_k = a_k +\frac{f_n-k}{f_n-k+1}*(b_k-a_k)

(1).当f(\lambda_k)<f(\mu_k):  a_{k+1} = a_k ,b_{k+1} = \mu_k

(2).当f(\lambda_k) \geq f(\mu_k):a_{k+1}=\lambda_k,b_{k+1} = b_k:

当满足第一种条件时,带入化简得出:

\mu_{k+1} = \lambda_k,我们只需求出\lambda_{k+1}即可

当满足第二种条件是,带入化简得出:

\lambda_{k+1} = \mu_k,我们只需求出\mu_{k+1}即可。

2.2算法设计步骤

(1)给定初始区间[a_n,b_n],和最终区间长度(精度)epsilon,求计算函数值的次数n,使

F_n\geqslant (b_n-a_n)/epsilon

随后计算试探点x_1,x_2

x_1 = a_k + \frac{f_n-k-1}{f_n-k+1}*(b_k-a_k)

x_2 = a_k +\frac{f_n-k}{f_n-k+1}*(b_k-a_k)

计算函数值f(x_1),f(x_2)置k=1

(2) 如果a-b是小于epsion,则返回\frac{a+b}{2},否则判断f(x_1),f(x_2)的大小,若f(x_1)>f(x_2)则转步骤(3),否则转步骤(4)

(3) k自增,令a = x_1, x_1 = x_2,重新计算x_2

x_2 = a_k +\frac{f_n-k}{f_n-k+1}*(b_k-a_k),转到步骤(2)

(4)k自增,令b = x_2,x_2 = x_1, 重新计算x_1

x_1 = a_k + \frac{f_n-k-1}{f_n-k+1}*(b_k-a_k),转到步骤(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)

得结果如图所示

  • 6
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值