Algorithm 递归的复杂性T(n)=T(n-1)+;T(n-2)和#x2B;N

Algorithm 递归的复杂性T(n)=T(n-1)+;T(n-2)和#x2B;N,algorithm,recursion,time-complexity,recurrence,Algorithm,Recursion,Time Complexity,Recurrence,递归T(n)=T(n-1)+T(n-2)+n的复杂度是多少? 我用树的方法做的,我得到的答案是n*2^n。 是这样吗 此递归公式的时间复杂度取决于输入大小,其中每个调用生成一个调用的二叉树(如您所述) 如果T(n)总共进行2n调用,则替换: T(n)=T(n-1)+T(n-2)+n T(n)=O(2

递归T(n)=T(n-1)+T(n-2)+n的复杂度是多少? 我用树的方法做的,我得到的答案是n*2^n。
是这样吗

此递归公式的时间复杂度取决于输入大小,其中每个调用生成一个调用的二叉树(如您所述)

如果
T(n)
总共进行
2
n
调用,则替换:

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

T(n)=O(2
)+O(2
)+O(2


O(2
n
好的,找到了一支笔和一些纸

是的,你是对的(尽管会有更严格的界限)

不过,我想给出完整性的证明(不使用树方法,使用基于替代和推理的方法,我觉得更有趣)

我们有
T(n)=T(n-1)+T(n-2)+n
。因为我们需要找到一个上界,让我们制作一个更简单的函数
T'(n)=2T(n-1)+m
,其中
m
是一个常数。显然,对于
m>=n
,此函数将“大于”T(n)
(参见脚注),因此,如果我们能找到此函数的上界,则原始函数有一个上界(只要我们当时选择常数
m
大于
n
)。它还具有易于建模的优点

让我们来看一下
T'(n)
的一些行为:

最后一个等式是在任意次数的
k
迭代(
0=n
)之后,按照逻辑级数得出的,我们第一次“调用”
T
,我们设置了
m=n
。也就是说,我们已经将常数设置为通过级数可以获得的最大值
n
。让我们看看得到了什么:

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

最后一点,由于所有
m>=n
T'
都比
T
大,我们有一个
T'
的上限,我们知道
T
也必须服从这个上限,所以
T
也是
O(n*2^n)
,就像你发现的那样

请指出任何错误,我可能把一些字母弄错了

编辑:真的,你还想证明
T'
实际上比我们所说的
T
大-但这很简单,你可以通过一个常数和一个常数和另一个递减序列和这一事实很容易说服自己。

假设我们通过替换任何一个rec来获得这个函数的上下界ursive与另一个通话:

我们可以重复替换以推导其复杂性(假设停止条件为
n=1
):

令人惊讶的是,没有系数
n
!因此:


进行一些数值试验以确认:

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)
的最紧界限

我们可以对
T(n)
进行更一般的形式替换:

通过匹配具有相同增长率的术语(
O(n)
对于
c
O(1)
对于
d
),我们可以立即推断
c=-1,d=0

我们可以忽略比指数项小得多的3。除以a*b^n

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

您可以通过上面对数数字图的梯度来测量和确认
b
的值:
b=10^0.209=1.618…
。也可以确认绑定值:
10^0.151=1.415…
vs
sqrt(2)=1.414…
,类似地
10^0.301=1.999…
vs
2


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

这听起来很合理(无法严格检查)。为了将来参考,您应该包括您的工作(因此有一些您工作的证据),这也可能是最好的问题——即使只是因为他们在那里有甜美的数学标记。我已经编辑了我的答案,包括了上下限和更详细的数值测试。希望这能使论点更具说服力。iirc这应该进一步简化,能够
T(n)=O(c^n)
既然
n=O(2^n)
。你的意思是总的复杂度可以是
O(c^n)
而不是
O(n*2n)
?如果是这样的话,
c
会是什么呢?Tnx对于upvote=)你提供的链接不是完全相同的问题-最后一个术语是常量
c
,而不是
n
。但是最终的结果还是一样的。是的,这就是为什么我发布了一个不同的答案,暗示链接的相似性。然而,我现在看到了你的答案,介于我发布的结果和你的结果之间。你觉得怎么样?@meowgoes狗我介于你的结果和我的结果之间,但更像你的字体,+1。谢谢你的投票。
T'(n) = c0*2^n + m*2^n - m
T'(n) = c0*2^n + n*2^n - n
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