递归函数的渐近时间复杂度
Posted
技术标签:
【中文标题】递归函数的渐近时间复杂度【英文标题】:Asymptotic time complexity of Recursive function 【发布时间】:2013-09-30 03:36:29 【问题描述】:我被要求开发一个递归函数,然后分析渐近时间复杂度。
f(N) = 0, if N < N1
f(N1) = C1
f(N)= A1 + M1*f(M2*N/D1 - S1) Op M3*f(M4*N/D2 - S2), if N > N1
我们假设:
s1 = s2 = 0
m2 = m4 = 1
d1 = d2 > 1
//the user enters N1 C1 A1 M1 M2 M3 M4 D1 D2 S1 S2 and then ARG
int Recursion_Plus(int ARG)
if (ARG < n1)
return 0;
else if(ARG == n1)
return c1;
else if(ARG > n1 )
return a1 + m1
*
Recursion_Plus(m2*ARG/d1 - s1)
+
m3*Recursion_Plus(m4*ARG/d2 - s2);
我已经针对讲师的程序测试了我的递归函数,它的工作原理完全相同,所以我继续进行分析,但我遇到了困难。
我正在努力解决这个问题,所以请多多包涵。
我对部分解决方案的尝试:
2 次比较(如果 ARG
a1 & m1 & m3 无关紧要,因为它们在递归调用之外
a1 + m1*_ = 1 个时间单位(加法)
m1*_ = 1 单位时间(乘法)
将 2 个递归调用加在一起是 1 个时间单位
m3*_ = 1 单位时间(乘法)
根据我们给出的说明,两个递归函数每次都将使用相同的 # 调用,并且递归函数调用的每个连续数字都将小于上一个,因为 d1 = d2 > 1。
因此,ARG 越大(与 n1 相比),达到基本情况所需的时间越长,结果也会越大。那么算法需要 O(ARG) 时间?
如果有人能告诉我我是否走在正确的轨道上,我将不胜感激。谢谢
【问题讨论】:
【参考方案1】:递归调用是:
f(N)= A1 + M1*f(M2*N/D1 - S1) Op M3*f(M4*N/D2 - S2), if N > N1
与
s1 = s2 = 0
m2 = m4 = 1
d1 = d2 > 1
我们有
f(N)= A1 + M1*f(N/D1) Op M3*f(N/D1), if N > N1
递归调用是获得渐近复杂度的关键点,剩下的就是“只是”常量。
所以重点是找到 T 比如:
T(n)=2*T(n/D)
一旦你找到 T(n),你就有了 Recursion_Plus 的调用次数,因为我们讨论的是渐近复杂度,所以不必关心最后一次调用(即n<N1
)。
现在都是关于数学的,我不会在这里描述一个正式的解决方案,但只要有一点直觉,你就可以得到结果。
每次调用 T 都会引发 2 次 T 调用,但以 # 除以 D,然后以 # 除以 D^2 进行 4 次调用 ...
复杂度是2^(logD(n))
(与logD(n)=ln(N)/ln(D) )
特殊情况:with D=2, the complexity is n
【讨论】:
【参考方案2】:请注意,在每个递归级别上,您都会调用该函数两次。因此,从第一次调用 c1
开始,它会调用自己两次:c21
和 c22
,然后从每个调用中它再次调用自己两次:c211
、c212
、c221
和 c222
等. 在每个递归级别,您有两次以上的调用。在第 N 级,您将有 2^n 次调用,因此它是指数级复杂度。
编辑:对不起,我的错。我没有注意到那里的论点存在分歧。在那种情况下不会有N个级别,只会有logd(N),其余的就像Tony写的那样。
【讨论】:
嗯?这个函数f(0) = 1, f(n) = f(n/2) + f(n/2)
怎么样。首先,与f(0) = 1, f(n) = 2f(n/2)
(不同 的渐近复杂度吗?此外,您是否声称它是指数级的?这些陈述都不是真的。以上是关于递归函数的渐近时间复杂度的主要内容,如果未能解决你的问题,请参考以下文章
算法 -- 数据结构和算法的关系算法定义和特性算法设计的要求算法效率的度量方法函数的渐近增长算法时间复杂度 算法空间复杂度