这是一个简单的C程序:
int f(int n) {
if(n==0 || n==1) {
return n;
} else {
return 2 * f(n - 1) + 3 * f(n - 2);
}
}
该程序具有指数时间复杂度。您可以在此f(5)
函数调用图中看到这一点:
我想表明该函数仅使用递推方程具有指数复杂性,而不是通过绘制图表和计算函数调用的数量。
我想出的复发关系是
T(n)= T(n-1)+ T(n-2)+ c
扩展提供
T(n)= 2T(n-2)+ T(n-3)+ 2c
但是,我不知道如何进一步解决这个问题。我该如何解决这种递归关系?
答案 0 :(得分:7)
对于初学者来说,你的复发需要某种基本情况,因为否则当你达到0时它是未定义的。为简单起见,让我们说
T(0)= a
T(1)= a + b
T(n + 2)= T(n)+ T(n + 1)+ c
让我们开始扩展此重复的前几个术语:
这里有一个非常有趣的模式。让我们分别看一下a,b和c项的系数。一个术语的系数遵循模式
1,1,2,3,5,8,13,21,......
这是Fibonacci系列,偏移了一步。 b项的系数是
0,1,1,2,3,5,8,13 ......
完全斐波那契系列。最后,我们来看看c术语:
嗯,这看起来并不熟悉。但是,如果我们将其与条款并排放置,我们会看到:0,0,1,2,4,7,12,20 ......
a:1,1,2,3,5,8,13,21 ......
b:0,0,1,2,4,7,12,20 ......
请注意,b条款是减去一个条款的所有条款!换句话说,它是斐波纳契系列向前移动一步,但每个项减去1。
根据这些观察结果,我们可以推测以下情况属实:
T(n)= aF n + 1 + bF n + c(F n + 1 - 1)
我们现在可以通过归纳来证明这一点。作为我们的基本案例:
T(0)= a = 1a + 0b + 0c = 1a + 0b +(1 - 1)c = aF 1 + bF 0 + c(F 1 - 1)
T(1)= a + b = 1a + 1b + 0c = 1a + 1b +(1 - 1)c = aF 2 + bF 1 + c (F 2 - 1)
对于我们的归纳步骤,让我们假设对于某些自然数n,
T(n)= aF n + 1 + bF n + c(F n + 1 - 1)
那个
T(n + 1)= aF n + 2 + bF n + 1 + c(F n + 2 - 1)
然后我们有了
T(n + 2)= T(n)+ T(n + 1)+ c
= aF n + 1 + bF n + c(F n + 1 - 1)+ aF n + 2 + bF n + 1 + c(F n + 2 - 1)+ c
= a(F n + 1 + F n + 2 )+ b(F n + F n + 1 )+ c(F n + 1 + F n + 2 - 2 + 1)
= aF n + 3 + bF n + 2 + c(F n + 3 - 1)
这样就完成了归纳,所以我们的公式必须正确!
那么这与效率有何关系?好吧,Binet's formula告诉我们F n =Θ(φ n ),其中φ是golden ratio(约1.61)。这意味着
T(n)= aF n + 1 + bF n + c(F n + 1 - 1)=aΘ(φ n )+bΘ(φ n )+cΘ(φ n )=Θ((a + b + c)φ n功能)
因此,只要a + b + c≠0,运行时间为Θ(φ n ),这是指数。
希望这有帮助!