CMU 15-751 课程第三课笔记。
接上回 CMU 15-751 CS Theory Toolkit Lecture 2 - Basic Asymptotics。
同样照抄参考了 Lecture Note。
今天学习的是阶乘和二项式系数的渐进分析,这两种的出现频率非常高,因此我们很有必要熟悉他们的渐进方法。这也是我们做更多渐进分析的练习的机会。
阶乘(Factorials)
n!=2Θ(nlogn)
阶乘我们非常熟悉,n!=n(n−1)(n−2)…2⋅1=∏i=1ni。
那我们如何分析 n! 的渐进性呢?
首先,我们显然有
n!=n(n−1)(n−2)…2⋅1≤n⋅n⋯n⋅n=nn
这是 n! 我们可以确定的一个上界,尽管这个上界可以说宽松得过分。
想要计算 n! 的下界,我们可以只取前 ⌈2n⌉ 项,对这些项应该都大于 2n,对它们都取 ⌈2n⌉ 的下界,得到
n!=n(n−1)(n−2)…2⋅1≥⌈2n⌉⋅⌈2n⌉⋯⌈2n⌉(⌈2n⌉times)=(⌈2n⌉)⌈2n⌉≥(2n)n/2
上面的讨论是建立在 n 是偶数的基础上的,但是在 n 是奇数的时候这也是成立的,这很容易看出来。
这样,我们就得到了一个仍然不宽松的下界,且把上下界都统一为 nn 的形式。
但是我们如何比较 n! 的上下界呢?即使形式类似,(2n)n/2 和 nn 的大小实际上也相差甚远。
对于这样的很大很长的连乘式,对它们不断取对数是一个很常用的做法,因为这样我们就可以把底数大小、连乘次数这些难以解决的东西变成对数下的常数。
因此,我们得到
2nln(2n)≤ln(n!)≤nlnn
因此,这里的 ln(n!) 的上下界都可以统一为 Θ(nlogn)。
于是我们就得到了 n!=2Θ(nlogn)。
当然,这个结果过于宽松,我们不会满意于这个结果。让我尝试获得更精确的结果。
ln(n!)∼nlnn
通过泰勒公式,我们可以得到:
ex=1+x+2!x2+3!x3+…≥n!xn,∀x≥0
我们令 x=n,则可以得到 n!≥enxn=(en)n。
这是一个非常优秀的下界,我们将之与之前得到的上界连在一起便可以得到 (en)n≤n!≤nn。于是
nln(en)=nlnn−n≤ln(n!)≤nlnn
于是我们就得到了 ln(n!)∼nlnn。
这是一个非常优美的形式,但是实际上这个界限还是非常宽松——这仅仅是一个对于 ln(n!) 的优秀渐进,对于 n! 本身仍然是一个很大的范围,我们希望知道 n! 是离 (en)n 更接近还是距离 (1n)n 更接近。
n!≈ennn
为了解决这个问题,我们可以设出分式的分母。令 n!=f(n)nn,即 f(n)=n!nn。我们只需要关心 f(n)→1 还是 f(n)→en,也就是 f(n)f(n+1)→1 还是 f(n)f(n+1)→e。
f(n)f(n+1)=(n+1)!/n!(n+1)n+1/nn=nn(n+1)n=(1+n1)n
根据微积分的基本知识,我们知道这个式子的极限是 e。(实际上,这也是 e 的定义之一,或者也可以通过 1+n1≈e1/n 来理解)
于是我们就得到了 f(n)≈en,那么对于很大的 n,我们就可以有 n!≈ennn。
n!=Θ(ennnn)
模仿上一个 Lecture 中我们求调和数的渐进性的方法,我们可以用积分发来更精确地计算 n! 的渐进。

我们知道 ln(n!)=ln1+ln2+ln3+⋯+lnn,其中 ln1=0,因此我们可以用 ∫1nlnt dt 来接近 ln(n!)。
如上面的图 (a) 所示,我们可以得到
ln(n!)≥∫1nlnt dt=tlnt−t∣∣∣1n=nlnn−n+1
这样我们就算出了 ln(n!) 的上限。
我们很清楚地知道我们这里的积分多算了哪一块。我们可以通过把每一个矩形左上角的三角形加回来,如图 © 所示,来弥补这个多算的部分——但是这样会导致有若干的小薄条没有被计算,因此我们得到的是 ln(n!) 的下限。
图 © 中的每一个小薄条,都是底为 1,高为 lnn−ln(n−1) 的直角三角形。这些直角三角形的面积和很容易计算,它们的高之和显然就是 ln2−ln1+ln3−ln2+⋯+lnn−ln(n−1)=lnn,因此它们的面积和就是 21⋅1⋅lnn=21lnn。
于是我们得到
nlnn−n+1≤ln(n!)≤nlnn−n+21lnn+1
对两边做 exp 运算,得到
ennn⋅e≤n!≤ennn⋅n⋅e
这样我们就把 n!≈ennn 推进到了一个更紧的范围。这个形式也可以写成 n!=Θ~(ennn)。
但是这个结果我们仍然不满意。我们想要知道除了 ennn 这个因式之外,剩下的那个因式到底是 Θ(1) 还是 Θ(n)。
我们知道,我们刚刚在计算 ln(n!) 的上界时,求得的结果只比真正的值多了若干个小薄片。那么我们要想办法把这个小薄片的面积减去。
直接计算当然不好算,但是我们可以想办法去接近。我们可以再 y=lnx 的曲线上,每一次都从第 i(i 从 2 开始编号)个小薄条的右上角 (n,lnn) 做一个切线,与 x=n−1 这条直线的交点,以及 (n−1,ln(n−1)) 这三个点构成一个三角形。这个三角形的面积显然会比小薄条的面积大,因此减去后就可以得到一个更紧密的下界。

我们知道 (n,lnn) 点的切线斜率是 n1,因此交点的 y 坐标是 lnn−n1,三角形的底就是 lnn−ln(n−1)−n1。于是小三角形的总面积就是
==21i=2∑n(lnn−ln(n−1)−n1)21i=2∑nlnn−21i=1∑n−1lnn−21i=2∑nn121(lnn−H(n)+1)
其中,H(n) 是我们上一个 Lecture 的调和数。我们知道 H(n)=lnn+γ−O(n1)。因此上式可以写为 21(1−γ+O(n1))=Θ(1)。
也就是说
nlnn−n+21lnn+1−Θ(1)≤ln(n!)≤nlnn−n+21lnn+1
即
n!=Θ(ennnn)
实际上从上面的结论到这个公式还需要做更多的计算。如果真的想要求出这个常数的话再后面的学习中我们可能会遇到。但是这里我们只需要知道
n!=2πn(en)n(1±O(n1))
二项式系数(Binomial Coefficients)
当 k 非常小的时候,(kn)≈k!nk
二项式系数我们都很熟悉,(kn)=k!(n−k)!n!=k!n(n−1)⋯(n−k+1)。它可以表示从 n 个不同物品中选出 k 个的方案数,也可以表示二项式展开得到的系数。
当 k 很小,也就是 k<<n 时,我们可以得到
===∼k!n(n−1)⋯(n−k+1)k!nk(1−n1)(1−n2)⋯(1−nk−1)k!nkPk,nk!nkexp(−2nk2)∼k!nk(1−2nk2)k!nk
其中 Pk,n 是我们在之前的生日问题中定义的数。
于是我们得到,当 k 非常小的时候,(kn)≈k!nk。
简单的上下界
实际上,因为 n(n−1)⋯(n−k+1)≤nk,所以 k!nk 是 (kn) 的一个简单的上界,这对任意的 k 都成立。又因为 k!≥ekkk,于是我们可以得到一个工整一些的形式:
(kn)≤(ken)k
我们也可以求出 (kn) 的下界。
我们知道
(kn)=kn⋅k−1n−1⋅k−2n−2⋯1n−k+1
因为 k−in−i≥kn(可以通过 ⇔nk−ki≥nk−ni 来证明),因此我们可以得到
(kn)≥(kn)k
我们惊喜地看到,我们得到的上界和下界仅有一个 ek 的因式的差异。这样的渐进对于我们来说往往是足够的,如果我们取一下对数,我们可以得到
kln(kn)≤ln(kn)≤kln(ken)=kln(kn)+k
也就是 ln(kn)=Θ(kln(kn))。
(pnn)≤2H(p)n
如果我们知道常数 p 满足 0<p≤2n,k=pn,我们希望能够对于这时的 (kn) 能够更好地分析渐进性。
一般来说,这里我们应该使用斯特林公式来求解这个问题,但是让我们先来试着用一些基本的方法求出 (pnn) 的上界。
我们令 V(n,k)=(0n)+(1n)+⋯+(kn)。这个值可以代表 1 的个数不多于 k 的长度为 n 的不同二进制字符串的数量,也通常被认为半径为 k 的以 00⋯0(n 个 0)为中心的「Hamming ball」的数量的容量。这个数在 TCS 中经常出现。
由二项式定理:
(1+x)n=1+(1n)x+(2n)x2+⋯+(kn)xk+⋯+(nn)xn≥(0n)+(1n)x+(2n)x2+⋯+(kn)xk≥xk⋅V(n,k),∀0<x≤1
因此
V(n,k)≤xk(1+x)n=(pn)k(1+x)n=(xp1+x)n=(x−p+x1−p)n=(x−p+xq)n,∀0<x≤1
其中,我们令 q=1−p。
通过求导我们可以知道,当 x=qp 时,x−p+xq 取得最小值。这个 x 会小于等于 1,因为我们曾假设 p≤21。那么此时
x−p+xq=x−p(1+x)=x−p(1+qp)=x−p⋅q1=(qp)−p⋅q1=(pq)p(q1)p(q1)q=(p1)p(q1)q
因而
(pnn)≤V(n,pn)≤[(p1)p(q1)q]n=p−pnq−qnfor p≤21
如果我们令 H(p)=plog2p1+qlog2q1,这个函数一般被称为二元交叉熵(Binary entropy function),那么上式可以写成
(pnn)≤V(n,pn)=2H(p)n

(pnn)=Θ(n12H(p)n)
现在让我们来使用斯特林公式解决这个问题。
(pnn)=(pn)!(qn)!n!∼2πn(pn/e)pn⋅2πn(qn/e)qn2πn(n/e)n=(2πn)(n/e)nppnqqn2πn(n/e)n=2πpq1n1[(p1)p(p1)q]n=2πpq1n12H(p)n
因此,(pnn)=Θ(n12H(p)n)。
特别的,当 p=21 时,H(p)=1,因此
2n(n/2n)∼πn2=Θ(n1)
也就是说,如果我们抛 n 枚硬币(n 是偶数),恰好 2n 枚硬币正面朝上的概率,大约会趋近于 πn2=Θ(n1)。