递归式的渐进分析

分治策略

  • 分解(Divide)步骤将问题划分为一些子问题,子问题的形式与原问题一样,只是规模更小
  • 解决(Conquer)步骤递归地求解出子问题。如果子问题的规模足够小,则停止递归,直接求解。
  • 合并(Combine)步骤将子问题的解组合成原问题的解
  • 当子问题足够大,需要递归求解时,我们称之为递归情况(recursive case)。
  • 当子问题变得足够小不再需要递归时,我们说递归已经“触底”,进入了基本情况(base case)

递归式求解的三种方法

  • 代入法:我们猜测一个界,然后用数学归纳法证明这个界是正确的
  • 递归树法:将递归式转换为一棵树,其结点表示不同层次的递归调用产生的代价。然后采用边界和技术来求解递归式。
  • 主定理法

代入法求解递归式

  • 步骤
    • 1.猜测解的形式。
    • 2.用数学归纳法求出解中的常数,并证明解是正确的。
  • 例子:归并排序\(T(n) =2T(\frac{n}{2})+n\)
    • 猜测\(T(n) = O(n\log n)\)\(T(n) \le cn\log n\)
    • \(T(n)=2T(\frac{n}{2})+n \le 2c\frac{n}{2} \log \frac{n}{2}+n=cn(\log n-\log 2)+n=cn\log n-(c-1)n\)
    • 若要满足,\(T(n)<=c\log n\),只须满足\(c-1\ge 0,c\ge 1\)即可

递归树求解递归式

  • 在递归树中,每个结点表示一个单一子问题的代价,子问题对应某次递归函数调用。我们将树中每层中的代价求和,得到每层代价,然后将所有层的代价求和,得到所有层次的递归调用的总代价。

  • 假设递归式为\(T(n) = aT(\frac{n}{b})+f(n)\)

    • \(a\):子问题的个数
    • \(n/b\):每个子问题的规模
    • \(f(n)\):当前层的额外代价 (划分、合并等)
  • 画出递归树的结构:根节点为\(f(n)\),引出\(a\)个分支,每个子问题为\(T(\frac{n}{b})\),每个子问题又可以引出\(a\)个分支子问题,留下\(f(\frac{n}{b})\)的合并花费,每个子问题为\(T(\frac{n}{b^2})\),......一直分到最底层子问题为\(T(1)\)

  • 然后计算每一层的代价:\(f(n)\)\(af(\frac{n}{b})\)\(a^2f(\frac{n}{b^2})\),...,\(a^kf(\frac{n}{b^k})\)\(\mathrm{LevelCost}(i)=a^i\cdot f\left(\frac n{b^i}\right)\) ,树高为\(H = \log_b n\),最后一层共\(a^H=a^{\log_b n}=n^{\log_b a}\)个节点,因此最后一层代价为\(T(1)\times n^{\log_b a} = \Theta(n^{\log_b a})\)

  • 细节问题\(a^{\log_b n } =n^{\log_b a}\)的证明

先对原式变形:

\[a^{\log_b n} = n^{\log_n a\cdot \log _b n} = n^{\log_b n \cdot\log_n a} \]

证明一个结论(利用对数的换底公式):

\[\log_a b\cdot \log_b c = \frac{\ln b}{\ln a} \cdot\frac{\ln c}{\ln b} = \frac{\ln c}{\ln a} = \log_a c \]

然后就可以轻易得出

\[a^{\log_b n}=n^{\log_b n \cdot\log_n a} = n^{\log_b a} \]

  • 总代价

    \[f(n)+\sum_{i=1}^{H-1=\log_b n-1} a^i\cdot f(\frac{n}{b^i}) + \Theta(n^{\log_b a}) \]

  • 例子: \(T(n) = 3T(\frac{n}{4}) + \Theta (n^2)\)

主定理求解递归式

  • 对于递归式:\(T(n)=aT\left(\frac nb\right)+f(n)\quad\forall n>b\)
  • 主定理如下:

\[T(n)=\begin{cases}\Theta(n^{\log_ba})&f(n)=O(n^{\log_b(a)-\epsilon}),\epsilon>0\\\Theta(f(n))&f(n)=\Omega(n^{\log_b(a)+\epsilon}),\epsilon\geq0\\\Theta(n^{\log_ba}\log^{k+1}n)&f(n)=\Theta(n^{\log_ba}\log^kn),k\geq0&\end{cases} \]

  • 第二种情况还需要满足regularity condition\(af(n/b)\leq cf(n),c<1\)
  • 例子:
    • 归并排序:\(T(n) = 2T(\frac{n}{2})+n\)
    • \(a=2,b=2,\log_b a = 1\)\(n^{\log_b a}=n\)
    • \(f(n) = n = \Theta(n)\)
    • \(T(n) = \Theta(n\log n)\)

递归树与主定理三种情况的联系

  • 递归式为:\(T(n) = aT(\frac{T}{b})+f(n)\)
  • 使用递归树分析:

  • 我们可以得出总代价

\[T(n) = f(n)+\sum_{i=1}^{H-1} a^if(\frac{n}{b^i}) +\Theta(n^{\log_b a}) \]

第一种情况

直观理解:

  • \(f(n)=O(n^{\log_b(a)-\epsilon})\)时:
  • 此时\(f(n)\)没有 \(n^{\log_b a}\) 增长速度快,中间项的增长速度随层数增加而增加,因此递归式总代价中\(\Theta(n^{\log_b a})\) 为增长最大的项,其他均为低阶项,因此在渐进分析中可以忽略

\[T(n)=f(n)+\sum_{i=1}^{H-1} a^if(\frac{n}{b^i}) +\Theta(n^{\log_b a})=\Theta(n^{\log_b a}) \]

  • 简记:头轻尾重取尾重

证明

  • 每一中间项

\[C_i = a^if\left(\frac n{b^i}\right)=a^i\cdot O\left(\left(\frac n{b^i}\right)^{\log_ba-\varepsilon}\right)=O(n^{\log_ba-\varepsilon}\cdot(a/b^{\log_ba-\varepsilon})^i)=O(n^{\log_ba-\varepsilon}\cdot(b^\epsilon)^i) \]

不难发现\(C_i\)的渐进上界是一个随 \(i\) 递增的函数,因此层数越深,所需时间代价越大,直观上来讲,就是最后一层的时间代价占主导地位,证明如下

\[\sum_{i=0}^{H-1} C_i \le cn^{\log_ba-\varepsilon}\sum_{i=0}^{H-1}(b^\epsilon)^i=cn^{\log_ba-\varepsilon}\cdot\frac{b^{H\varepsilon}-1}{b^\varepsilon-1} \]

\(H = \log_b n\),进一步化简

\[\sum_{i=0}^{H-1}C_i\leq cn^{\log_ba-\varepsilon}\cdot\frac{n^\varepsilon-1}{b^\varepsilon-1}=\frac c{b^\varepsilon-1}(n^{\log_ba}-n^{\log_ba-\varepsilon})=O(n^{\log_ba}). \]

所以

\[T(n)=\sum_{i=0}^{H-1}C_i+\Theta(n^{\log_ba})=\Theta(n^{\log_ba}). \]

第二种情况

直观理解:

  • \(f(n)=\Omega(n^{\log_b(a)+\epsilon})\)时:
  • 此时\(f(n)\)\(n^{\log_b a}\) 增长速度快,中间项的增长速度随层数增加而减小,递归式总代价中\(f(n)\) 为增长最大的项,对于中间项\(a^if(\frac{n}{b^i})\)一定没有\(f(n)\)增长快,因此其他项相对\(f(n)\)低阶,均可以忽略。别忘了满足正则条件 \(af(n/b)\leq cf(n),c<1\)

\[T(n)=f(n)+\sum_{i=1}^{H-1} a^if(\frac{n}{b^i}) +\Theta(n^{\log_b a})=\Theta(f(n)) \]

  • 简记:头重尾轻取头重

证明

  • 中间项

\[C_i = a^if\left(\frac n{b^i}\right) = a^i\Omega((\frac{n}{b^i})^{\log_b a+\epsilon}) = \Omega(n^{\log_b a+\epsilon} b^{-\epsilon i}) \]

不难发现,\(C_i\)的渐进下界是一个随 \(i\) 递减的函数,因此层数越深,所需时间代价越小,直观上来讲,就是第一层的时间代价占主导地位,证明如下

\[\sum_{i=1}^{H-1} C_i \ge ... \]

等等,我们发现这个符号好像反了,我们需要证明这个和要小于\(f(n)\),而这是大等号,怎么办呢?这时候就要引入正则条件(\(af(n/b)\leq cf(n),c<1\))了

由正则条件,(\(0<c<1\)

\[af(n/b)\leq cf(n) \]

可知

\[a^if{\left(\frac n{b^i}\right)} = a^{i-1}(af{\left(\frac n{b^i}\right)}) \le a^{i-1}cf(\frac n{b^{i-1}}) \le a^{i-2}cf(\frac n{b^{i-2}})\le ...\le c^if(n) \]

因此让我们回到刚刚的式子

\[\sum_{i=1}^{H-1} C_i \le \sum_{i=1}^{H-1}c^if(n)\le f(n)\sum_{i=1}^{H-1}c^i =f(n)\frac{c-c^{\log_b n}}{1-c}<\frac{c}{1-c}f(n)<\frac{1}{1-c}f(n)=c'f(n) \]

所以中间项都比第一项小,再考虑最后一层

\[C_H = \Theta(n^{\log_b a}) \]

因为

\[f(n)=\Omega(n^{\log_b(a)+\epsilon}) \]

所以\(f(n)\),肯定比最后一层增长快,最后一层代价被忽略

所以得到结论

\[T(n) = \Theta(f(n)) \]

第三种情况

直观理解:

  • \(f(n)=\Theta(n^{\log_ba}\log^kn)\)
  • 这意味着$ f(n)$ 和 “分治部分的代价” \(n^{\log_b a}\) 增长速度几乎一样,只是多了一层对数因子。
  • 在递归树中,每一层的代价不会快速衰减或增长,而是大致相同数量级
  • 此时相当于每一层代价累加后得到

\[T(n)=\Theta(n^{^{\log_ba}}\log^{k+1} {n}) \]

  • 简记:头尾均匀取累重

证明

  • 对每一层代价

\[C_i = a^if(\frac{n}{b^i}) = a^i \Theta(\left(\frac n{b^i}\right)^{\log_ba}\log^k\frac n{b^i}) \]

\[C_i = \Theta(n^{\log_b a} \cdot (\frac{a^i}{b^{i\log_b a}})\cdot\log^k\frac n{b^i}) =\Theta(n^{\log_b a} \cdot (\frac{a}{a})^i\cdot \log^k\frac n{b^i})=\Theta(n^{\log_b a}\cdot \log^k\frac n{b^i}) \]

\[C_i =\Theta(n^{\log_b a}\cdot \log^k\frac n{b^i}) = \Theta(n^{\log_b a}(\log n -i\log b)^k) \]

  • 总代价

\[T(n)=\sum_{i=0}^{\log_bn}C_i=\Theta\left(n^{\log_ba}\sum_{i=0}^{\log_bn}(\log n-i\log b)^k\right)\]

对于比较复杂的求和部分单独分析:

我们发现

\[\log_b n =\frac{\log n}{\log b} \]

\(\log n-i\log b\) 部分对 \(i\) 而言是线性增长的,如果令\(m=\log_b n\)\(j=m-i\),则\(i\)\(0\)\(m\)变化的同时,\(j\)\(m\)\(0\) 变化,它们变化区间一致,所以

\[\sum_{i=0}^m(\log n-i\log b)^k = \sum_{j=0}^m(\log n-(m-j)\log b)^k \]

\[=\sum_{j=0}^m (\log n -m\log b+j\log b)^k =\sum_{j=0}^m(j\log b)^k \]

于是就化简成了一个简单的形式

通过Faulhaber 公式

\[\sum_{j=1}^mj^k=\frac{m^{k+1}}{k+1}+\frac12m^k+O(m^{k-1}). \]

可知(才不是懒得证了才直接套结论呢~)

\[\sum_{j=1}^mj^k=\Theta(m^{k+1})=\Theta(\log^{k+1} {n}) \]

因此

\[T(n)=\sum_{i=0}^{\log_bn}C_i=\Theta\left(n^{\log_ba}\sum_{i=0}^{\log_bn}(\log n-i\log b)^k\right)=\Theta(n^{^{\log_ba}}\log^{k+1} {n}) \]

posted @ 2025-10-24 00:13  NightRainLone  阅读(21)  评论(0)    收藏  举报