本文为 MOOC 算法设计与分析 的学习笔记
目录
算法设计的例子
投资问题
-
m
m
m 元钱,投资
n
n
n 个项目. 效益函数
f
i
(
x
)
f_i (x)
fi(x),表示第
i
i
i 个项目投
x
x
x 元的效益,
i
=
1
,
2
,
…
,
n
i =1, 2, …, n
i=1,2,…,n. 求如何分配每个项目的钱数使得总效益最大?
- 实例:5 万元,投资给 4 个项目,效益函数:
- 实例:5 万元,投资给 4 个项目,效益函数:
问题建模
- 输入: n , m , f i ( x ) , i = 1 , 2 , . . . , n , x = 1 , 2 , . . . , m n, m, f_i(x), i =1,2, ..., n, x = 1,2, ..., m n,m,fi(x),i=1,2,...,n,x=1,2,...,m
- 解:
n
n
n 维向量
<
x
1
,
x
2
,
…
,
x
n
>
<x_1, x_2, … , x_n>
<x1,x2,…,xn>,
x
i
x_i
xi 是第
i
i
i 个项目的钱数,使得下述条件满足:
设计算法
蛮力算法
- 对所有满足下述条件的向量
<
x
1
,
x
2
,
…
,
x
n
>
<x_1,x_2,…,x_n>
<x1,x2,…,xn>
x 1 + x 2 + … + x n = m x_1+ x_2 + … + x_n = m x1+x2+…+xn=m, x i x_i xi 为非负整数, i = 1 , 2 , . . . , n i = 1, 2 , ..., n i=1,2,...,n - 计算相应的效益 f 1 ( x 1 ) + f 2 ( x 2 ) + … + f n ( x n ) f_1(x_1) + f_2(x_2) + … + f_n(x_n) f1(x1)+f2(x2)+…+fn(xn),从中确认效益最大的向量
正确性分析
- 该算法显然可以求出最优解
算法效率分析
- 下面对方程
x
1
+
x
2
+
…
+
x
n
=
m
x_1+ x_2 + … + x_n = m
x1+x2+…+xn=m 的非负整数解
<
x
1
,
x
2
,
…
,
x
n
>
<x_1,x_2,…,x_n>
<x1,x2,…,xn> 的个数进行估计:
- 可行解表示成
0
−
1
0-1
0−1 序列:
m
m
m 个
1
1
1,
n
−
1
n-1
n−1 个
0
0
0
- 例如, n = 4 , m = 7 n=4, m=7 n=4,m=7,可行解 < 1 , 2 , 3 , 1 > <1, 2, 3, 1> <1,2,3,1> 对应的序列为 1011011101 1 0 1 1 0 1 1 1 0 1 1011011101
- 因此,非负整数解个数为 C m + n − 1 m = ( m + n − 1 ) ! m ! ( n − 1 ) ! = Θ ( ( 1 + ε ) m + n − 1 ) C_{m+n-1}^m=\frac{(m+n-1)!}{m!(n-1)!}=\Theta((1+\varepsilon)^{m+n-1}) Cm+n−1m=m!(n−1)!(m+n−1)!=Θ((1+ε)m+n−1),序列个数是输入规模的指数函数 (可以代入 Stirling 公式进行证明)
- 可行解表示成
0
−
1
0-1
0−1 序列:
m
m
m 个
1
1
1,
n
−
1
n-1
n−1 个
0
0
0
货郎问题 与 NP-hard 问题
货郎问题
- 有
n
n
n 个城市,已知任两个城市之间的距离. 求一条每个城市恰好经过 1 次的回路,使得总长度最小. (最短哈密顿回路)
建模:
- 输入:有穷个城市的集合 C = { c 1 , c 2 , … , c n } C = \{ c_1, c_2, …, c_n\} C={c1,c2,…,cn}, 距离 d ( c i , c j ) = d ( c j , c i ) ∈ Z + d(c_i,c_j) = d(c_j,c_i)∈Z^+ d(ci,cj)=d(cj,ci)∈Z+, 1 ≤ i < j ≤ n 1≤ i < j ≤ n 1≤i<j≤n
- 解:
1
,
2
…
,
n
1, 2 …, n
1,2…,n 的排列
k
1
,
k
2
,
…
,
k
n
k_1, k_2, …, k_n
k1,k2,…,kn 使得:
设计算法
- 对于货郎问题,至今还未找到比蛮力算法有着本质改进的高效算法 (指算法的时间复杂度由指数函数降为多项式函数)
NP-hard 问题
- 至今没找到比蛮力算法有着本质改进的高效算法 (指算法的时间复杂度由指数函数降为多项式函数)
- 货郎问题也属于 NP-hard 问题
- 至今没有人能够证明对于这类问题不存在多项式时间的算法 ( P = N P ? \boldsymbol{P=NP?} P=NP? 问题 )
- 从是否存在多项式时间算法的角度看,这些问题彼此是等价的. 这些问题的难度处于可有效计算的边界
算法及其时间复杂度
时间复杂度定义
- 算法时间复杂度: 针对指定基本运算, 计数算法所做运算次数。下面给出基本运算的一些示例:
- 排序: 元素之间的比较
- 检索: 被检索元素 x x x 与数组元素的比较
- 整数乘法: 每位数字相乘 (位乘) 1 次; m m m 位和 n n n 位整数相乘要做 m n mn mn 次位乘
- 矩阵相乘: 每对元素乘 1 次; i × j i×j i×j 矩阵与 j × k j×k j×k 矩阵相乘要做 i j k i jk ijk 次乘法
- 图的遍历: 置指针
- …
- 输入规模:通常用下述参数度量:
- 排序:数组中元素个数 n n n
- 检索:被检索数组的元素个数 n n n
- 整数乘法:两个整数的位数 m , n m, n m,n
- 矩阵相乘:矩阵的行列数 i , j , k i, j, k i,j,k
- 图的遍历:图的顶点数 n n n, 边数 m m m
- …
- 算法基本运算次数可表示为输入规模的函数。因此 算法时间复杂度可表示为输入规模的函数 T ( n ) T(n) T(n)
- 补充:给定问题和基本运算就决定了一个算法类
- 例如,给定排序问题和比较运算,就可以确定一个算法类。可以证明基于关键字比较的排序问题算法类在最坏情况下的最好时间复杂度为 O ( n log n ) O(n\log n) O(nlogn)
算法的两种时间复杂度
对于相同输入规模 n n n 的不同实例,算法的基本运算次数也不一样,可定义两种时间复杂度
- 最坏情况下的时间复杂度 W ( n ) W(n) W(n):算法求解输入规模为 n n n 的实例所需要的最长时间
- 平均情况下的时间复杂度
A
(
n
)
A(n)
A(n):在给定同样规模为
n
n
n 的输入实例的概率分布下,算法求解这些实例所需要的平均时间
- 设
S
S
S 是输入规模为
n
n
n 的实例集;实例
I
∈
S
I∈S
I∈S 的概率是
P
I
P_I
PI;算法对实例
I
I
I 执行的基本运算次数是
t
I
t_I
tI
A ( n ) = ∑ I ∈ S P I t I A(n)=\sum_{I\in S}P_It_I A(n)=I∈S∑PItI
- 设
S
S
S 是输入规模为
n
n
n 的实例集;实例
I
∈
S
I∈S
I∈S 的概率是
P
I
P_I
PI;算法对实例
I
I
I 执行的基本运算次数是
t
I
t_I
tI
函数的渐近的界
O , Ω , o , ω , Θ O,\Omega,o,\omega,\Theta O,Ω,o,ω,Θ 符号
大 O O O 符号
- 定义:设
f
f
f 和
g
g
g 是定义域为自然数集
N
N
N 上的函数. 若存在正数
c
c
c 和
n
0
n_0
n0,使得对一切
n
≥
n
0
n\geq n_0
n≥n0 有 (我们只关注非常大的
n
n
n)
0 ≤ f ( n ) ≤ c g ( n ) 0 \leq f(n) \leq c g(n) 0≤f(n)≤cg(n)成立, 则称 f ( n ) f(n) f(n) 的 渐近的上界 是 g ( n ) g(n) g(n), 记作
f ( n ) = O ( g ( n ) ) f (n) = O(g(n)) f(n)=O(g(n)) - 若 f ( n ) = O ( g ( n ) ) f (n) = O(g(n)) f(n)=O(g(n)) ,则 f ( n ) f(n) f(n) 的阶不高于 g ( n ) g(n) g(n) 的阶
- 常函数可以写作 O ( 1 ) O(1) O(1)
例
设
f
(
n
)
=
n
2
+
n
f(n) = n^2 + n
f(n)=n2+n,则
- f ( n ) = O ( n 2 ) f (n)=O(n^2) f(n)=O(n2),取 c = 2 , n 0 = 1 c=2,n_0 =1 c=2,n0=1 即可
- f ( n ) = O ( n 3 ) f (n)=O(n^3) f(n)=O(n3),取 c = 1 , n 0 = 2 c=1,n_0 =2 c=1,n0=2 即可
大 Ω \Omega Ω 符号
- 定义:设
f
f
f 和
g
g
g 是定义域为自然数集
N
N
N 上的函数. 若存在正数
c
c
c 和
n
0
n_0
n0,使得对一切
n
≥
n
0
n\geq n_0
n≥n0 有
0 ≤ c g ( n ) ≤ f ( n ) 0 \leq c g(n) \leq f(n) 0≤cg(n)≤f(n)成立, 则称 f ( n ) f(n) f(n) 的 渐近的下界 是 g ( n ) g(n) g(n), 记作
f ( n ) = Ω ( g ( n ) ) f (n) = \Omega(g(n)) f(n)=Ω(g(n)) - 若 f ( n ) = Ω ( g ( n ) ) f (n)= \Omega(g(n)) f(n)=Ω(g(n)),则 f ( n ) f(n) f(n) 的阶不低于 g ( n ) g(n) g(n) 的阶.
例
设
f
(
n
)
=
n
2
+
n
f(n) = n^2 + n
f(n)=n2+n,则
- f ( n ) = Ω ( n 2 ) f (n)=\Omega(n^2) f(n)=Ω(n2),取 c = 1 , n 0 = 1 c=1,n_0 =1 c=1,n0=1 即可
- f ( n ) = Ω ( 100 n ) f (n)=\Omega(100n) f(n)=Ω(100n),取 c = 1 / 100 , n 0 = 1 c=1/100,n_0 =1 c=1/100,n0=1 即可
小 o 符号
- 定义:设
f
f
f 和
g
g
g 是定义域为自然数集
N
N
N 上的函数. 若对于任意正数
c
c
c 都存在
n
0
n_0
n0,使得对一切
n
≥
n
0
n\geq n_0
n≥n0 有
0 ≤ f ( n ) < c g ( n ) 0 \leq f(n)<c g(n) 0≤f(n)<cg(n)成立, 则记作
f ( n ) = o ( g ( n ) ) f (n) = o(g(n)) f(n)=o(g(n)) - 若 f ( n ) = o ( g ( n ) ) f (n) = o(g(n)) f(n)=o(g(n)),则 f ( n ) f(n) f(n) 的阶低于 g ( n ) g(n) g(n) 的阶.
- 对不同正数 c , n 0 c, n_0 c,n0 不一样. c c c 越小 n 0 n_0 n0 越大.
例
设
f
(
n
)
=
n
2
+
n
f(n) = n^2 + n
f(n)=n2+n,则
f
(
n
)
=
o
(
n
3
)
f (n)=o(n^3)
f(n)=o(n3)
- c ≥ 1 c\geq1 c≥1 显然成立
- 任取
1
>
c
>
0
1>c>0
1>c>0,取
n
0
>
⌈
2
/
c
⌉
n_0>\lceil2/c\rceil
n0>⌈2/c⌉ 即可. 因为
c n ≥ c n 0 > 2 ( 当 n ≥ n 0 ) n 2 + n < 2 n 2 < c n 3 \begin{aligned}&cn\geq cn_0>2\ \ \ \ \ \ \ (当n\geq n_0) \\&n^2+n<2n^2<cn^3\end{aligned} cn≥cn0>2 (当n≥n0)n2+n<2n2<cn3
小 ω \omega ω 符号
- 定义:设
f
f
f 和
g
g
g 是定义域为自然数集
N
N
N 上的函数. 若对于任意正数
c
c
c 都存在
n
0
n_0
n0,使得对一切
n
≥
n
0
n\geq n_0
n≥n0 有
0 ≤ c g ( n ) < f ( n ) 0 \leq c g(n)< f(n) 0≤cg(n)<f(n)成立, 则记作
f ( n ) = ω ( g ( n ) ) f (n) = \omega(g(n)) f(n)=ω(g(n)) - 若 f ( n ) = ω ( g ( n ) ) f (n) = \omega(g(n)) f(n)=ω(g(n)),则 f ( n ) f(n) f(n) 的阶高于 g ( n ) g(n) g(n) 的阶.
- 对不同正数 c , n 0 c, n_0 c,n0 不一样. c c c 越大 n 0 n_0 n0 越大.
例
设
f
(
n
)
=
n
2
+
n
f(n) = n^2 + n
f(n)=n2+n,则
f
(
n
)
=
ω
(
n
)
f (n)=\omega(n)
f(n)=ω(n)
Θ \Theta Θ 符号
- 若
f
(
n
)
=
O
(
g
(
n
)
)
f (n) = O (g(n))
f(n)=O(g(n)) 且
f
(
n
)
=
Ω
(
g
(
n
)
)
f (n) = \Omega(g(n))
f(n)=Ω(g(n)) 成立, 则称
f
(
n
)
f(n)
f(n) 的 渐近的紧的界 是
g
(
n
)
g(n)
g(n),记作
f ( n ) = Θ ( g ( n ) ) f (n) = \Theta(g(n)) f(n)=Θ(g(n)) - f ( n ) f(n) f(n) 的阶与 g ( n ) g(n) g(n) 的阶相等
例
f
(
n
)
=
n
2
+
n
,
g
(
n
)
=
100
n
2
f(n) =n^2 + n, g(n) =100n^2
f(n)=n2+n,g(n)=100n2,那么有
f
(
n
)
=
Θ
(
g
(
n
)
)
f (n) = \Theta(g(n))
f(n)=Θ(g(n))
例:素数测试
问题:
- 若
n
1
/
2
n^{1/2}
n1/2 可在
O
(
1
)
O(1)
O(1) 计算, 基本运算是整除, 以下表示是否正确?
(1) W ( n ) = O ( n 1 / 2 ) W(n)=O(n^{1/2}) W(n)=O(n1/2)
(2) W ( n ) = Θ ( n 1 / 2 ) W(n)=\Theta(n^{1/2}) W(n)=Θ(n1/2)
解
- (1) 对于任何输入实例 n n n,循环内执行整除的次数都不超过 n 1 / 2 n^{1/2} n1/2 次,因此 W ( n ) = O ( n 1 / 2 ) W(n)=O(n^{1/2}) W(n)=O(n1/2)
- (2) 对于输入实例 n n n 为偶数的情况,循环内执行整除的次数为 1 次, W ( n ) = Θ ( 1 ) W(n)=\Theta(1) W(n)=Θ(1),因此 (2) 错误
有关函数渐近的界的定理
定理 1
设
f
f
f 和
g
g
g 是定义域为自然数集合的函数.
- (1) 如果 l i m n → ∞ f ( n ) g ( n ) = c lim_{n\rightarrow\infty} \frac{f (n)}{g(n)}=c limn→∞g(n)f(n)=c, c > 0 c>0 c>0 且 为常数,则 f ( n ) = Θ ( g ( n ) ) f(n)=\Theta(g(n)) f(n)=Θ(g(n))
- (2) 如果 l i m n → ∞ f ( n ) g ( n ) = 0 lim_{n\rightarrow\infty} \frac{f (n)}{g(n)}=0 limn→∞g(n)f(n)=0,则 f ( n ) = o ( g ( n ) ) f(n)=o(g(n)) f(n)=o(g(n))
- (3) 如果 l i m n → ∞ f ( n ) g ( n ) = ∞ lim_{n\rightarrow\infty} \frac{f (n)}{g(n)}=\infty limn→∞g(n)f(n)=∞, c > 0 c>0 c>0 且 为常数,则 f ( n ) = ω ( g ( n ) ) f(n)=\omega(g(n)) f(n)=ω(g(n))
证明
(1)
- 根据极限定义,对于给定正数 ε ε ε 存在某个 n 0 n_0 n0,只要 n ≥ n 0 n ≥ n_0 n≥n0,就有 ∣ f ( n ) g ( n ) − c ∣ < ε |\frac{f (n)}{g(n)}-c|<\varepsilon ∣g(n)f(n)−c∣<ε,所以 c − ε < f ( n ) g ( n ) < c + ε c-\varepsilon<\frac{f (n)}{g(n)}<c+\varepsilon c−ε<g(n)f(n)<c+ε
- 取 ε = c / 2 \varepsilon=c/2 ε=c/2,有 c / 2 < f ( n ) g ( n ) < 3 c / 2 < 2 c c/2<\frac{f (n)}{g(n)}<3c/2<2c c/2<g(n)f(n)<3c/2<2c;因此 f ( n ) ≤ 2 c g ( n ) f(n)\leq 2cg(n) f(n)≤2cg(n), f ( n ) ≥ ( c / 2 ) g ( n ) f(n)\geq (c/2)g(n) f(n)≥(c/2)g(n);于是 f ( n ) = O ( g ( n ) ) = Ω ( g ( n ) ) = Θ ( g ( n ) ) f(n)=O(g(n))=\Omega(g(n))=\Theta(g(n)) f(n)=O(g(n))=Ω(g(n))=Θ(g(n))
估计函数的阶
例1
设
f
(
n
)
=
1
2
n
2
−
3
n
f(n)=\frac{1}{2}n^2-3n
f(n)=21n2−3n,证明
f
(
n
)
=
Θ
(
n
2
)
f(n)=\Theta(n^2)
f(n)=Θ(n2)
解
l
i
m
n
→
∞
1
2
n
2
−
3
n
n
2
=
1
2
lim_{n\rightarrow\infty}\frac{\frac{1}{2}n^2-3n}{n^2}=\frac{1}{2}
limn→∞n221n2−3n=21
例2
证明:多项式函数的阶低于指数函数的阶
n
d
=
o
(
r
n
)
,
r
>
1
,
d
>
0
n^d = o(r^n),r >1,d > 0
nd=o(rn),r>1,d>0解
不妨设
d
d
d 为正整数,
l
i
m
n
→
∞
n
d
r
n
=
l
i
m
n
→
∞
d
n
d
−
1
r
n
l
n
r
=
l
i
m
n
→
∞
d
2
n
d
−
2
r
n
(
l
n
r
)
2
=
.
.
.
=
l
i
m
n
→
∞
d
d
r
n
(
l
n
r
)
d
=
0
lim_{n\rightarrow\infty}\frac{n^d}{r^n}=lim_{n\rightarrow\infty}\frac{dn^{d-1}}{r^nlnr}=lim_{n\rightarrow\infty}\frac{d^2n^{d-2}}{r^n(lnr)^2} \\=...=lim_{n\rightarrow\infty}\frac{d^d}{r^n(lnr)^d}=0
limn→∞rnnd=limn→∞rnlnrdnd−1=limn→∞rn(lnr)2d2nd−2=...=limn→∞rn(lnr)ddd=0
例3
证明:对数函数的阶低于幂函数的阶
l
n
n
=
o
(
n
d
)
,
d
>
0
ln\ n = o (n^d ),d > 0
ln n=o(nd),d>0解
l
i
m
n
→
∞
l
n
n
n
d
=
l
i
m
n
→
∞
1
n
d
n
d
−
1
=
l
i
m
n
→
∞
1
d
n
d
=
0
lim_{n\rightarrow\infty}\frac{ln\ n}{n^d}=lim_{n\rightarrow\infty}\frac{\frac{1}{n}}{dn^{d-1}}=lim_{n\rightarrow\infty}\frac{1}{dn^d}=0
limn→∞ndln n=limn→∞dnd−1n1=limn→∞dnd1=0
定理 2
设函数
f
,
g
,
h
f, g, h
f,g,h 的定义域为自然数集合,
- (1) 如果 f = O ( g ) f=O(g) f=O(g) 且 g = O ( h ) g=O(h) g=O(h),那么 f = O ( h ) f=O(h) f=O(h)
- (2) 如果 f = Ω ( g ) f=Ω(g) f=Ω(g) 且 g = Ω ( h ) g=Ω(h) g=Ω(h),那么 f = Ω ( h ) f =Ω (h) f=Ω(h)
- (3) 如果 f = Θ ( g ) f=Θ(g) f=Θ(g) 和 g = Θ ( h ) g=Θ(h) g=Θ(h),那么 f = Θ ( h ) f =Θ (h) f=Θ(h)
- 函数的阶之间的关系具有传递性,因此可以方便地建立一系列函数的阶的排列顺序
例
按照阶从高到低排序以下函数:
f
(
n
)
=
(
n
2
+
n
)
/
2
,
g
(
n
)
=
10
n
h
(
n
)
=
1.
5
n
,
t
(
n
)
=
n
1
/
2
f(n)=(n^2+n)/2,g(n)=10n\\ h(n)=1.5^n ,t(n)=n^{1/2}
f(n)=(n2+n)/2,g(n)=10nh(n)=1.5n,t(n)=n1/2解
h
(
n
)
=
ω
(
f
(
n
)
)
,
f
(
n
)
=
ω
(
g
(
n
)
)
,
g
(
n
)
=
ω
(
t
(
n
)
)
,
h(n) = ω(f(n)), f(n) = ω(g(n)), g(n) = ω(t(n)),
h(n)=ω(f(n)),f(n)=ω(g(n)),g(n)=ω(t(n)),因此排序:
h
(
n
)
,
f
(
n
)
,
g
(
n
)
,
t
(
n
)
h(n), f(n), g(n), t(n)
h(n),f(n),g(n),t(n)
定理 3
- 假设函数
f
f
f 和
g
g
g 的定义域为自然数集,若对某个其它函数
h
h
h, 有
f
=
O
(
h
)
f =O(h)
f=O(h) 和
g
=
O
(
h
)
g=O(h)
g=O(h),那么
f + g = O ( h ) . f + g = O(h). f+g=O(h).该性质可以推广到有限个函数. - 推论:若
g
=
O
(
f
)
g=O(f)
g=O(f),则
f
+
g
=
Θ
(
f
)
f+g=\Theta(f)
f+g=Θ(f)
- 算法由有限步骤构成. 算法的时间复杂度只要取各步时间复杂度函数的上界中最高阶的函数即可.
几类重要的函数
阶的高低
- 至少指数级 (爆炸性增长): 2 n , 3 n , n ! , ( l o g n ) l o g n = n l o g l o g n 2^n, 3^n, n!,(logn)^{logn}=n^{loglogn} 2n,3n,n!,(logn)logn=nloglogn, …
- 多项式级 (以一个多项式作为渐近上界): n , n 2 , n l o g n , l o g ( n ! ) , a l o g b n n, n^2, nlogn,log(n!),a^{log_b n} n,n2,nlogn,log(n!),alogbn, …
- 对数多项式级: l o g n , l o g 2 n , l o g n , l o g l o g n logn,log^2n,\sqrt{logn}, loglogn logn,log2n,logn,loglogn, …
- 常数级: 1 , n 1 / l o g n 1,n^{1/logn} 1,n1/logn,…
如果算法在多项式级以上,则认为算法实际不可计算,即为 NP-hard 问题
对数函数
-
l
o
g
k
n
=
Θ
(
l
o
g
l
n
)
log_kn = Θ (log_l n)
logkn=Θ(logln)
- 因此常常省略对数函数的底
- 证: l i m n → ∞ l o g k n l o g l n = l i m n → ∞ l o g l n l o g l k ⋅ l o g l n = 1 l o g l k lim_{n\rightarrow\infty}\frac{log_kn}{log_l n}=lim_{n\rightarrow\infty}\frac{log_ln}{log_lk\cdot log_l n}=\frac{1}{log_lk} limn→∞loglnlogkn=limn→∞loglk⋅loglnlogln=loglk1
-
l
o
g
b
n
=
o
(
n
α
)
log_bn = o(n^α)
logbn=o(nα) (
α
>
0
\alpha>0
α>0)
- 证: l o g b n = Θ ( l n n ) , l n n = o ( n α ) log_bn = Θ (ln\ n),ln\ n=o(n^\alpha) logbn=Θ(ln n),ln n=o(nα);因此有 l o g b n = o ( n α ) log_bn = o(n^α) logbn=o(nα)
-
a
l
o
g
b
n
=
n
l
o
g
b
a
a^{log_b n} = n^{log_b a}
alogbn=nlogba
- 说明等式左边的 a l o g b n a^{log_b n} alogbn 其实是多项式级,而非指数级
- 证:等式两边取对数 l o g b n l o g b a = l o g b a l o g b n log_bnlog_ba=log_balog_bn logbnlogba=logbalogbn
指数函数与阶乘
Stirling 公式
n
!
=
2
π
n
(
n
e
)
n
(
1
+
Θ
(
1
n
)
)
n!=\sqrt{2\pi n}(\frac{n}{e})^n(1+\Theta(\frac{1}{n}))
n!=2πn(en)n(1+Θ(n1))
- n ! = o ( n n ) n! = o(n^n) n!=o(nn)
- n ! = ω ( 2 n ) n! = ω (2^n) n!=ω(2n)
- l o g ( n ! ) = Θ ( n l o g n ) log(n!) = Θ(nlogn) log(n!)=Θ(nlogn)
前两个性质通过 Stirling 公式 可证,下面对第三个性质进行证明:
-
l
o
g
(
n
!
)
=
Ω
(
n
l
o
g
n
)
log(n!) = Ω (nlogn)
log(n!)=Ω(nlogn) 的证明
l o g ( n ! ) = ∑ k = 1 n l o g k ≥ ∫ 1 n l o g x d x = l o g e ( n l o g n − n + 1 ) = Ω ( n l o g n ) log(n!) = \sum_{k=1}^nlogk\geq \int_1^nlogxdx=loge(nlogn-n+1)=Ω (nlogn) log(n!)=k=1∑nlogk≥∫1nlogxdx=loge(nlogn−n+1)=Ω(nlogn) -
l
o
g
(
n
!
)
=
O
(
n
l
o
g
n
)
log(n!) = O (nlogn)
log(n!)=O(nlogn) 的证明
l o g ( n ! ) = ∑ k = 1 n l o g k ≤ ∫ 2 n + 1 l o g x d x = O ( n l o g n ) log(n!) = \sum_{k=1}^nlogk\leq\int_2^{n+1}logxdx=O (nlogn) log(n!)=k=1∑nlogk≤∫2n+1logxdx=O(nlogn) - 也可以直接计算:
l i m n → ∞ l o g ( n ! ) n l o g n = l i m n → ∞ l n ( n ! ) / l n 2 n l n n / l n 2 = l i m n → ∞ l n ( n ! ) n l n n = l i m n → ∞ l n ( 2 π n ( n e ) n ( 1 + c n ) ) n l n n = l i m n → ∞ l n 2 π n + n l n n e + l n ( 1 + c n ) n l n n = 1 \begin{aligned}lim_{n\rightarrow\infty}\frac{log(n!)}{nlogn}&=lim_{n\rightarrow\infty}\frac{ln(n!)/ln2}{nln\ n/ln2}=lim_{n\rightarrow\infty}\frac{ln(n!)}{nln\ n} \\&=lim_{n\rightarrow\infty}\frac{ln(\sqrt{2\pi n}(\frac{n}{e})^n(1+\frac{c}{n}))}{nln\ n}\\ &=lim_{n\rightarrow\infty}\frac{ln\sqrt{2\pi n}+nln\frac{n}{e}+ln(1+\frac{c}{n})}{nln\ n}=1\end{aligned} limn→∞nlognlog(n!)=limn→∞nln n/ln2ln(n!)/ln2=limn→∞nln nln(n!)=limn→∞nln nln(2πn(en)n(1+nc))=limn→∞nln nln2πn+nlnen+ln(1+nc)=1
取整函数
- ⌊ x ⌋ \lfloor x\rfloor ⌊x⌋:小于等于 x x x 的最大整数
- ⌈ x ⌉ \lceil x\rceil ⌈x⌉:大于等于 x x x 的最小整数
取整函数的性质
- x − 1 < ⌊ x ⌋ ≤ x ≤ ⌈ x ⌉ < x + 1 x−1<\lfloor x\rfloor≤ x ≤ \lceil x\rceil< x+1 x−1<⌊x⌋≤x≤⌈x⌉<x+1
- ⌊ x + n ⌋ = ⌊ x ⌋ + n , ⌈ x + n ⌉ = ⌈ x ⌉ + n \lfloor x+n\rfloor = \lfloor x\rfloor +n, \lceil x+n\rceil = \lceil x\rceil+n ⌊x+n⌋=⌊x⌋+n,⌈x+n⌉=⌈x⌉+n, n n n 为整数
- ⌈ n 2 ⌉ + ⌊ n 2 ⌋ = n \lceil\frac{n}{2}\rceil+\lfloor \frac{n}{2}\rfloor =n ⌈2n⌉+⌊2n⌋=n
- ⌈ ⌈ n a ⌉ b ⌉ = ⌈ n a b ⌉ \lceil\frac{\lceil\frac{n}{a}\rceil}{b}\rceil=\lceil\frac{n}{ab}\rceil ⌈b⌈an⌉⌉=⌈abn⌉, ⌊ ⌊ n a ⌋ b ⌋ = ⌊ n a b ⌋ \lfloor\frac{\lfloor\frac{n}{a}\rfloor}{b}\rfloor=\lfloor\frac{n}{ab}\rfloor ⌊b⌊an⌋⌋=⌊abn⌋