如何解决递归关系的特殊情况

时间:2014-04-22 18:03:00

标签: algorithm complexity-theory relation recurrence

有很多关于解决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。

有关如何解决此递归关系的任何提示?

由于

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 > 0n -> 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. 保留的语句,除非它们不会,因此常量需要修补。这些细节往往是乏味的,没有指导意义。我们也应该证明一个匹配的下限,但上面的分析非常紧,我相信这可以做到。不过,我会在这里停下来。