【问题标题】:Fibonacci numbers with memoization runs slow in Python?带有记忆功能的斐波那契数在 Python 中运行缓慢?
【发布时间】:2013-01-28 22:24:04
【问题描述】:
def fib(n):
    if n == 1:
        return 0
    if n == 2:
        return 1
    return fib(n-2) + fib(n-1)


def memo(f):
    cache = {}
    def memoized(n):
        if n not in cache:
            cache[n] = f(n)
        return cache[n]
    return memoized

fib1 = memo(fib)

这段代码在我的笔记本电脑上运行很慢, 但如果我将名称 fib1 更改为 fib,那么一切正常……有人知道原因吗?谢谢!

【问题讨论】:

  • 向您的 fib() 函数添加一些打印内容,看看这些调用对您是否有意义。
  • 一个很好的方法是使用装饰器:ujihisa.blogspot.com/2010/11/…

标签: python


【解决方案1】:

fib 递归到 fib,而不是 fib1。如果记忆的版本有不同的名称,它将不会被使用。

【讨论】:

    【解决方案2】:

    在该代码中,fib 是非记忆函数的名称。 fib1 是你给记忆函数起的名字。但是如果你看到你的代码,你会看到它递归地调用fib 非记忆版本。因此,为什么您没有获得速度优势。

    【讨论】:

      【解决方案3】:

      我同意添加一些您可能会看到问题的打印。你已经非常接近真正得到它了。

      你现在只存储 n ,其中 n 是给 fib1 的参数。在 fib 内部,您正在调用 fib,它不会记住任何先前计算的值。因此,通过在 fib print "fib ", n 中添加打印语句并调用 fib1(4),您将获得以下输出:

      fib 4
      谎言 2
      谎言 3
      纤维 1
      谎言 2

      所以你看到它两次调用 n=2 的 fib。 fib = memo(fib) 更快的原因是因为它实际上是 momoizing,因为您将 fib 重新定义为 memoized 函数。

      【讨论】:

        【解决方案4】:

        在 python 3 中,您可以通过使用非本地 as pointed out here 来实现您的目标。

        def memo(f):
            cache = {}
            def memoized(n):
                nonlocal cache
                if n not in cache:
                    cache[n] = f(n)
                return cache[n]
            return memoized
        

        Python 的 functools 模块提供了完成缓存的装饰器。这些方法有一个限制,因为它们增加了总递归深度的成本。使用闭包的另一种方法允许更深层次的递归。

        def fibonacci(n):
            cache = {0:0,1:1}
            def fib(n):
                if n in cache:
                    return cache[n]
                cache[n] = fib(n-1) + fib(n-2)
                return cache[n]
            return fib(n)
        

        【讨论】:

          猜你喜欢
          • 2019-06-04
          • 1970-01-01
          • 1970-01-01
          • 2015-06-16
          • 2015-10-19
          • 2011-12-14
          • 1970-01-01
          • 2020-08-19
          • 2018-11-09
          相关资源
          最近更新 更多