Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/292.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 带记忆的斐波那契大O?_Python_Big O_Time Complexity_Memoization - Fatal编程技术网

Python 带记忆的斐波那契大O?

Python 带记忆的斐波那契大O?,python,big-o,time-complexity,memoization,Python,Big O,Time Complexity,Memoization,当我运行这个程序时,它似乎是O(1),因为对于没有记忆的fib来说,它几乎是相当大的数字。如果它是在计算前面的数字,那么它所要做的就是相加,结果是O(1) memo={} def纤维(n): 如果(n

当我运行这个程序时,它似乎是O(1),因为对于没有记忆的fib来说,它几乎是相当大的数字。如果它是在计算前面的数字,那么它所要做的就是相加,结果是O(1)

memo={}
def纤维(n):
如果(n<2):
返回1
如果备忘录中没有n:
备忘录[n]=Fib(n-1)+Fib(n-2)
返回备忘录[n]
我还将其与没有记忆的斐波那契程序进行了比较,这里是从1到40的绘图结果:
我的感觉是仍然是O(n),如果你计算Fin(100),你需要计算所有的数字才能得到100。当然,如果上一次运行已经完成,那么您将把它保存在内存中,但是对于任何您可以想象并运行过上一次执行的数字,我可以想象一个更大的:)


也许你可以说它是O(1)摊销(与java中的ArrayList获得元素的O(1)相同……实际上是O(n),因为你可能需要调整数组的大小,但通常情况并非如此,因此O(1)是一个“可接受”的度量值)。

首先,你的算法的下限是
O(n)
仅仅是因为对于给定的
n
您在字典中填充了
n
值(假设我们正在处理对
Fib
的第一个调用)

另一方面,对于每个
n
函数,您在
Fib
函数中执行的每个操作都是
O(1)
摊销的。总之,你得到的第一次呼叫
Fib
O(n)
摊销的

请注意,对于巨大的
n
而言,这可能高于
O(n)
,因为
不在
O(1)
操作不是
O(1)
(它只是
O(1)
摊销)。
n
必须有多大?不知道,取决于底层的哈希函数。另外,在到达该
n
之前,可能会耗尽内存

现在这显然是以空间(即内存)为代价的,它也变成了
O(n)
。这只是在假设每个整数占用相同的空间量的情况下,不幸的是,Python并不是这样。“整数无限制”方法的结果是,大整数作为数字数组保存在内存中。由于一个数字
n
最多有
log_b(n)+1
个位数(其中
b
是数字系统,例如对于十进制系统
10
,我不确定Python内部使用的是哪一个),我们得到的实际空间复杂度介于
O(n)
O(log_b(n!))
之间

如果我们不在乎这是不是第一次打电话,事情就会变得更复杂。但是只有一点点。您可以轻松地检查
Fib
通常是
O(max(n-k,1))
复杂性,其中
k
是调用时
memo
字典的大小

将其与迭代法进行比较。在这种方法中,始终保留最后两个元素和一个计数器。这样你就得到了时间复杂度和空间复杂度


当然,对于简单的递归斐波那契,时间复杂度是
O(2^n)
O(n)
空间复杂度(由于调用堆栈)。

你不能在恒定的时间内计算斐波那契数。计算和存储记忆值的成本是成本的一部分。请尝试使用1000个元素绘制。我认为您的数据中有错误。@erip如何?我自己没有绘制它,它是用gnuplot完成的,时间是用时间记录的。time()查找保存的引用通常比执行越来越多的计算要快,是的。当然,对于朴素的递归斐波那契,时间复杂度是O(2^n),空间复杂度是O(1)。由于递归调用的堆栈,它实际上是
O(n)
空间。没有尾部递归优化。
memo = {}
def Fib(n):
    if (n < 2):
        return 1
    if not n in memo:
        memo[n] = Fib(n-1) + Fib(n-2)
    return memo[n]