算法导论其一:分析
目录
工欲善其事必先利其器,写出优良算法的基础是拥有对算法性能衡量的能力。一起回顾一下时间复杂度的计算吧。
假设计算机无限快,并且计算机存储器是免费的,那么你还有任何理由来研究算法吗?
——《算法导论》
关注点
- 性能:尽量跑的快一点
- 安全:比如不要泄露内存
- 扩展:泛用性很强(对字符串排序、对数字排序)
- 易用性:接口简单
- 鲁棒性:稳定(不要忽快忽慢,忽然崩溃)
常用性能衡量工具
- 数学符号(渐进记号)
- 定义域为自然数域 $\mathrm{N}=\{0,1,2,…\}$
- 目的:衡量并比较算法性能优劣
- $\Theta$记号:$\Theta(g(n))=\{f(n);\exists c_1,c_2,n_0,\forall n\ge n_0,0\le c_1 g(n) \le f(n) \le c_2 g(n)\}$
- 人话:一定输入规模之后,$f$可以被$g$夹着。渐近地代表了一个函数的上界和下界。
- $\mathrm{O}$记号:$\mathrm{O}(g(n))=\{f(n);\exists c,n_0,\forall n\ge n_0,0\le f(n) \le c g(n)\}$
- 人话:一定输入规模之后,$f$不会比$g$大。$\Theta$记号是隐含着$\mathrm{O}$的。
- $\Omega$记号:$\Omega(g(n))=\{f(n);\exists c,n_0,\forall n\ge n_0,0\le c g(n)\le f(n) \}$
- 人话:一定输入规模之后,$f$不会比$g$小。$\Theta$记号也是隐含着$\mathrm{O}$的。
- $\mathrm{o}$记号:$\mathrm{o}(g(n))=\{f(n);\forall c, \exists n_0,\forall n\ge n_0,0\le f(n) \le c g(n)\}$
- 人话:一定是非渐近紧确的上界,标志着在输入规模足够之后,$f$是$g$的等价无穷小了。
- $\omega$记号:$\omega(g(n))=\{f(n);\forall c, \exists n_0,\forall n\ge n_0,0\le c g(n)\le f(n) \}$
- 人话:一定是非渐近紧确的下届,标志着在输入规模足够之后,$g$是$f$的等价无穷小了。
- 注意:
- $\Theta \mathrm{O} \Omega$记号都是不保证渐近紧确的。
- 传递性:五种符号都支持
- 自反性:$\Theta \mathrm{O} \Omega$
- 对称性:$\Theta$
- 转置对称性(即$fg$对换位置):$\mathrm{O}$和$\Omega$,$\mathrm{o}$和$\omega$
- 运算约定
- 最常用的写法是:$f(n)=\Theta(g(n))$,更标准的写法是$f(n)\in \Theta(g(n))$。
- 出现在一个“等式”中,如:$2n^2+3n+1=2n^2+\Theta(n)$,此时渐近符号代表某个不在乎其名字的匿名函数。
- 出现在“等式”两边,如:$2n^2+\Theta(n)=\Theta(n^2)$,此时代表,无论左侧的匿名函数如何选择,总有一个右边的匿名函数能使等式成立。可以整体理解为,任意左侧的属于右侧
- 常用数学:
- 任何底大于1的指数函数都比任何多项式函数增长的更快:$n^b=\mathrm{o}(a^n),a>1$
- 任何正多项式函数都比多相对数函数增长的更快:$lg^bn=\mathrm{o}(n^a),a>0$
- 易知:$n!=\mathrm{o}(n^n),n!=\omega(2^n)$,并可用斯特林公式证明:$lg(n!)=\Theta(nlgn)$
- 主方法(Master Method)
- 形式:对递归表达式$T(n)=aT(\frac{n}{b})+f(n)$,要求$f(n)$渐近趋正(n够大的时候都大于0),$b>1,a\ge 1$
- 比较:$f(n)$ vs $n^{log_b^a}$
- 若存在常数$\varepsilon>0$,使得$f(n)=\mathrm{O}(n^{(log_b a)-\varepsilon})$,则有$T(n)=\Theta(n^{log_b a})$
- 若$f(n)=\Theta(n^{log_b a})$,则$T(n)=\Theta(n^{log_b a} lgn)$
- 若存在常数$\varepsilon>0$,使得$f(n)=\Omega(n^{(log_b a)+\epsilon})$,且对常数$c<1$与所有足够大的$n$,有$af(\frac{n}{b})\le cf(n)$,则$T(n)=\Theta(f(n))$
- 主方法并不能适用于所有递归表达式,有些式子无法满足所有
- 主方法是有严格证明的,可以看,但没必要(折磨自己)。
- 画递归树
- 通常可以先用递归树获得一个不太严谨的答案,然后使用代换法证明
- 核心思想是统计出出所有的叶节点数量,并计算每一层的任务量
- 代换法(猜想并归纳证明)
0. 例如:$T(n)=4T(n/2)+n$
- 猜想是$T(n)=\mathrm{O}(n^2)$(不紧确)
- 设$T(k) \le c_1 k^2 - c_2 k$
- 代换原始递归式并证明可以满足猜想
- 证明边界情况满足(例如T(1)或T(2)等)
- 需要较高的猜想技巧,另外该方法并不保证猜出渐近紧确的界
平摊分析(等待补充)
部分算法、数据结构,它的单一操作可能最坏、但平摊耗费较小。不保证实时性能。对于这类算法和数据结构,不能用常规方法分析,需要对其平均性能进行估计。
- 例子
- 聚集分析
- 记账法
- 势能法
竞争分析(等待补充)
- 分类
- 应用
- 方法
- 举例
参考资料
学点英语,主要是尽量把术语发音正确噢 😜MIT6.046Jのbilibili传送门