本文最后更新于 2024年10月5日 上午
弃坑了,转战Jeff的《Algorithms》
第二章 算法分析的数学基础
序列求和的方法
数列求和公式:等差、等比数列与调和级数
k=1∑nak=2n(a1+an),k=0∑naqk=1−qa(1−qn+1)
k=0∑∞aqk=1−qa(q<1),k=1∑nk1=lnn+O(1)
估计和式上界的放大法(下界同理)
-
∑k=1nak≤namax
-
假设存在常数 r<1, 使得对一切 k≥0 有 akak+1≤r 成立
∑k=0nak≤∑k=0∞a0rk=a0∑k=0∞rk=1−ra0
-
积分法估计上界
递推方程与算法分析
递推方程
设序列 a0,a1,⋯,an,⋯ 简记为 {an},一个把 a 与其些个 ai(i<n) 联系起来的等式叫做关于序列 {an} 的递推方程
递推方程的求解:
给定关于序列 {an} 的递推方程和若干初值,计算 an
例子:Fibonacci 数列
Hanoi塔问题
插入排序
小结
- 递推方程的定义及初值
- 递推方程与算法时间复杂度的关系
- Hanoi 塔的递归算法
- 插入排序的递推算法
递推方程的解法
迭代法
- 不断用递推方程的右部替换左部
- 每次替换,随着 n 的降低在和式中多出一项
- 直到出现初值停止迭代
- 将初值代入并对和式求和
- 可用数学归纳法验证解的正确性
换元迭代
- 将 n 的递推式换成对其他变元 k 的递推式
- 对 k 直接代入递推式
- 将解(关于 k 的函数)转换成关于 n 的函数
假设 n=2k,递推方程如下:
W(n)=2W(n/2)+n−1W(1)=0
换元:
W(2k)=2W(2k−1)+2k−1W(0)=0
小结
迭代法解递推方程
- 直接迭代,代入初值,然后求和
- 对递推方程和初值进行还原,然后求和,求和后再换元回去,得到原始递推方程的解
- 用数学归纳法验证解的正确性
差消法
如果递推关系比较复杂的时候,直接迭代会非常的困难。 我们要尽量的化简,把高阶的递推方程化简成一阶的 这样才能继续迭代。
快速排序
- 假设 A[p⋯r] 的元素彼此不等
- 以首元素 A[1] 对数组 A[p⋯r] 划分,得到:
- 小于 x 的元素放在 A[p⋯q−1]
- 大于 x 的元素放在 A[q+1⋯r]
- 递归对 A[p⋯q−1] 和 A[q+1⋯r] 排序
工作量 = 子问题的工作量 + 划分所用工作量
输入情况
x 排好序位置 |
子问题 1 规模 |
子问题 2 规模 |
1 |
0 |
n-1 |
2 |
1 |
n-2 |
3 |
2 |
n-3 |
⋯ |
⋯ |
⋯ |
n-1 |
n-2 |
1 |
n |
n-1 |
0 |
工作量总和
T(0)+T(n−1)+n−1T(1)+T(n−2)+n−1T(2)+T(n−3)+n−1⋯+T(n−1)+T(0)+n−1=2[T(1)+...+T(n−1)]+n(n−1)
快速排序平均工作量
假设首元素排好序在每个位置是等概率的
递推式为:
T(n)=n2i=1∑n−1T(i)+O(n),n⩾2T(1)=0
对于高阶方程应该先化简, 然后迭代
差消化简
利用两个方程相减, 将右边的项尽量消去, 将左边的项尽可能简化
T(n)=n2i=1∑n−1T(i)+cnnT(n)=2i=1∑n−1T(i)+cn2
得到
(n−1)T(n−1)=2i=1∑n−2T(i)+c(n−1)2
将上述两式相减:
nT(n)−(n−1)T(n−1)=2T(n−1)+cn2−c(n−1)2=2T(n−1)+2cn−c=2T(n−1)+2c(n−1)=2T(n−1)+c1n
得到:
n+1T(n)=nT(n−1)+n+1c1
迭代求解:
n+1T(n)=nT(n−1)+n+1c1=c1[n+11+n1+⋯+31]+2T(1)=c1[n+11+n1+⋯+31]=Θ(logn)
因此最终可以得到:
T(n)=Θ(logn)
递归树
递归树的概念
- 递归树是迭代计算的模型.
- 递归树的生成过程与迭代过程一致.
- 递归树上所有项恰好是迭代之后产生和式的项.
- 对递归树上的项求和就是迭代后方程的解.
二分归并排序
递归树的生成规则
- 初始, 递归树只有根结点, 其值为 W(n)
- 不断继续迭代过程:
- 将函数项叶结点的迭代式 W(m) 表示成二层子树
- 用该子树替换该叶结点
- 继续递归树的生成,直到树中无函数项(只有初值)为止.
求和
方程: T(n)=T(n/3)+T(2n/3)+n,递归树层数 k,每层 O(n)
:n(32)k=1⇒(32)k=n⇒k=O(log23n)⇒T(n)=Θ(nlogn)
小结
- 递归树是迭代的图形表述
- 递归树的生成规则
- 如何利用递归树求解递推方程
主定理
应用背景
求解递推方程:
T(n)=aT(bn)+f(n)
其中:
- a: 递归后的子问题个数
- n/b: 递归后子问题的规模
- f(n): 递归过程及组合子问题的解的工作量
二分检索: T(n)=T(n/2)+1
二分归并排序: T(n)=2T(n/2)+n−1
主定理的内容与证明
定理: 设a≥1,b>1为常数, f(n)为函数, T(n) 为非负整数,定义为:T(n)=aT(n/b)+f(n),则:
- 若 f(n)=Θ(nlogba−ϵ),ϵ>0,则 T(n)=Θ(nlogba)
- 若 f(n)=Θ(nlogba),ϵ>0,则 T(n)=Θ(nlogbalogn)
- 若 f(n)=Ω(nlogba+ϵ),ϵ>0,且对于某个常数 c<1 和 n 足够大的 n 有 af(n/b)≤cf(n),则 T(n)=Θ(f(n))
证明:
对于 T(n)=aT(n/b)+f(n),设 n=bk,则有:
T(n)=aT(n/b)+f(n)=a[aT(n/b2)+f(n/b)]+f(n)=a2T(n/b2)+af(n/b)+f(n)=a3T(n/b3)+a2f(n/b2)+af(n/b)+f(n)=⋯=akT(1)+i=0∑k−1aif(bin)=c1nlogba+i=0∑k−1aif(bin),T(1)=c1
其中:
- 第一项为所有最小子问题的计算工作量
- 第二项为迭代过程归约到子问题及综合解的工作量
情形一: f(n)=Θ(nlogba−ϵ),ϵ>0
T(n)=c1nlogba+j=0∑k−1ajf(bjn)=c1nlogba+O(j=0∑logbn−1aj(bjn)logba−ϵ)=c1nlogba+O(nlogba−ϵj=0∑logbn−1(blogba−ϵ)jaj)(使用:(blogba−ϵ)j1=(blogba)jbϵj=ajbϵj)=c1nlogba+O(nlogba−ϵj=0∑logbn−1(bϵ)j)=c1nlogba+O(nlogba−ϵbϵ−1bϵlogbn−1)=c1nlogba+O(nlogba−ϵnϵ)=Θ(nlogba)
情形二: f(n)=Θ(nlogba),ϵ>0
T(n)=c1nlogba+j=0∑k−1ajf(bjn)=c1nlogba+Θ(j=0∑logbn−1aj(bjn)logba)=c1nlogba+Θ(nlogbaj=0∑logbn−1ajaj)=c1nlogba+Θ(nlogbalogn)=Θ(nlogbalogn)
情形三: f(n)=Ω(nlogba+ϵ),ϵ>0,af(n/b)≤cf(n)
T(n)=c1nlogba+j=0∑k−1ajf(bjn)⩽c1nlogba+j=0∑k−1cjf(n)=c1nlogba+f(n)c−1clogbn−1=c1nlogba+Θ(f(n))=Θ(f(n))
Q.E.D.
主定理的应用
例题1: 求解递推方程 T(n)=9T(n/3)+n.
解: 上述方程 a=9,b=3,f(n)=n,ϵ=1,根据主定理,有:nlog39=O(nlog39)=n2,因此 f(n)=O(nlog39−1)。
由主定理,T(n)=Θ(n2)
例题2: 求解递推方程 T(n)=T(2n/3)+1.
解: 上述方程 a=1,b=23,f(n)=1,ϵ=1,根据主定理,有:f(n)=Θ(nlog231)=Θ(1)。
由主定理,T(n)=Θ(1⋅logn)=Θ(logn)
例题3: 求解递推方程 T(n)=3T(n/4)+nlogn.
解: 上述方程 a=3,b=4,f(n)=nlogn,根据主定理,有:f(n)=nlogn=Ω(nlog43+ϵ)≈Ω(n0.793+ϵ),取 ϵ=0.2 即可。
要使 af(n/b)≤cf(n) 成立,代入 f(n)=nlogn,得到:
3(n/4)log(n/4)≤cnlogn
只要 c>3/4, 上述不等式可以对所有充分大的 n 成立.
由主定理,有 T(n)=Θ(f(n))=Θ(nlogn)
不能使用主定理的情况
小结
- 使用主定理求解递推方程需要满足什么条件?
- 主定理怎样用于算法复杂度分析?