递归的复杂度T(n)= T(n-1)+ T(n-2)+ n?

时间:2017-08-26 10:13:42

标签: algorithm recursion time-complexity recurrence

递归的复杂性T(n)= T(n-1)+ T(n-2)+ n? 我使用树方法完成它,我得到答案为n * 2 ^ n。 这是正确的吗?

3 个答案:

答案 0 :(得分:2)

这个递归公式的时间复杂度取决于输入大小,其中每个调用产生一个二元树调用(如你所提到的tree approach)。

T(n)总共调用2 n ,您可以替换:

T(n) = T(n-1) + T(n-2) + n

T(n) = O(2 n-1 ) + O(2 n-2 ) + O(2 n功能 )

O(2 n )

答案 1 :(得分:2)

假设我们通过将另一个递归调用替换为另一个递归调用来获取此函数的 upper lower 边界:

enter image description here

我们可以反复替代以得出它们的复杂性(假设停止条件是ceil()):

enter image description here

enter image description here

令人惊讶的是,没有n = 1的因素!因此:

  

enter image description here

要确认的一些数值测试:

n

enter image description here

在对数刻度图上,所有三个函数都显示为线性,这意味着它们是指数,即N R(N) T(N) S(N) ------------------------------------- 10 1.14E+02 3.64E+02 2.04E+03 15 7.49E+02 4.16E+03 6.55E+04 20 4.07E+03 4.63E+04 2.10E+06 25 2.45E+04 5.14E+05 6.71E+07 30 1.31E+05 5.70E+06 2.15E+09 35 7.86E+05 6.32E+07 6.87E+10 40 4.19E+06 7.01E+08 2.20E+12 45 2.52E+07 7.78E+09 7.04E+13 50 1.34E+08 8.63E+10 2.25E+15 55 8.05E+08 9.57E+11 7.21E+16 60 4.29E+09 1.06E+13 2.31E+18 65 2.58E+10 1.18E+14 7.38E+19 而不是O(a^n)

如果您不相信这些结果,我建议您编写简单的程序来自行测试。

  

我们可以做得更好吗?即找到O(n * a^n)可能的最严格的界限?

我们可以为T(n)进行更多通用格式替换:

enter image description here

我们可以通过匹配具有相同增长率的字词(T(n)c = -1, d = 0O(n)c来立即推断O(1)

enter image description here

我们可以忽略比指数项小得多的3。除以d

![enter image description here

我们可以丢弃较小的根,因为它的大小小于1,这意味着它将缩小而不是增长,因此渐近无关。因此:

  

enter image description here

您可以从上面的对数数字图的渐变中测量并确认a * b^n的值:b。还可以确认绑定值:b = 10^0.209 = 1.618... vs 10^0.151 = 1.415...,类似sqrt(2) = 1.414... vs 10^0.301 = 1.999...

请注意,基础2与之前获得的边界(1.618)一致。

答案 2 :(得分:0)

好的,设法找到一支笔和一些纸。

是的,你是对的(尽管存在更严格的界限)。

我想提供完整性证明(不使用树方法,使用基于替换和推理的方法,我觉得更有趣)。

我们有T(n) = T(n-1) + T(n-2) + n。由于我们需要找到一个上限,让我们创建一个更简单的函数T'(n) = 2T(n-1) + m,其中m是一个常量。显然,对于m >= n,此函数将比T(n)“更大”(参见脚注),因此如果我们可以找到此函数的上限,则我们有一个原始上限(如只要我们选择常量m,使其大于n。它还具有更容易建模的优势!

让我们来看看T'(n)

的一些行为
T'(n) = 2T'(n-1) +  m
      = 4T'(n-2) + 3m
      = 8T'(n-3) + 7m
      = ...
      = 2^k T'(n-k) + (2^k - 1)m

最后一个等式是按照我们在任意数k次迭代(0 <= k <= n)之后所看到的逻辑进展来进行的。

如果我们现在延伸到迭代的末尾,那就是n = k,我们有:

T'(n) = 2^n T'(0) + (2^n - 1)m

如果我们让T'(0)成为常量c0,那么我们就有T'的上限:

T'(n) = c0*2^n + m*2^n - m

c0m保持常量,所以我们还不能对它们做太多的事情。

现在我们说T'对于所有T而言比m >= n“更大”,所以我们说第一次“呼叫”T时,我们设置{ {1}}。也就是说,我们将常量设置为m = n可以通过进展的最大值。让我们看看我们得到了什么:

n

因此T'(n) = c0*2^n + n*2^n - n 。完美!

最后一次触摸,因为O(n*2^n)对于所有T'而言比T“更大”,并且我们有m >= n的上限,我们知道T' 1}}也必须遵守上限,所以T也是T,就像你找到的一样。

请指出任何错误,我可能会在某处混淆一些信件!

编辑:真的,你也想证明O(n*2^n)实际上比T'更大,就像我们说的那样 - 但这是微不足道的,你可以轻易地通过一个总和来说服自己不断增加,而另一个则减少一系列。

相关问题