有很多关于解决T(n)= T(n-1)+ T(n-2)+ O(n ^ k)或T(n)= a形式的递归关系的例子和教程T(n / b)+ O(n ^ k),具有一些初始条件。
我试图解决这两种形式混合的递归关系,其中: T(n)= T(n-2)+ 2 T(n / 2),初始条件T(0)= 1,T(1)= 1。
有关如何解决此递归关系的任何提示?
由于
答案 0 :(得分:0)
使用替换方法。好吧,让我备份一下。替换方法用于评估猜测,但猜测必须来自某个地方。我没有太多关于这种复发的直觉,所以我会写下我的过程。我发现查看序列的开头很有用。
>>> def T(n):
... if n==0: return 1
... elif n==1: return 1
... else: return T(n-2) + 2*T(n//2)
...
>>> [T(n) for n in range(50)]
[1, 1, 3, 3, 9, 9, 15, 15, 33, 33, 51, 51, 81, 81, 111, 111, 177, 177, 243, 243, 345, 345, 447, 447, 609, 609, 771, 771, 993, 993, 1215, 1215, 1569, 1569, 1923, 1923, 2409, 2409, 2895, 2895, 3585, 3585, 4275, 4275, 5169, 5169, 6063, 6063, 7281, 7281]
数字之间的差距越来越大,所以它可能是超线性的。另一方面,它看起来似乎并没有变得足够快以达到指数级。也许这是多项式。那么T(2*n)/T(n)
应该是有限的,但似乎并没有发生。
>>> T(20)/T(10)
6.764705882352941
>>> T(50)/T(25)
13.955665024630543
>>> T(100)/T(50)
20.954112248499822
>>> T(200)/T(100)
35.791368360763435
这是我开始替换看看会发生什么的点。我们试试2^n
。
T(0) = 1 <= 2^0 = 1: check
T(1) = 1 <= 2^1 = 2: check
T(n) = T(n-2) + 2*T(n/2)
<= 2^(n-2) + 2*2^(n/2)
= 2^(n-2) + 2^(1 + n/2): FAIL,
因为n=2
的命题意味着2^0 + 2^2 <= 2^2
。这会在我身上产生一种“错过”的感觉,因为1 + n/2
不接近n
,除非n
很小。实际上,绑定4^n
确实有效。
T(0) = 1 <= 4^0 = 1: check
T(1) = 1 <= 4^1 = 4: check
T(n) = T(n-2) + 2*T(n/2)
<= 4^(n-2) + 4^(1/2 + n/2)
<= 4^(n-2) + 4^(n - 1/2) [since n - 1/2 >= 1/2 + n/2 for n >= 2]
<= 4^n: check
有一些更简单的方法来“修复”绑定,但c^n
形式的任何内容仍然是错误的想法:使用4^(n + O(1))
作为一个只是浪费限制在4^(n/2 + O(1))
,这种直觉是由上面的实际数字支持的。
让我说明当我们尝试用多项式约束时会发生什么,比如n^100
。
T(n) = T(n-2) + 2*T(n/2)
<= (n-2)^100 + 2*(n/2)^100
= n^100 + O(n^99) + 2^-99*n^100 + O(n^99): FAIL,
因为n^100
上的常量略大。这表明绑定不起作用。
在多项式和指数之间进入的一种更简单的方法是 quasipolynomial ,如n^log(n)
或n^(log(n)^2)
。让我们试试前者。
T(n) = T(n-2) + 2*T(n/2)
<= n^log(n-2) + 2*((n/2)^log(n/2))
= n^(log(n) + log(1 - 2/n)) + 2*((n/2)^(log(n) - 1))
= n^(log(n) + ln(1 - 2/n)/ln(2)) + 2*((n/2)^(log(n) - 1))
<= n^(log(n) - 2/(n*ln(2))) + n^(log(n) - 1) / 2^(log(n) - 2)
[by log(1 + x) <= x, often written 1 + x <= e^x]
= n^log(n) / n^(2/(n*ln(2))) + 4*n^log(n) / n^2
这看起来很有希望。对于所有c > 0
,n -> infinity
的{{1}}限制为n^(c/n) = e^(c*ln(n)/n)
,并且从上方接近。我们所要做的就是得到一个约束1
,然后我们就定了。写
n^(2/(n*ln(2))) >= 1/(1 - 4/n^2) = 1 + 4/n^2 + O(1/n^4)
看起来好像复杂性是 quasipolynomial ,尽管这个证明有一些松散的结局。我证明渐近需要为所有n^(c/n) = e^(c*ln(n)/n) >= 1 + c*ln(n)/n >= 1 + 4/n^2 + O(1/n^4) for large n.
保留的语句,除非它们不会,因此常量需要修补。这些细节往往是乏味的,没有指导意义。我们也应该证明一个匹配的下限,但上面的分析非常紧,我相信这可以做到。不过,我会在这里停下来。