您的位置:首页 > 其它

算法导论——lec 04 递归式

2014-07-06 08:10 169 查看
  在分治法中,我们经常会将一些问题分解为几个子问题,每个子问题的规模都比原问题要小,而求解子问题相对于解原问题要容易一些。如此递归地分割子问题,就得到更小的子子问题,当问题的规模小到一定的程度的时候,子问题就可以直接求解,当我们获得最下层子问题的解的时候,就可以通过合并子问题的解来获得上层子问题的解,如此类推,最后就能得到原问题的解。

        假设原问题的规模为n,我们利用分治法将原问题分解为a个子问题,每个子问题的规模是原问题的1/b,假设分割原问题的时间为D(n),合并问题的时间为C(n),最后就可以得到如下的递推关系:



那么得到以上的递推关系式以后,我们如何得到问题的时间复杂度T(n)呢?本文就介绍三种解决这类问题的方法。

一、 代换法

代换法是先猜测有某个界存在,然后用数学归纳法来证明这个猜测的正确性。用代换法求解需要两个步骤:猜测解的形式;用数学归纳法找出使解真正有效的常数。

一般先确定其界, 然后根据边界条件确定常数。

例题一:T(n)=2T(⌊n/2⌋)+n

我们猜测其解为T (n) = O(n lg n), 即存在常数c,使得T(n) <= c n lg n

于是,T(n) = 2T(⌊n/2⌋)+n <= 2 * (c ⌊n/2⌋ lg ⌊n/2⌋) + n <= 2 * (c n/2 lg n/2) + n  = cn lgn - cn + n <= c n lg n

当c > 1的时候上式成立。

边界条件:由定义只要找出n0,使得当n >= n0的时候T(n) <= c n lg n即可,

我们取n0 = 2,可证边界条件成立。

代换法的缺点:不存在通用的方法,需要经验。

试探法、 递归树、 类似的先例、 先证明递归式的上下界然后不断缩小不确定性区间等。

例题二:经验——减掉一个低阶项  T (n) = T (⌊n/2⌋) + T (⌈n/2⌉) + 1

我们猜测解为T(n) = O(n),这样就存在正常数c,是得对于n >= n0时有 T(n) <= cn

 T (n) = T (⌊n/2⌋) + T (⌈n/2⌉) + 1 <= c (⌊n/2⌋) + c (⌈n/2⌉) + 1 = cn + 1

与所猜测的解不一致;

这里我们可以考虑减掉一个低阶项,使得T(n) <= cn - b

T (n) = T (⌊n/2⌋) + T (⌈n/2⌉) + 1 <= (c⌊n/2⌋ - b) + (c⌈n/2⌉ - b) + 1 = cn-
2b + 1 <= cn - b

只要b >= 1上式即成立。

例题三:经验——避免陷阱 T(n)=2T(⌊n/2⌋)+n

错误解法:我们猜测解为T(n) = O(n),即存在正常数c和n0,当n >= n0时有 T(n)  <= cn

则,T(n)  = 2T(⌊n/2⌋)+n <= 2 (c *⌊n/2⌋) + n <= cn + n = O(n)

注:此处我们需要的是得到 T(n) <= cn, 而不是 T(n) <= O(n)

正确解法: 我们猜测解为T(n) = O(nlgn), 即存在正常数c和n0,当n >= n0时有 T(n)  <= cnlgn

则 T(n)  = 2T(⌊n/2⌋)+n <= 2 (c * ⌊n/2⌋ lg ⌊n/2⌋) + n <= 2(c * (n/2)lg(n/2)) + n = cnlgn - cn + n <= cnlgn

当c>=1时成立。

例题四:经验——改变变量 T(n)= 2T(⌊sqrt (n)⌋  ) + lgn

我们令m = lgn, 则 n = 2^m, 代入上式得到

T(2^m) = 2 T (⌊2^(m/2)⌋ ) + m

令 H(m) = T(2^m), 则 H(m) = 2 H(m/2) + m

由上题的结论我们知道H(m) = O(m lg m)

则T(n) = T(2^m) = O(m lg m) = O(lgn * lg(lgn))

二、 递归树方法

递归树方法是将递归式转化为树形结构,树中的节点代表在不同递归层次付出的代价,最后利用对和式限界的技术来解出递归式。

递归树方法是一种得到好猜测的直接方法,通常可以容忍小量的不良性(有时候可以忽略顶和底函数等等)。

例题五:T (n) = 3T (⌊n/4⌋) + Θ(n2)

忽略顶和底函数,建立递归式T (n) = 3T(n/4) +cn^2的递归树,常系数c>0,假设n是4的幂次方



对于深度为i的节点,其子问题大小为n/4^i。那么,当n/4^i=1,或是党i= log4 n时子问题的大小即达到1.因此这棵树

有log4 n + 1层.



最后我们验证:取T (n) < dn^2

T(n) <= 3T(⌊n/4⌋) + cn^2 <= (3/16) d n^2 + cn^2 <= d n^2

只要 c <= (13/16)d, 即 d >= (16/13)c.

由于树根就有Ω(n^2)复杂度,所以Ω(n^2)也是T(n)的下界,由此,T (n) = Θ(n^2).

例题六: T (n) = T(n/3) + T(2n/3) + O(n)



树高最多不超过log3/2 n, 所以T (n) = O(cn log3/2 n) = O(n lg n)是一个猜测解。

取T (n) ≤ dn lg n

         T(n)≤ T(n/3) + T(2n/3) + cn ≤ d(n/3)lg(n/3) + d(2n/3)lg(2n/3) + cn 

=(d(n/3)lgn - d(n/3)lg 3) + (d(2n/3)lg n - d(2n/3)lg(3/2))+cn

               =dn lg n - d((n/3) lg 3 + (2n/3) lg(3/2)) + cn =dn lg n - d((n/3) lg 3 + (2n/3) lg 3 - (2n/3)lg 2) + cn 

=dn lg n - dn(lg 3 - 2/3) + cn ≤ dn lg n

只需要d ≥ c/(lg 3 - (2/3))。

递归树并不完整,但是我们可以容忍这些误差。

三、 主方法

主方法是给出求解如下形式的递归式的“食谱”方法

T(n)=aT(n/b)+f(n),其中a≥1,b>1,f(n)是给定的函数。

主定理: 设a ≥ 1 和b > 1 是常数,设f (n) 为一函数,T (n) 由递归式T(n) = aT(n/b) + f(n),对非负整数,其中n/b 指⌊n/b⌋ 或⌈n/b⌉。那么T (n)可能有如下的渐近界



注解:1. 三种情况都把f(n)与n^(logb a )作比较;直觉判断解是由两者中较大的决定;

    2. 第一种情况不仅要f(n)小于n^(logb a ), 而且是多项式小于;第三种情况不仅要f(n)大于n^(logb a ), 而且是多项式大于,而且要满足规则性条件:af(n/b) <= cf(n)

    3. 三种情况没有覆盖所有可能的f(n)

主定理的三种情况对应于递归树中总代价的三种情况:

1. 由所有叶结点的代价决定;

2. 均匀的分布在各层上;

3. 由根结点的代价决定;

引理一:设a≥1,b>1为常数,f (n)为定义在b的正合幂上的非负函数。定义T(n)如下:



其中i是正整数。则有:



引理二: 设a≥1,b>1为常数,f (n)为定义在b的正合幂上的非负函数。函数由下式定义:



对于整数幂,该函数可被渐近限界为:



例题七:T (n) = 9T(n/3) + n

a = 9, b = 3, f (n) = n = O(n^(log3 9 - ε))

适合第一种情况,所以T (n) = Θ(n^2)  

例题八:T (n) = T (2n/3) + 1

a = 1, b = 3/2, f (n) = 1 = (1) = Θ(1)

适合第二种情况, 所以T(n) = Θ(log n)

例题九: T(n) = 3T(n/4) + n lg n

a = 3, b = 4, f (n) = n lg n = Ω(n^(log4 3 + ε))

规则性条件:对足够大的n,af(n/b)=3(n/4)lg(n/4)≤(3/4)nlgn =cf(n), c=3/4

适合第三种情况,所以T(n) = Θ(nlg n)

例题十: T(n) = 2T(n/2) + n lg n

a = 2, b = 2, f(n) = n lg n

n^(logb a) = n,表面上似乎可以选择第三种,其实不然,因为f(n)=nlgn渐进大于,但是并不是多项式大于n。

对此,主方法失效。

         主定理的三种情况没有覆盖所有可能的f(n)。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息