Bootstrap

0403用代入法求解递归式-分治策略-算法导论第三版

1.代入法求解递归式步骤

1.1 求解步骤

代入法求解递归式分两步:

  1. 猜测解的形式。
  2. 用数学归纳法求出解中的常数,并证明解是正确的。

当讲归纳假设应用与较小的值时,我们将猜测的解带入函数,因此得名“导入法”。

我们可以用代入法为递归式建立上界或下界。例如,我们确定下面递归式的上界;

T ( n ) = 2 T ( ⌊ n 2 ⌋ ) + n T(n)=2T(\lfloor \frac{n}{2}\rfloor)+n T(n)=2T(⌊2n⌋)+n (4.19)

该递归式与递归式4.3和4.4相似,我们猜测其解为 T ( n ) = O ( n lg ⁡ n ) T(n)=\Omicron(n\lg n) T(n)=O(nlgn)。代入法要求证明,恰当选择常数 c > 0 c\gt 0 c>0,可有 T ( n ) ≤ c n lg ⁡ n T(n)\le cn\lg n T(n)cnlgn
证明: 假设次上界对所有正数 m < n 成立,特别是对 m = ⌊ n 2 ⌋ 有 T ( ⌊ n 2 ⌋ ) ≤ c ⌊ n 2 ⌋ lg ⁡ ⌊ n 2 ⌋ , 带入递归式 T ( n ) ≤ 2 c ⌊ n 2 ⌋ lg ⁡ ⌊ n 2 ⌋ + n ≤ c n lg ⁡ n 2 + n ≤ c n lg ⁡ n − c n + n 证明:\\ 假设次上界对所有正数m\lt n成立, 特别是对m=\lfloor \frac{n}{2}\rfloor\\ 有T(\lfloor\frac{n}{2}\rfloor)\le c \lfloor \frac{n}{2}\rfloor\lg\lfloor\frac{n}{2}\rfloor,带入递归式\\ T(n)\le 2c \lfloor \frac{n}{2}\rfloor\lg\lfloor\frac{n}{2}\rfloor+n\\ \le cn\lg\frac{n}{2}+n \le cn\lg n-cn+n 证明:假设次上界对所有正数m<n成立,特别是对m=2nT(⌊2n⌋)c2nlg2n,带入递归式T(n)2c2nlg2n+ncnlg2n+ncnlgncn+n
其中,只要 c ≥ 1 c\ge 1 c1,最后一步都会成立。

1.2 边界条件

数学归纳法要求我们证明解在边界条件下也成立。对于递归式4.19,我们必须证明,通过选择足够大的常数c,可以使得上界 T ( n ) ≤ c n lg ⁡ n T(n)\le cn\lg n T(n)cnlgn对边界条件也成立。这一要求有时可能引起问题。例如为了方便讨论,假设 T ( 1 ) = 1 T(1)=1 T(1)=1是递归式唯一的边界条件。
对于 n = 1 ,边界条件 T ( n ) ≤ c n lg ⁡ n 推到出 T ( 1 ) ≤ 0 与 T ( 1 ) = 1 相矛盾 对于n=1,边界条件T(n)\le cn\lg n推到出\\ T(1)\le 0\\ 与T(1)=1相矛盾 对于n=1,边界条件T(n)cnlgn推到出T(1)0T(1)=1相矛盾
对特定的边界条件证明归纳假设成立,可以适当修改。比如,在递归式4.19中,渐进符号仅要求我们对 n ≥ n 0 ,时证明 T ( n ) ≤ c n lg ⁡ n n\ge n_0,时证明T(n)\le cn\lg n nn0,时证明T(n)cnlgn,其中 n 0 n_0 n0是我们可以自己选择的常数。我们保留麻烦的边界条件 T ( 1 ) = 1 T(1)=1 T(1)=1,当将其从归纳证明中移除。首先观察到对于 n > 3 n\gt 3 n>3,递归式并不直接依赖T(1),因此将证明中的基本情况T(1)替换为T(2)和T(3)。
证明: 令 n 0 = 2 , 则 T ( 2 ) = 4 , T ( 3 ) = 5 对于某个常数 c ≥ 1 , T ( n ) ≤ c n lg ⁡ n 选择足够大的 c 满足 T ( 2 ) ≤ c 2 lg ⁡ 2 , T ( 3 ) ≤ c 3 lg ⁡ 3 当 c ≤ 2 时保证不等式成立 证明:\\ 令n_0=2,则T(2)=4,T(3)=5\\ 对于某个常数c\ge 1,T(n)\le cn\lg n\\ 选择足够大的c满足T(2)\le c2\lg2,T(3)\le c3\lg3\\ 当c\le 2时保证不等式成立 证明:n0=2,T(2)=4,T(3)=5对于某个常数c1,T(n)cnlgn选择足够大的c满足T(2)c2lg2,T(3)c3lg3c2时保证不等式成立
对于我们所要讨论的大多数递归式来说,扩展边界条件使归纳假设对较小的n成立,是一种简单直接的方法。

2.做出好的猜测

不存在通用的方法来猜解递归式的正确解。猜测解需要经验和创造力。可以使用一些启发式的方法来帮助完成猜解。

如果要求解的递归式与你曾见过的递归式相似,那么猜测一个类似的解是合理的。例如,考虑如下递归式:

T ( n ) = 2 T ( ⌊ n 2 ⌋ + 17 ) + n T(n)=2T(\lfloor \frac{n}{2}\rfloor+17)+n T(n)=2T(⌊2n+17)+n

增加的17不会显著的影响递归式的解。当n较大时, ⌊ n 2 ⌋ 和 ⌊ n 2 ⌋ + 17 \lfloor\frac{n}{2}\rfloor和\lfloor\frac{n}{2}\rfloor+17 2n2n+17差距不大,都是接近n的一半。因此猜测 T ( n ) = O ( n lg ⁡ n ) T(n)=\Omicron(n\lg n) T(n)=O(nlgn).

另一种做出好的猜测的方法是先证明递归式较松的上界和下界,然后缩小不确定的范围。例如,对递归式4.19,我们可以从下界 T ( n ) = Ω ( n ) T(n)=\Omega(n) T(n)=Ω(n)开始,因为递归式中包含n这一项,还可以证明一个初始上界 T ( n ) = O ( n 2 ) T(n)=\Omicron(n^2) T(n)=O(n2)。然后我们可以逐渐降低上界,提升下界,直至收敛到渐进紧确界 T ( n ) = Θ ( n lg ⁡ n ) T(n)=\Theta(n\lg n) T(n)=Θ(nlgn)

3.微妙的细节

有时你可能正确的猜测出了递归式的渐进界,但莫名其妙地在归纳证明时失败了。问题常常出在归纳假设不够强,无法证出准确的界。当遇到这种障碍时,如果修改猜测,将它减去一个低阶项,数学证明常常能顺利进行。

考虑如下递归式

T ( n ) = T ( ⌊ n 2 ⌋ ) + T ( ⌈ n 2 ⌉ ) + 1 T(n)=T(\lfloor\frac{n}{2}\rfloor)+T(\lceil\frac{n}{2}\rceil)+1 T(n)=T(⌊2n⌋)+T(⌈2n⌉)+1

我们猜测 T ( n ) = O ( n ) T(n)=\Omicron(n) T(n)=O(n),并尝试证明对某个恰当选出的常数c, T ( n ) ≤ c n T(n)\le cn T(n)cn成立。猜测带入递归式,得到

T ( n ) ≤ c ⌊ n 2 ⌋ + c ⌈ n 2 ⌉ + 1 ≤ c n + 1 T(n)\le c\lfloor\frac{n}{2}\rfloor+c\lceil\frac{n}{2}\rceil+1\le cn+1 T(n)c2n+c2n+1cn+1

这并不意味着对任意c都有 T ( n ) ≤ c n T(n)\le cn T(n)cn。我们可能忍不住尝试猜测一个更大的界,比如 T ( n ) = O ( n 2 ) T(n)=\Omicron(n^2) T(n)=O(n2)。虽然从这个猜测也能推出结果,但原来的猜测 T ( n ) = O ( n ) T(n)=\Omicron(n) T(n)=O(n)是正确的。然而为了证明它是正确是,我们必须做出更强的归纳假设。

直觉上,我们的猜测是接近正确的:只差一个常数1,一个低阶项。但是,除非我们证明与归纳假设严格一致的形式,否则数学归纳法还是会失败。克服这个困难的方法是从先前的猜测中减去一个低阶项。新的猜测为 T ( n ) ≤ c n + d T(n)\le cn+d T(n)cn+d,d是大于等于0的一个常数,带入递归式有:


T ( n ) ≤ ( c ⌊ n 2 ⌋ − d ) + c ( ⌈ n 2 ⌉ − d ) + 1 ≤ c n − 2 d + 1 ≤ c n − d T(n)\le (c\lfloor\frac{n}{2}\rfloor-d)+c(\lceil\frac{n}{2}\rceil-d)+1\\ \le cn-2d+1\le cn-d T(n)(c2nd)+c(⌈2nd)+1cn2d+1cnd
只要 d ≤ 1 d\le 1 d1,此式成立。与以前一样,我们必须选择走够大的c来处理边界条件。

你可能发现减去一个低阶项的想法与直觉是相悖的。比较,如果证明上界失败了,就应该将猜测增加而不是减少,更松的界难道不是更容易证明吗?不一定!当利用归纳法证明一个上界时,实际上一个更弱的上界可能会更困难一些,因为为了证明一个更弱的上界,我们在归纳证明中也必须使用同样更弱的界。在当前例子中,当递归式中包含超过一个递归项时,将猜测的界减去衣蛾低阶项意味着每次对每个递归项都减去一个低阶项。在上例中,我们将去常数d两次。我们以不等式 T ( n ) ≤ c n − 2 d + 1 T(n)\le cn-2d+1 T(n)cn2d+1结束,可以很容易找到一个d值,使得 c n − 2 d + 1 ≤ c n − d cn-2d+1\le cn-d cn2d+1cnd

4.避免陷阱

使用渐进符号很容易出错。例如,在递归式4.19中,我们可能错误地证明 T ( n ) = O ( n ) T(n)=\Omicron(n) T(n)=O(n),猜测 T ( n ) ≤ c n T(n)\le cn T(n)cn
证明: T ( n ) ≤ 2 ( c ⌊ n 2 ⌋ ) + n ≤ c n + n = O ( n ) 证明:\\ T(n)\le 2(c\lfloor\frac{n}{2}\rfloor)+n\le cn+n=\Omicron(n) 证明:T(n)2(c2n⌋)+ncn+n=O(n)

因为c是常数。错误在于我们并未证出与归纳假设 严格一致的形式,即 T ( n ) ≤ c n T(n)\le cn T(n)cn。因此,当要证明 T ( n ) = O ( n ) T(n)=\Omicron(n) T(n)=O(n)时,需要显示的证出 T ( n ) ≤ c n T(n)\le cn T(n)cn

5.改变变量

有时,一个小的代数运算可以将一个未知的递归式变成你熟悉的形式。例如,考虑如下递归式:

T ( n ) = 2 T ( ⌊ n ⌋ ) + lg ⁡ n T(n)=2T(\lfloor\sqrt{n}\rfloor)+\lg n T(n)=2T(⌊n ⌋)+lgn

我们可以通过改变变量来简化它。为避免舍入误差问题,只考虑 n \sqrt{n} n 是整数的情况。
令 m = lg ⁡ n , 得 T ( 2 m ) = 2 T ( 2 m / 2 ) + m 令m=\lg n,得\\ T(2^m)=2T(2^{m/2})+m m=lgn,T(2m)=2T(2m/2)+m
重新命名 S ( m ) = T ( 2 m ) S(m)=T(2^m) S(m)=T(2m)得到新的递归式

S ( m ) = 2 S ( m / 2 ) + m S(m)=2S(m/2)+m S(m)=2S(m/2)+m

这个递归式与4.19非常像,具有相同的解: S ( m ) = O ( m lg ⁡ m ) S(m)=\Omicron(m\lg m) S(m)=O(mlgm).在从 S ( m ) 转换会 T ( n ) S(m)转换会T(n) S(m)转换会T(n)

T ( n ) = T ( 2 m ) = S ( m ) = O ( m lg ⁡ m ) = O ( lg ⁡ n lg ⁡ lg ⁡ n ) T(n)=T(2^m)=S(m)=\Omicron(m\lg m)=\Omicron(\lg n\lg\lg n) T(n)=T(2m)=S(m)=O(mlgm)=O(lgnlglgn)

结语

欢迎小伙伴一起学习交流,需要啥工具或者有啥问题随时联系我。

❓QQ:806797785

⭐️源代码地址:https://gitee.com/gaogzhen/algorithm

[1]算法导论(原书第三版)/(美)科尔曼(Cormen, T.H.)等著;殷建平等译 [M].北京:机械工业出版社,2013.1(2021.1重印).p47-50

;