【问题标题】:Trying to understand this dynamic programming python code?试图理解这个动态编程 python 代码?
【发布时间】:2019-01-08 19:26:35
【问题描述】:

所以我正在阅读这篇优秀的 intro 到动态编程,我正在尝试破译这个 python 代码(斐波那契数的 DP 方法)。我主要用 C/C# 编写代码,所以对我来说理解 Python 有点困难。 所以这是代码:

def fibonacciVal(n):
    memo = [0] * (n+1)
    memo[0], memo[1] = 0, 1
    for i in range(2, n+1):
        memo[i] = memo[i-1] + memo[i-2]
    return memo[n]

所以,我想了解的位是:

  1. memo = [0] * (n+1) : 我知道这是一个数组,但是这里的值是如何存储的,它是如何初始化的?

  2. for i in range(2, n+1): : 为什么循环到 n+1,不应该只循环到 n 吗?

就是这样。我正在尝试自己破译这一点,让有 python 经验的人在这里帮助我会有所帮助。

谢谢!

【问题讨论】:

  • 这是斐波那契的记忆版本,因此它不会重新计算已计算的值。
  • range() 的第二个参数是何时停止。
  • 在您尝试了解动态编程之前,您需要了解实现它的工具。请在此处发布之前查看 Python 基础知识:初始化列表和 range 迭代器。
  • 您可以通过阅读文档在 10 分钟内弄清楚所有这些,通过在调试器中单步执行 5 分钟,或者通过玩 repl 60 秒来解决所有这些问题。如果您不知道其中任何一个,那好吧,但现在您知道了,下次再做。
  • memo 初始化可以缩短为memo = [0, 1] + [0] * (n-2)

标签: python dynamic-programming fibonacci


【解决方案1】:
1: [0]*3 -> [0,0,0] i.e. multiplying an array duplicates it that many times -n+1 in your case-.
2: because you start with [0,1,0,0,0, ...]
 the first index you add to is ^

... the last index you add to will be at n+1 because the first index you added to was 2
[0,1,1,2,3,5,8,13,21,...]

【讨论】:

  • 在阅读答案之前,我只是自己探索了代码,我确实弄明白了。看了你的回答,让我的理解更加坚定了。谢谢!
【解决方案2】:

memo = [0] * (n+1) :我知道这是一个数组,但是这里的值是如何存储的,它是如何初始化的?

当您在 Python 中将一个元素列表乘以一个整数时,它会初始化一个列表,其中该元素重复您指定的多次。例如,对于n=5

memo = [0] * (n+1)

将初始化一个包含 6 个0s 的列表并将其分配给变量memo

>>> n = 5
>>> memo = [0] * (n+1)
>>> memo
[0, 0, 0, 0, 0, 0]

请注意,这种初始化列表的方法适用于不可变对象列表(布尔值、数字、字符串等),但不适用于可变对象(如列表列表或字典列表) .这是因为 Python 将 same 对象n 副本添加到列表中,这通常不是您想要的。 (当您尝试更改列表中的一个可变对象时,它们都会更改,因为它们都是同一个对象的副本。)


for i in range(2, n+1): : 为什么循环到n+1,不应该只循环到n吗?

它确实停在n,因为这是range 函数的内置行为。当您传入两个参数时,它们是它的 startstop 值。 range 函数将返回从start(包括)到stop(不包括)的序列。

如果您改为使用range(2, n),它将停在n-1。 (另一种思考方式是,将 1 加到 n 是让它停在 n 的原因。)

【讨论】:

  • 谢谢!这有助于我更好地理解 Python :)
【解决方案3】:

您使用什么工具来“试图理解”?几个基本的print 命令会有很大帮助:

def fibonacciVal(n):
    memo = [0] * (n+1)
    print("INIT", memo)
    memo[0], memo[1] = 0, 1
    for i in range(2, n+1):
        memo[i] = memo[i-1] + memo[i-2]
        print("TRACE", i, memo)
    return memo[n]

fibonacciVal(5)

输出:

INIT [0, 0, 0, 0, 0, 0]
TRACE 2 [0, 1, 1, 0, 0, 0]
TRACE 3 [0, 1, 1, 2, 0, 0]
TRACE 4 [0, 1, 1, 2, 3, 0]
TRACE 5 [0, 1, 1, 2, 3, 5]

【讨论】:

  • 是的,打印是尝试理解某事的方式。此外,我不知道 python 具有用于 print() 的 INIT 和 TRACE 参数。谢谢你,你丰富了我的知识!
  • 那些是不是参数:它们只是我用来区分输出的文本标签。
【解决方案4】:
   dic ={}
    def febo (n):
    if n in dic:
        return dic[n]
    if n<=2:
        dic[n] = 1
    else:
        dic[n]  = febo(n-1) + febo(n-2)
    return dic[n]

    if __name__ == "__main__":
        n = int(input())
        print(febo(n))

##使用这个

【讨论】:

  • 你能解释一下为什么会这样吗?
猜你喜欢
  • 1970-01-01
  • 2019-08-30
  • 2017-08-10
  • 1970-01-01
  • 2019-02-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-02-17
相关资源
最近更新 更多