算法导论——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)。
假设原问题的规模为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)。
相关文章推荐
- 算法导论 求解递归式的总结
- Introduction to Algorithms 算法导论 第4章 递归式 学习笔记及习题解答
- 第4章 算法导论之递归式笔记
- 算法导论——lec 11 动态规划及应用
- 算法导论——lec 12 平摊分析与优先队列
- 算法导论——lec 11 动态规划及应用
- 算法导论——lec 10 图的基本算法及应用
- 用代入法求解递归式里的”微妙细节“【算法导论P49】
- 算法导论笔记:13-04红黑树以及其他平衡树
- 算法导论——lec 12 平摊分析与优先队列
- 【算法导论】递归式求解的三种方法
- [算法导论] 递归式求解的三种方法
- 算法导论之线性时间排序(2)
- 红黑树的删除(算法导论)
- [算法导论]22:基本图结构
- 算法导论实验四_分治法求平面上的最小点对
- 排序及相关三(算法导论PS1-3)
- 【算法导论】邻接表存储的拓扑排序
- 【算法学习笔记】04.C++中结构体定义练习(bign初步)
- 【算法导论】最小生成树之Kruskal法