【问题标题】:Inaccurate Large Fibonacci Numbers in PythonPython中不准确的大斐波那契数
【发布时间】:2017-01-03 19:12:25
【问题描述】:

我目前正在实现这个简单的代码,试图使用 Python 2.7 找到斐波那契数列的第 n 个元素:

import numpy as np

def fib(n):
        F = np.empty(n+2) 
        F[1] = 1
        F[0] = 0
        for i in range(2,n+1):
            F[i]=F[i-1]+F[i-2]
        return int(F[n])

这适用于 F fib(100) 给了我 14472334024676220。我认为这可能是由 python 处理整数的方式引起的,但我不知道究竟是什么问题。非常感谢任何帮助!

【问题讨论】:

  • 为什么在这里使用numpy?这是没有意义的,并且可能只会减慢您的速度。我怀疑这是使用np.emptyint 处理小变化的方式引起的问题。
  • 如果您只返回结果,为什么还要将它们存储在列表中?您可以轻松地跟踪函数中的两个数字。
  • 我最近才开始使用 numpy(和 python 相关的..)并且想用它来实现我在过去几天学到的一些命令。应该坚持基本命令。不过,谢谢。
  • @RandomDavis:谢谢,但我一般都在玩斐波那契数列,可能还想返回整个数列 F。但你的建议对于上述函数的目的更有意义,谢谢!

标签: python fibonacci


【解决方案1】:

numpy 数组的默认数据类型是 depending on architecture 64(或 32)位整数。

纯 python 会让你有任意长的整数; numpy 没有。

所以它更像是 numpy 处理整数的方式;纯 python 就可以了。

【讨论】:

  • 非常感谢,这很有道理。我现在使用列表而不是 numpy 并且它可以工作。非常有帮助 +1
  • @berkju:非常欢迎!我相信你知道这是获取大斐波那契数的一种非常低效的方法(除非你需要所有这些数)。
  • 很好地抓住了 32 位 int。传递dtype =np.uint64 使OP 的功能工作。
【解决方案2】:

Python 将在这里完美地处理整数。确实,这就是python的。另一方面,numpy 引入了丑陋,恰好完全没有必要,并且可能会减慢您的速度。您的实施也将需要更多空间。 Python 允许您编写美观、易读的代码。这是 Raymond Hettinger 在 Python 中迭代斐波那契的规范实现:

def fib(n):
    x, y = 0, 1
    for _ in range(n):
        x, y = y, x + y
    return x

即O(n)时间和常数空间。它美观、易读、简洁。只要您有内存将数字存储在机器上,它也会为您提供正确的整数。学会在合适的工具时使用numpy,同样重要的是,学会在不合适的时候使用它。

【讨论】:

    【解决方案3】:

    除非你想生成一个包含直到 Fn 的所有斐波那契数的列表,否则不需要使用列表、numpy 或其他类似的东西,一个简单的循环和 2 个变量就足够了,因为你只需要知道前两个值

    def fib(n):
       Fk, Fk1 = 0, 1
       for _ in range(n):
          Fk, Fk1 = Fk1, Fk+Fk1
       return Fk
    

    当然,使用Fibonacci 数字的数学属性有更好的方法,我们知道有一个matrix 可以为我们提供正确的结果

    import numpy
    
    def fib_matrix(n):
        mat = numpy.matrix( [[1,1],[1,0]], dtype=object) ** n
        return mat[0,1]
    

    我假设他们有一个优化的矩阵 exponentiation 使其比以前的方法更有效。

    使用底层Lucas sequence 的属性可以在没有矩阵的情况下做到这一点,并且与通过平方和相同数量的变量进行取幂同样有效,但起初这有点难以理解一目了然,与第一个示例不同,因为与第二个示例一起,它需要更多的数学知识。

    接近的形式,即具有黄金比例的形式,会更快地为您提供结果,但由于使用浮点运算,存在不准确的风险。

    【讨论】:

      【解决方案4】:

      作为 hiro protagonist 上一个回答的附加词,请注意,如果需要使用 Numpy,您可以通过替换:

      F = np.empty(n+2)
      

      F = np.empty(n+2, dtype=object)
      

      但它只会将计算转移回纯 Python。

      【讨论】:

        猜你喜欢
        • 2014-05-23
        • 1970-01-01
        • 2013-08-03
        • 2013-02-24
        • 2019-12-19
        • 1970-01-01
        • 2014-04-25
        • 1970-01-01
        • 2016-11-28
        相关资源
        最近更新 更多