Algorithm + Data Structures = Programs

本文最后更新于 2024年10月5日 上午

弃坑了,转战Jeff的《Algorithms》

第二章 算法分析的数学基础

本章重点

序列求和的方法

数列求和公式:等差、等比数列与调和级数

k=1nak=n(a1+an)2,k=0naqk=a(1qn+1)1q\sum_{k=1}^{n} a_k = \frac{n(a_1+a_n)}{2},\qquad\sum_{k=0}^{n} aq^k = \frac{a(1-q^{n+1})}{1-q}

k=0aqk=a1q(q<1),k=1n1k=lnn+O(1)\sum_{k=0}^{\infty} aq^k = \frac{a}{1-q} (q<1),\qquad \sum_{k=1}^{n} \frac{1}{k} = \ln n + O(1)

估计和式上界的放大法(下界同理)

  1. k=1naknamax\sum_{k=1}^{n} a_k \leq na_{max}

  2. 假设存在常数 r<1r<1, 使得对一切 k0k \geq 0ak+1akr\frac{a_{k+1}}{a_k} \leq r 成立

    k=0nakk=0a0rk=a0k=0rk=a01r\sum_{k=0}^{n} a_k \leq \sum_{k=0}^{\infty} a_0r^k = a_0 \sum_{k=0}^{\infty} r^k = \frac{a_0}{1-r}

  3. 积分法估计上界

递推方程与算法分析

递推方程

设序列 a0,a1,,an,a_0, a_1, \cdots, a_n, \cdots 简记为 {an}\{a_n\},一个把 a 与其些个 ai(i<n)a_i(i<n) 联系起来的等式叫做关于序列 {an}\{a_n\} 的递推方程

递推方程的求解:

给定关于序列 {an}\{a_n\} 的递推方程和若干初值,计算 ana_n

例子:Fibonacci 数列

Hanoi塔问题

汉诺塔 递归算法 算法分析

插入排序

插入排序 算法分析

小结

  • 递推方程的定义及初值
  • 递推方程与算法时间复杂度的关系
  • Hanoi 塔的递归算法
  • 插入排序的递推算法

递推方程的解法

迭代法

  • 不断用递推方程的右部替换左部
  • 每次替换,随着 nn 的降低在和式中多出一项
  • 直到出现初值停止迭代
  • 将初值代入并对和式求和
  • 可用数学归纳法验证解的正确性
Hanoi塔算法 时间复杂度

换元迭代

  • nn 的递推式换成对其他变元 kk 的递推式
  • kk 直接代入递推式
  • 将解(关于 kk 的函数)转换成关于 nn 的函数
二分归并排序

假设 n=2kn=2^k,递推方程如下:

W(n)=2W(n/2)+n1W(1)=0W(n) = 2 W(n/2) + n - 1 \\ W(1) = 0

换元:

W(2k)=2W(2k1)+2k1W(0)=0W(2^k) = 2 W(2^{k-1}) + 2^k - 1 \\ W(0) = 0

迭代求解 归纳验证

小结

迭代法解递推方程

  • 直接迭代,代入初值,然后求和
  • 对递推方程和初值进行还原,然后求和,求和后再换元回去,得到原始递推方程的解
  • 用数学归纳法验证解的正确性

差消法

如果递推关系比较复杂的时候,直接迭代会非常的困难。 我们要尽量的化简,把高阶的递推方程化简成一阶的 这样才能继续迭代。

快速排序

  • 假设 A[pr]A[p \cdots r] 的元素彼此不等
  • 以首元素 A[1]A[1] 对数组 A[pr]A[p \cdots r] 划分,得到:
    • 小于 xx 的元素放在 A[pq1]A[p \cdots q-1]
    • 大于 xx 的元素放在 A[q+1r]A[q+1 \cdots r]
  • 递归对 A[pq1]A[p \cdots q-1]A[q+1r]A[q+1 \cdots r] 排序

工作量 = 子问题的工作量 + 划分所用工作量

输入情况

  • 有 n 种可能的输入
x 排好序位置 子问题 1 规模 子问题 2 规模
1 0 n-1
2 1 n-2
3 2 n-3
\cdots \cdots \cdots
n-1 n-2 1
n n-1 0
  • 对于每个输入, 比较次数都是 n-1

工作量总和

T(0)+T(n1)+n1T(1)+T(n2)+n1T(2)+T(n3)+n1+T(n1)+T(0)+n1=2[T(1)+...+T(n1)]+n(n1)T(0) + T(n-1) + n-1 \\ T(1) + T(n-2) + n-1 \\ T(2) + T(n-3) + n-1 \\ \cdots \\ + T(n-1) + T(0) + n-1 \\ = 2[T(1)+...+T(n-1)] + n(n-1)

快速排序平均工作量

假设首元素排好序在每个位置是等概率的
递推式为:

T(n)=2ni=1n1T(i)+O(n),n2T(1)=0T(n) = \frac{2}{n} \sum_{i=1}^{n-1} T(i) + O(n), n \geqslant 2 \\ T(1) = 0

对于高阶方程应该先化简, 然后迭代

差消化简

利用两个方程相减, 将右边的项尽量消去, 将左边的项尽可能简化

T(n)=2ni=1n1T(i)+cnnT(n)=2i=1n1T(i)+cn2T(n) = \frac{2}{n} \sum_{i=1}^{n-1} T(i) + cn \\ nT(n) = 2 \sum_{i=1}^{n-1} T(i) + cn^2 \\

得到

(n1)T(n1)=2i=1n2T(i)+c(n1)2(n-1)T(n-1) = 2 \sum_{i=1}^{n-2} T(i) + c(n-1)^2

将上述两式相减:

nT(n)(n1)T(n1)=2T(n1)+cn2c(n1)2=2T(n1)+2cnc=2T(n1)+2c(n1)=2T(n1)+c1n\begin{align*} nT(n) - (n-1)T(n-1) & = 2T(n-1) + cn^2 - c(n-1)^2 \\ & = 2T(n-1) + 2cn - c \\ & = 2T(n-1) + 2c(n-1) \\ & = 2 T(n-1) + c_1n \end{align*}

得到:

T(n)n+1=T(n1)n+c1n+1\frac{T(n)}{n+1} = \frac{T(n-1)}{n} + \frac{c_1}{n+1}

迭代求解:

T(n)n+1=T(n1)n+c1n+1=c1[1n+1+1n++13]+T(1)2=c1[1n+1+1n++13]=Θ(logn)\begin{align*} \frac{T(n)}{n+1} & = \frac{T(n-1)}{n} + \frac{c_1}{n+1} \\ & = c_1 [\frac{1}{n+1} + \frac{1}{n} + \cdots + \frac{1}{3}] + \frac{T(1)}{2} \\ & = c_1 [\frac{1}{n+1} + \frac{1}{n} + \cdots + \frac{1}{3}] \\ & = \Theta(\log n) \end{align*}

因此最终可以得到:

T(n)=Θ(logn)T(n) = \Theta(\log n)

递归树

递归树的概念

  • 递归树是迭代计算的模型.
  • 递归树的生成过程与迭代过程一致.
  • 递归树上所有项恰好是迭代之后产生和式的项.
  • 对递归树上的项求和就是迭代后方程的解.
迭代在递归树中的表示

二分归并排序

二层子树的例子

递归树的生成规则

  • 初始, 递归树只有根结点, 其值为 W(n)W(n)
  • 不断继续迭代过程:
    • 将函数项叶结点的迭代式 W(m)W(m) 表示成二层子树
    • 用该子树替换该叶结点
  • 继续递归树的生成,直到树中无函数项(只有初值)为止.
递归树生成实例1 递归树生成实例2
递归树 对递归树上的量求和
递归树应用实例

求和
方程: T(n)=T(n/3)+T(2n/3)+nT(n) = T(n/3) + T(2n/3) + n,递归树层数 kk,每层 O(n)O(n)

n(23)k=1(23)k=nk=O(log32n)T(n)=Θ(nlogn): \begin{align*} & n (\frac{2}{3})^k = 1 \\ & \Rightarrow (\frac{2}{3})^k = n \\ & \Rightarrow k = O(\log _{\frac{3}{2}} n) \\ & \Rightarrow T(n) = Θ(n log n) \end{align*}

小结

  • 递归树是迭代的图形表述
  • 递归树的生成规则
  • 如何利用递归树求解递推方程

主定理

应用背景

求解递推方程:
T(n)=aT(nb)+f(n)T(n) = a T(\frac{n}{b}) + f(n)

其中:

  1. aa: 递归后的子问题个数
  2. n/bn/b: 递归后子问题的规模
  3. f(n)f(n): 递归过程及组合子问题的解的工作量

二分检索: T(n)=T(n/2)+1T(n) = T(n/2)+1

二分归并排序: T(n)=2T(n/2)+n1T(n) = 2T(n/2)+n-1

主定理的内容与证明

定理:a1,b>1a≥1, b>1为常数, f(n)f(n)为函数, T(n)T(n) 为非负整数,定义为:T(n)=aT(n/b)+f(n)T(n) = aT(n/b) + f(n),则:

  1. f(n)=Θ(nlogbaϵ),ϵ>0f(n) = \Theta(n^{\log_b a - \epsilon}), \epsilon > 0,则 T(n)=Θ(nlogba)T(n) = \Theta(n^{\log_b a})
  2. f(n)=Θ(nlogba),ϵ>0f(n) = \Theta(n^{\log_b a}), \epsilon > 0,则 T(n)=Θ(nlogbalogn)T(n) = \Theta(n^{\log_b a}\log n)
  3. f(n)=Ω(nlogba+ϵ),ϵ>0f(n) = \Omega(n^{\log_b a + \epsilon}), \epsilon > 0,且对于某个常数 c<1c < 1nn 足够大的 nnaf(n/b)cf(n)af(n/b) ≤ cf(n),则 T(n)=Θ(f(n))T(n) = \Theta(f(n))

证明:
对于 T(n)=aT(n/b)+f(n)T(n) = aT(n/b) + f(n),设 n=bkn = b^k,则有:

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=0k1aif(nbi)=c1nlogba+i=0k1aif(nbi),T(1)=c1\begin{align*} T(n) & = aT(n/b) + f(n) \\ &= a[aT(n/b^2) + f(n/b)] + f(n) \\ & = a^2T(n/b^2) + af(n/b) + f(n) \\ &= a^3T(n/b^3) + a^2f(n/b^2) + af(n/b) + f(n) \\ &= \cdots \\ &= a^k T(1) + \sum_{i=0}^{k-1} a^i f(\frac{n}{b^i}) \\ &= c_1 n^{\log_b a} + \sum_{i=0}^{k-1} a^i f(\frac{n}{b^i}), \quad T(1) = c_1 \end{align*}

其中:

  • 第一项为所有最小子问题的计算工作量
  • 第二项为迭代过程归约到子问题及综合解的工作量

情形一: f(n)=Θ(nlogbaϵ),ϵ>0f(n) = \Theta(n^{\log_b a - \epsilon}), \epsilon > 0

T(n)=c1nlogba+j=0k1ajf(nbj)=c1nlogba+O(j=0logbn1aj(nbj)logbaϵ)=c1nlogba+O(nlogbaϵj=0logbn1aj(blogbaϵ)j)(使用:1(blogbaϵ)j=bϵj(blogba)j=bϵjaj)=c1nlogba+O(nlogbaϵj=0logbn1(bϵ)j)=c1nlogba+O(nlogbaϵbϵlogbn1bϵ1)=c1nlogba+O(nlogbaϵnϵ)=Θ(nlogba)\begin{align*} T(n) &= c_1 n^{\log_b a} + \sum_{j=0}^{k-1} a^j f(\frac{n}{b^j}) \\ &= c_1 n^{\log_b a} + O(\sum_{j=0}^{\log_b n -1} a^j (\frac{n}{b^j})^{\log_b a - \epsilon}) \\ &= c_1 n^{\log_b a} + O(n^{\log_b a - \epsilon} \sum_{j=0}^{\log_b n -1} \frac{a^j}{(b^{\log_b a - \epsilon})^j}) \\ &(使用: \frac{1}{(b^{\log_b a - \epsilon})^j} = \frac{b^{\epsilon j}}{(b^{\log_b a})^j} = \frac{b^{\epsilon j}}{a^j}) \\ &= c_1 n^{\log_b a} + O(n^{\log_b a - \epsilon} \sum_{j=0}^{\log_b n -1} (b^\epsilon)^j) \\ &= c_1 n^{\log_b a} + O(n^{\log_b a - \epsilon} \frac{b^{\epsilon \log_b n} - 1}{b^\epsilon - 1})\\ &= c_1 n^{\log_b a} + O(n^{\log_b a - \epsilon} n^\epsilon) \\ &= \Theta(n^{\log_b a}) \end{align*}

情形二: f(n)=Θ(nlogba),ϵ>0f(n) = \Theta(n^{\log_b a}), \epsilon > 0

T(n)=c1nlogba+j=0k1ajf(nbj)=c1nlogba+Θ(j=0logbn1aj(nbj)logba)=c1nlogba+Θ(nlogbaj=0logbn1ajaj)=c1nlogba+Θ(nlogbalogn)=Θ(nlogbalogn)\begin{align*} T(n) &= c_1 n^{\log_b a} + \sum_{j=0}^{k-1} a^j f(\frac{n}{b^j}) \\ &= c_1 n^{\log_b a} + \Theta(\sum_{j=0}^{\log_b n -1} a^j (\frac{n}{b^j})^{\log_b a}) \\ &= c_1 n^{\log_b a} + \Theta(n^{\log_b a} \sum_{j=0}^{\log_b n -1}\frac{a^j}{a^j}) \\ &= c_1 n^{\log_b a} + \Theta(n^{\log_b a} \log n) \\ &= \Theta(n^{\log_b a} \log n) \end{align*}

情形三: f(n)=Ω(nlogba+ϵ),ϵ>0,af(n/b)cf(n)f(n) = \Omega(n^{\log_b a + \epsilon}), \epsilon > 0,\quad af(n/b) ≤ cf(n)

T(n)=c1nlogba+j=0k1ajf(nbj)c1nlogba+j=0k1cjf(n)=c1nlogba+f(n)clogbn1c1=c1nlogba+Θ(f(n))=Θ(f(n))\begin{align*} T(n) &= c_1 n^{\log_b a} + \sum_{j=0}^{k-1} a^j f(\frac{n}{b^j}) \\ & \leqslant c_1 n^{\log_b a} + \sum_{j=0}^{k-1} c^j f(n) \\ & = c_1 n^{\log_b a} + f(n) \frac{c^{\log_b n} - 1}{c - 1} \\ &= c_1 n^{\log_b a} + \Theta(f(n)) \\ & = \Theta(f(n)) \end{align*}

Q.E.D.

主定理的应用

例题1: 求解递推方程 T(n)=9T(n/3)+nT(n) = 9T(n/3) + n.

解: 上述方程 a=9,b=3,f(n)=n,ϵ=1a = 9, b = 3, f(n) = n, \epsilon = 1,根据主定理,有:nlog39=O(nlog39)=n2n^{\log_3 9} = O(n^{\log_3 9}) = n^2,因此 f(n)=O(nlog391)f(n) = O(n^{\log_3 9 - 1})

由主定理,T(n)=Θ(n2)T(n) = \Theta(n^2)

例题2: 求解递推方程 T(n)=T(2n/3)+1T(n) = T(2n/3) + 1.

解: 上述方程 a=1,b=32,f(n)=1,ϵ=1a = 1, b = \frac{3}{2}, f(n) = 1, \epsilon = 1,根据主定理,有:f(n)=Θ(nlog321)=Θ(1)f(n) = \Theta(n^{\log_{\frac{3}{2}} 1}) = \Theta(1)

由主定理,T(n)=Θ(1logn)=Θ(logn)T(n) = \Theta(1 \cdot \log n) = \Theta(\log n)

例题3: 求解递推方程 T(n)=3T(n/4)+nlognT(n) = 3T(n/4) + n \log n.

解: 上述方程 a=3,b=4,f(n)=nlogna = 3, b = 4, f(n) = n \log n,根据主定理,有:f(n)=nlogn=Ω(nlog43+ϵ)Ω(n0.793+ϵ)f(n) = n \log n = \Omega(n^{\log_4 3 + \epsilon}) \approx \Omega(n^{0.793 + \epsilon}),取 ϵ=0.2\epsilon = 0.2 即可。

要使 af(n/b)cf(n)a f (n/b) \leq c f (n) 成立,代入 f(n)=nlognf (n) = n \log n,得到:

3(n/4)log(n/4)cnlogn3 (n/4) \log (n/4) \leq c n \log n

只要 c>3/4c > 3/4, 上述不等式可以对所有充分大的 nn 成立.

由主定理,有 T(n)=Θ(f(n))=Θ(nlogn)T(n)=\Theta(f(n))=\Theta(n\log n)

算法分析

不能使用主定理的情况

例4
递归树求解 求和

小结

  • 使用主定理求解递推方程需要满足什么条件?
  • 主定理怎样用于算法复杂度分析?

算法设计与分析Ch02
http://dbqdss.github.io/2024/08/02/算法设计与分析/算法设计与分析Ch02/
作者
DBQDSS
发布于
2024年8月2日
许可协议