主定理

定义

主定理(Master Theorem)通常是指在算法分析领域中的一个定理,特别是用于分析递归算法的时间复杂度。

时间复杂度相关定义

在计算机科学中,算法的时间复杂度(time complexity)是一个函数,它定性描述该算法的运行时间。其原理在于,将计算机的每种基本运算(如加减乘除)所需的时间视为常数,然后考察一个算法调用了多大量级的基本运算。时间复杂度常用大 \(O\) 符号表述,不包括这个函数的低阶项和首项系数。使用这种方式时,时间复杂度可被称为是渐近的,亦即考察输入值大小趋近无穷时的情况。例如,如果一个算法对于任何大小为 \(n\) 的输入,它至多需要 \(5n^3 + 3n\) 的时间运行完毕,那么它的渐近时间复杂度是 \(O(n^3)\)

为了计算时间复杂度,我们通常会估计算法的操作单元数量,每个单元执行的时间都是相同的。因此,总运行时间和算法的操作单元数量最多相差一个常量系数。

相同大小的不同输入值仍可能造成算法的执行时间不同,因此我们通常使用算法的最坏情况复杂度(时间复杂度上界),记为 \(T(n)\) ,定义为任何大小的输入 \(n\) 所需的最大执行时间。另一种较少使用的方法是平均情况复杂度,通常有特别指定才会使用(如用于随机算法)。

对 Bachmann–Landau 符号描述如下:

\(f(n)=O(g(n))\) 表示 \(g\)\(f\) 的上界;

\(f(n)=\Omega(g(n))\) 表示 \(g\)\(f\) 的下界;

\(f(n)=\Theta(g(n))\) 表示 \(g\)\(f\) 的上界和下界。

内容

在算法中,假设有递归关系式:

\[ T(n)=aT\left(\frac nb\right)+f(n),\ a\geq 1,b>1 \]

其中,\(n\) 为问题规模,\(a\) 为子问题数量,\(\frac nb\) 为每个子问题的规模(假设每个子问题规模基本一致),\(f(n)\) 为递归以外的计算。

  • 情况1: 若 \(\exists \epsilon >0\) ,有 \(f(n)=O(n^{\log_ba-\epsilon})\) ,则 \(T(n)=\Theta(n^{\log_ba})\)

  • 情况2: 若 $\exists \epsilon \geq0 $,有 \(f(n)=\Theta(n^{\log_ba}\log^\epsilon n)\) ,则 \(T(n)=\Theta(n^{\log_ba}\log^{\epsilon+1}n)\)

  • 情况3: 若 \(\exists \epsilon >0,c<1\) ,有 \(f(n)=\Omega(n^{\log_ba+\epsilon}),af\left(\frac nb\right)\leq cf(n)\) ,则 \(T(n)=\Theta(f(n))\)

证明

设总复杂度为 \(T(n)\),有

\[T(n)=\sum_{i=0}^{\log_bn}a^i f\left(\frac n{b^i}\right) \]

将上述三种情况分别代入得 \(T(n)\)

  • 情况1:

\[ \begin{aligned} T(n)&=O(\sum_{i=0}^{\log_bn}a^i\left(\frac n{b^i}\right)^{\log_ba-\epsilon})\\ &=O(n^{\log_ba-\epsilon}\sum_{i=0}^{\log_bn}\left(\frac a{b^{\log_ba=\epsilon}}\right)^i)\\ &=O(n^{\log_ba-\epsilon}\sum_{i=0}^{\log_bn}b^{\epsilon j})\\ &=O(n^{\log_ba-\epsilon}\left(\frac{n^\epsilon-1}{b^\epsilon-1}\right))\\ &=O(n^{\log_ba}) \end{aligned} \]

  • 情况2:

\[\begin{aligned} T(n) & =\Theta\left(\sum_{i=0}^{\log_b n} a^i\left(\frac{n}{b^i}\right)^{\log _b a} \log ^k\left(\frac{n}{b^i}\right)\right) \\ & =\Theta\left(\sum_{i=0}^{\log_b n} a^i\left(\frac{n^{\log _b a}}{b^{i^{\log _b a}}}\right)\left(\log n-\log b^i\right)^k\right) \\ & =\Theta\left(n^{\log _b a} \sum_{i=0}^{\log_b n}\left(\frac{a}{b^{\log _b a}}\right)^i\left(\log ^k n-\log ^k b^i\right)\right) \\ & =\Theta\left(n^{\log _b a} \sum_{i=0}^{\log_b n} \log ^k n-\log ^k b^i\right) \\ & =\Theta\left(n^{\log _b a}\left(\log _b n \cdot \log ^k n-\sum_{i=0}^{\log_b n} \log ^k b^i\right)\right) \\ & =\Theta\left(\log _b n \cdot \log ^k n \cdot n^{\log _b a}-n^{\log _b a} \sum_{i=0}^{\log_b n} \log ^k b^i\right)\\ & =\Theta\left(n^{\log _b a}\log ^{k+1} n\right) \end{aligned}\\ \]

  • 情况3:

\[\begin{aligned} &af(\frac nb)\leq cf(n)\\ &\Rightarrow a^if(\frac nb)\leq c^if(n)\\ &\Rightarrow T(n)\leq \sum_{i=0}^{\log_b n}c^if(n)\\ &\Rightarrow T(n)\leq f(n)\sum_{i=0}^\infty c^i\\ &\Rightarrow T(n)\leq \left(\frac 1{1-c}\right)f(n)\\ &\Rightarrow T(n)=O(f(n)) \end{aligned} \]

又由于 \(f(n)=\Omega(n^{\log_ba+\epsilon})\)\(T(n)=\Omega(f(n))\),因此

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

综上,定理得证。

应用

一般的递归算法都可以用主定理分析时间复杂度。如大多数分治算法等。下面给出一个具体的问题作为实例。

最小圆覆盖问题 :给定平面上的 \(n\) 个点,求出一个最小的一圆包围所有的点。

对于一个答案,一定有至少两个点在圆上。若不然,则圆可以继续缩小。因此我们只需要找到两个点(作为直径)或三个点即可确定一个最小圆覆盖。

我们用到随机增量法,即将给出的点以随机的顺序进行遍历。\(\{p_i\}\) 为加入的点集。设前 \(i-1\) 个点确定的最小覆盖圆为 \(C\),此时加入 \(p_i\)

  1. \(p_i\)\(C\) 内,则最小覆盖圆不变。

  2. \(p_i\)\(C\) 外,则其一定在新确定的最小覆盖圆上。此时遍历前 \(i-1\) 个点。设当前遍历到 \(p_j\),则将 \(p_i,p_j\) 确定的圆设为当前最小覆盖圆,并遍历前 \(j-1\) 个点,若有点 \(p_k\) 在圆外,则将 \(p_i,p_j,p_k\) 确定的圆设为当前最小覆盖圆。

可以证明,这样一定能获得一个最小圆覆盖。

设三个循环的复杂度分别为 \(T_1(n),T_2(n),T_3(n)\)。现在考虑第一层循环,即加入一个点的循环。由于最多只有三个点在最小覆盖圆上,且我们的点是随机加入的,理论上每个点其之前点确定的最小覆盖圆上的概率是相同的,因此点 \(p_i\) 在加入时在当前圆外并调用下层循环的概率是 \(\frac 3i\)。第二层调用类似。因此计算时间复杂度为

\[ \begin{aligned} &T_1(n)=\sum_{i=1}^n\frac 3iT_2(i)+O(n)\\ &T_2(n)=\sum_{i=1}^n\frac 3iT_3(i)+O(n)\\ &T_3(n)=O(n) \end{aligned} \]

其中两点及三点确定一个圆可由公式推出,计算量固定可视为常数。

这里每一层对上一层实际上是有 \(n\) 个规模为 \(1\) 的子问题。由主定理得,最终算法的时间复杂度为 \(T_1(n)=O(n)\)


PS:tex 写多了感觉不会写 markdown 了……

posted @ 2024-01-05 22:36  Star_Cried  阅读(92)  评论(0编辑  收藏  举报