【问题标题】:Fibonacci memoization order of execution斐波那契记忆执行顺序
【发布时间】:2018-11-09 00:11:36
【问题描述】:

以下代码是使用记忆化的斐波那契数列。但我不明白算法中的执行顺序。如果我们做dynamic_fib(4),它将计算dynamic_fib(3) + dynamic_fib(2)。左侧先调用,然后计算dynamic_fib(2) + dynamic_fib(1)。但是在计算 dynamic_fib(3) 时,当我们没有像 C 中的 &dic[n] 那样将结果保存到字典的内存地址时,dynamic_fib(2) 的缓存答案是如何向上传播以被重用的。

我认为应该发生的是,dynamic_fib(2) 的答案已经消失,因为它只存在于那个堆栈中。所以在计算dynamic_fib(4)的时候还要重新计算dynamic_fib(2)

我错过了什么吗?

def dynamic_fib(n):
    return fibonacci(n, {})

def fibonacci(n, dic):
    if n == 0 or n == 1:
        return n

    if not dic.get(n, False):
        dic[n] = fibonacci(n-1, dic) + fibonacci(n-2, dic)

    return dic[n]

【问题讨论】:

    标签: dynamic-programming fibonacci memoization


    【解决方案1】:

    函数dynamic_fib(调用一次)只是将工作委托给fibonacci,真正的工作在那里完成。在fibonacci 中,您有字典dic,它用于在计算后保存函数的值。所以,对于每个值(2-n),当你第一次调用函数fibonacci时,它会计算结果,但它也会将它存储在字典中,以便下次我们要求它时,我们已经有了它,而且我们不需要再次遍历整棵树。所以复杂度是线性的,O(n)

    【讨论】:

    • 我知道你描述的是带记忆的普通斐波那契。
    • 但是,在这种情况下,我想知道的是,在 fibonacci(3,{}) 中,计算 fibonacci(2,{}) + fibonacci(1,{}),它调用 fibonacci (1,{}) + 斐波那契(0,{})。所以这会返回 1 并将其保存到 dic[2] = 1 中。但是,由于 dic[2] 仅存在于当前堆栈中,并且在传播时消失了,所以 dic 不是空字典吗?
    • 在 C 编程中,这是有道理的,因为您可以在参数中传入字典指针,我们可以对其进行操作。但是在 Python 中,简单地操作参数就是在玩副本而不是修改实际的字典?
    • dic 作为可变字典传递,类似于对可变对象的引用,因此每次 dic 都包含更新的状态。检查docs.python.org/3/faq/…
    • @MattChoi 你现在确信了吗?
    猜你喜欢
    • 2011-12-14
    • 2019-06-04
    • 2015-10-19
    • 2021-11-17
    • 2021-05-21
    • 2018-10-11
    • 2015-06-16
    • 2021-08-17
    • 1970-01-01
    相关资源
    最近更新 更多