函数的增长

渐进记号的理论基础
渐进记号是算法分析中的核心数学工具,用于描述函数在输入规模趋于无穷大时的渐进行为。这些记号建立在极限理论的基础上,允许我们忽略常数因子和低阶项,专注于算法的本质特征。
在算法分析中,我们通常关注非负函数 f:N→R+ 的渐进行为,其中输入规模 n 表示问题的规模。渐进记号提供了一种形式化的方法来比较不同函数的增长速度。
Θ-记号:渐进紧确界
Θ-记号(Theta记号)表示函数的渐进紧确界,它同时给出了函数的上界和下界。
形式化定义:设 f(n) 和 为定义在正整数集上的函数。我们称 ,当且仅当存在正常数 、 和 ,使得对于所有 ,都有:
g(n)
f(n)=Θ(g(n)) c1⋅g(n)≤f(n)≤c2⋅g f(n)=Θ(g(n))⟺∃c
- 自反性:f(n)=Θ(f(n))
- 对称性:若 f(n)=Θ(g(n)),则
证明示例:证明 3n2+2n+1=Θ(n2)
确定上界:对于 n≥1,有 3n2+2n+。取 ,,则 对所有 成立。
Θ-记号提供了函数增长速度的精确描述,它表明 f(n) 和 g(n) 在渐近意义下具有相同的增长阶。
O-记号:渐进上界
O-记号(大O记号)表示函数的渐进上界,用于描述算法在最坏情况下的性能上界。
形式化定义:设 f(n) 和 g(n) 为定义在正整数集上的函数。我们称 f(n)=O(g(n)),当且仅当存在正常数 c 和 ,使得对于所有 ,都有:
f(n)≤c⋅g(n) f(n)=O(g(n))⟺∃c>0,∃n
- 自反性:f(n)=O(f(n))
- 传递性:若 f(n)=O(g(n)) 且 ,则
证明示例:证明 2n+3=O(n)
对于 n≥3,有 2n+3≤2n+n=3n。取 c=3,,则 对所有 成立,因此 。
O-记号在算法分析中最为常用,它描述了算法时间复杂度的上界,即最坏情况下的性能保证。
Ω-记号:渐进下界
Ω-记号(大Omega记号)表示函数的渐进下界,用于描述算法在最好情况下的性能下界。
形式化定义:设 f(n) 和 g(n) 为定义在正整数集上的函数。我们称 f(n)=Ω(g(n)),当且仅当存在正常数 c 和 ,使得对于所有 ,都有:
f(n)≥c⋅g(n) f(n)=Ω(g(n))⟺∃c>0,∃n
- 自反性:f(n)=Ω(f(n))
- 传递性:若 f(n)=Ω(g(n)) 且 ,则
证明示例:证明 n2+n=Ω(n2)
对于 n≥1,有 n2+n≥n2。取 c=1,,则 对所有 成立,因此 。
Ω-记号描述了算法时间复杂度的下界,表明无论算法如何优化,其时间复杂度都不可能低于该下界。
三个记号的关系
Θ-记号、O-记号和Ω-记号之间存在重要的数学关系。
定理:f(n)=Θ(g(n)) 当且仅当 f(n)=O(g(n)) 且 。
必要性(⇒):假设 f(n)=Θ(g(n)),则存在 c,,,使得对所有 ,有 。
o-记号与 ω-记号
o-记号和ω-记号提供了比O-记号和Ω-记号更严格的比较关系。
o-记号(小o记号)的形式化定义:f(n)=o(g(n)) 当且仅当:
‘n→∞limg(n)f(n)=0‘ 等价地,对于任意正常数 c>0,存在 n0∈N,使得对所有 n≥n0,都有 。
ω-记号(小omega记号)的形式化定义:f(n)=ω(g(n)) 当且仅当:
‘n→∞limg(n)f(n)=∞‘ 等价地,对于任意正常数 c>0,存在 n0∈N,使得对所有 n≥n0,都有 。
- 若 f(n)=o(g(n)),则 f(n)=O(g(n)),但反之不成立
- 若 ,则 ,但反之不成立
证明示例:证明 n=o(n2)
‘n→∞limn2n= 因此 n=o(n2)。
常用函数的增长速度
在算法分析中,不同函数类型的增长速度存在严格的数学关系。我们通过极限理论可以严格证明这些函数的增长速度排序。
增长速度的严格排序
对于常见的函数类型,当 n→∞ 时,增长速度的严格排序为:
O(1)≺O(logn)≺O(n 数学证明(以 logn=o(n) 为例):
‘n→∞limnlogn= 因此 logn=o(n),即对数函数的增长速度严格慢于线性函数。
函数类型及其渐近性质
所有对数函数的增长速度在渐近意义下相同,即 logan=Θ(logbn) 对任意 a,b 成立。这是因为 ,常数因子 在渐近分析中可以忽略。因此,在算法分析中我们通常省略对数的底数,统一记为 。
增长速度比较的数学分析
定理:对于任意常数 a>1 和 b>0,有 nb=o(an)。
n→∞lima 定理:对于任意常数 a>1,有 an=o(n!)。
证明:使用斯特林公式 n!∼2πn(en,可得:
n→∞limn!
渐进记号的性质与运算
渐进记号满足一系列重要的数学性质,这些性质在算法分析中具有重要应用。
基本运算性质
- 若 f1(n)=O(g1(n)) 且 f,则
- 若 f1(n)=O(g1(n)) 且 f,则
标量乘法:对于任意常数 c>0,c⋅f(n)=Θ(f(n))。
记号之间的关系
对偶关系:f(n)=O(g(n)) 当且仅当 g(n)=Ω(f(n))。
- 若 f(n)=o(g(n)),则 f(n)=O(g(n))
- 若 ,则
练习
-
严格证明以下等式的正确性:
- 证明 3n2+2n+1=O(n2),并给出具体的常数 c 和
def mystery_function(n):
result = 0
for i in range(n):
for j in range(i, n):
for k in range(j, n):
result += 1
return result
要求:计算内层循环的执行次数,并用渐进记号表示结果。
- 算法选择的理论分析:
在以下场景中,从理论角度分析应选择何种时间复杂度的算法,并说明理由:
- 排序1000个用户ID(考虑常数因子和实际性能)
- 在100万个文件中查找特定文件(考虑预处理成本)
- 计算100个城市之间的最短路径(考虑问题规模与算法复杂度)
- 验证一个100位数字是否为质数(考虑问题特性)
(
n
)
1
>
0,∃c2>
0,∃n0∈
N,∀n≥
n0:
c1⋅
g(n)≤
f(n)≤
c2⋅
g(n)
g(n)=
Θ(f(n))
传递性:若 f(n)=Θ(g(n)) 且 g(n)=Θ(h(n)),则 1≤
3n2+
2n2+
n2=
6n2
f(n)≤6n2 确定下界:对于 n≥1,有 3n2+2n+1≥。取 ,,则 对所有 成立。
结论:由于存在 c1=3,c2=6,,使得 对所有 成立,因此 。
n0
0
∈
N,∀n≥
n0:
f(n)≤
c⋅
g(n)
g(n)=
O(h(n))
f(n)=O(h(n)) 加法性质:若 f1(n)=O(g1(n)) 且 f,则 乘法性质:若 f1(n)=O(g1(n)) 且 f,则 n0=3
2n+3≤3n 2n+3=O(n) n0
0
∈
N,∀n≥
n0:
f(n)≥
c⋅
g(n)
g(n)=
Ω(h(n))
f(n)=Ω(h(n)) 对偶性:f(n)=O(g(n)) 当且仅当 g(n)=Ω(f(n)) n0=1
n2+n≥n2 n2+n=Ω(n2)
f
(
n
)
=
Ω(g(n))
1
>
0
n0∈N c1⋅g(n)≤f(n)≤c2⋅g 由 f(n)≤c2⋅g(n) 可得 (取 )。
由 f(n)≥c1⋅g(n) 可得 (取 )。
充分性(⇐):假设 f(n)=O(g(n)) 且 f(n,则存在 ,,,,使得对所有 有 ,对所有 有 。
取 n0=max(n1,n,则对所有 ,有 ,因此 。
f(n)<c⋅g(n)
f(n)>c⋅g(n)
f
(
n
)
=
ω(g(n))
f(n)=Ω(g(n)) f(n)=o(g(n)) 当且仅当 g(n)=ω(f(n)) n→∞lim
n1
=
0‘
)
≺
O(n)≺
O(nlogn)≺
O(n2)≺
O(n3)≺
O(2n)≺
O(n!)
n→∞lim11/n=
n→∞limn1=
0‘
n
→
∞
f
(
n
)
=
c
| 对数函数 | Θ(logn) | f(n)=logan,其中 a>1 | (对任意 ) |
| 线性函数 | Θ(n) | f(n)=cn+d,其中 c>0 | |
| 线性对数函数 | Θ(nlogn) | f(n)=cnlogn+dn,其中 c>0 |
| 平方函数 | Θ(n2) | f(n)=cn2+dn+e,其中 |
| 立方函数 | Θ(n3) | f(n)=cn3+o(n,其中 |
| 指数函数 | Θ(2n) | f(n)=c⋅an,其中 a>, |
| 阶乘函数 | Θ(n!) | f(n)=n! | limn→∞(对任意 ) |
>
1
logan=logbal logba1 n
nb
=
n→∞limanlnab⋅nb−1=
⋯=
n→∞liman(lna)bb!=
0
)
n
an
=
0
2
(
n
)
=
O(g2(n))
f1(n)+f2(n)=O(max(g 若 f1(n)=Θ(g1(n)) 且 f,则 2
(
n
)
=
O(g2(n))
f1(n)⋅f2(n)=O(g 若 f1(n)=Θ(g1(n)) 且 f,则
f
(
n
)
=
ω(g(n))
f(n)=Ω(g(n)) 若 f(n)=Θ(g(n)),则 f(n)=O(g(n)) 且 n0
证明 n3+100n2=Θ(n3),给出完整的上下界证明 证明 2n=O(n!),使用极限定义 证明或反驳:logn=Ω(n) 证明 n2=o(n3),使用极限定义
函数增长速度排序:
将以下函数按照增长速度从慢到快严格排序,并证明相邻函数之间的关系:
f1(n)=n2,f2(n),,,,,,
算法复杂度分析:
分析以下代码片段的时间复杂度,给出严格的数学证明:
f
(
n
)
=
Θ(h(n))
3
n2
f(n)≥3n2 n0=1
3n2≤3n2+2n+1≤6n2 3n2+2n+1=Θ(n2) 2
(
n
)
=
O(g2(n))
f1(n)+f2(n)=O(max(g 2
(
n
)
=
O(g2(n))
f1(n)⋅f2(n)=O(g (
n
)
f(n)=
O(g(n))
f(n)=
Ω(g(n))
)
=
Ω(g(n))
f(n)≤c2⋅g(n) f(n)≥c1⋅g(n) 2
)
c1⋅g(n)≤f(n)≤c2⋅g f(n)=Θ(g(n)) limn→∞nϵlogn=0
limn→∞nf(n)=
c
| limn→∞nlognf(n)=c |
c>0
| limn→∞n2f(n)=c |
3
)
| limn→∞n3f(n)=c |
1
| limn→∞bnf(n)=∞(对任意 ) |
anf(n)
=
∞
o
g
b
n
a
n
=
a
e
)n
=
1
(
n
)
,
g2
(
n
)))
2
(
n
)
=
Θ(g2(n))
f1(n)+f2(n)=Θ(max(g
1
(
n
)
⋅
g2(n))
2
(
n
)
=
Θ(g2(n))
f1(n)⋅f2(n)=Θ(g
f
(
n
)
=
Ω(g(n))
=
2n
f3(n)=n! f4(n)=logn f5(n)=n f6(n)=nlogn f7(n)=n3 f8(n)=n 1
(
n
)
,
g2
(
n
)))
1
(
n
)
⋅
g2(n))
(
n
)
b<a
1
(
n
)
,
g2
(
n
)))
1
(
函数的增长 | 自在学n
)
⋅
g2(n))