函数的增长

渐进记号的理论基础
渐进记号是算法分析中的核心数学工具,用于描述函数在输入规模趋于无穷大时的渐进行为。这些记号建立在极限理论的基础上,允许我们忽略常数因子和低阶项,专注于算法的本质特征。
在算法分析中,我们通常关注非负函数 f:N→R+ 的渐进行为,其中输入规模 n 表示问题的规模。渐进记号提供了一种形式化的方法来比较不同函数的增长速度。
Θ-记号:渐进紧确界
Θ-记号(Theta记号)表示函数的渐进紧确界,它同时给出了函数的上界和下界。
形式化定义:设 f(n) 和 g(n) 为定义在正整数集上的函数。我们称 f(n)=Θ(g(n)),当且仅当存在正常数 c1、c2 和 n0,使得对于所有 n≥n0,都有:
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,都有 。
与O/Ω记号的关系:
- 若 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)。
证明:应用洛必达法则 b 次:
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位数字是否为质数(考虑问题特性)