算法
- 算法是指解决问题的一种方法或一个过程。
- 算法是若干指令的有穷序列,满足性质:
- 输入:有外部提供的量作为算法的输入。
- 输出:算法产生至少一个量作为输出。
- 确定性:组成算法的每条指令是清晰,无歧义的。
- 有限性:算法中每条指令的执行次数是有限的,执行每条指令的时间也是有限的。
程序
-
程序是算法用某种程序设计语言的具体实现。
-
程序可以不满足算法的性质(4)。
例如操作系统,是一个在无限循环中执行的程序,因而不是一个算法。
操作系统的各种任务可看成是单独的问题,每一个问题由操作系统中的一个子程序通过特定的算法来实现。该子程序得到输出结果后便终止。
问题求解的关键
-
建模:对输入参数和解给出形式化或半形式化的描述
-
设计算法:
采用什么算法设计技术
正确性——是否对所有的示例都得到正确的解
-
分析算法:效率
问题计算复杂度的界定
举例:排序算法的效率
算法 | 最坏情况下 | 平均情况下 |
---|---|---|
插入排序 | O ( n 2 ) O(n^2) O(n2) | O ( n 2 ) O(n^2) O(n2) |
冒泡排序 | O ( n 2 ) O(n^2) O(n2) | O ( n 2 ) O(n^2) O(n2) |
快速排序 | O ( n 2 ) O(n^2) O(n2) | O ( n l o g n ) O(nlogn) O(nlogn) |
堆排序 | O ( n l o g n ) O(nlogn) O(nlogn) | O ( n l o g n ) O(nlogn) O(nlogn) |
二分归并排序 | O ( n l o g n ) O(nlogn) O(nlogn) | O ( n l o g n ) O(nlogn) O(nlogn) |
好的算法:提高求解问题的效率、节省存储空间
算法研究的目标
问题 – 建模并寻找算法 【算法设计技术】
算法 – 算法的评价【算法分析方法】
算法类 – 问题复杂度估计【问题复杂度分析】
问题类 – 能够求解的边界【计算复杂性理论】
算法及其时间复杂度
问题及实例
-
问题:需要回答的一般性提问,通常含若干参数
-
问题描述:
定义问题参数(集合、变量、函数、序列等)
说明每个参数的取值范围及参数间的关系
定义问题的解
说明解满足的条件(优化目标或约束条件) -
问题实例:
参数的一组赋值可得到问题的一个实例
算法
- 算法:
有限条指令的序列
这个指令序列确定了解决某个问题的一系列运算或操作 - 算法A解问题P:
把问题P的任何实例作为算法A的输入
每步计算是确定性的
A能够在有限步停机
输出该实例的正确的解
基本运算与输入规模
-
算法时间复杂度:针对指定基本运算,计数算法所做运算次数
-
基本运算:比较、加法、乘法、置指针、交换…
排序:元素之间的比较
检索:被检索元素 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 ijk 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
… -
算法基本运算次数可表为输入规模的函数
-
给定问题和基本运算就决定了一个算法类
算法的两种时间复杂度
-
最坏情况下的时间复杂度 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\in 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)=\Sigma_{I\in S}P_It_I A(n)=ΣI∈SPItI
在某些情况下可以假定每个输入实例概率相等
算法复杂性分析
- 算法复杂性 = 算法所需要的计算机资源
- 算法的时间复杂性 T ( n ) T(n) T(n)
- 算法的空间复杂性 S ( n ) S(n) S(n)
- 其中 n n n 是问题的规模(输入大小)
算法的时间复杂性
- 最坏情况下的时间复杂性 – T m a x ( n ) = m a x { T ( I ) ∣ s i z e ( I ) = n } T_{max}(n)=max\{T(I)|size(I)=n\} Tmax(n)=max{T(I)∣size(I)=n}
- 最好情况下的时间复杂性 – T m i n ( n ) = m i n { T ( I ) ∣ s i z e ( I ) = n } T_{min}(n)=min\{T(I)|size(I)=n\} Tmin(n)=min{T(I)∣size(I)=n}
- 平均情况下的时间复杂性 – T a v g ( n ) = Σ s i z e ( I ) = n p ( I ) T ( I ) T_{avg}(n)=\Sigma_{size(I)=n}p(I)T(I) Tavg(n)=Σsize(I)=np(I)T(I)
【其中 I I I 是问题的规模为 n n n 的实例, p ( I ) p(I) p(I) 是实例 I I I 出现的概率】
算法渐近复杂性
T ( n ) → ∞ , a s n → ∞ T(n)\to \infty,\ as\ n\to \infty T(n)→∞, as n→∞ 且 T ( n ) − t ( n ) T ( n ) → 0 , a s n → ∞ \frac{T(n)-t(n)}{T(n)}\to 0,\ as \ n\to \infty T(n)T(n)−t(n)→0, as n→∞
t ( n ) t(n) t(n) 是 T ( n ) T(n) T(n) 的渐近性态,为算法的渐近复杂性。在数学上, t ( n ) t(n) t(n) 是 T ( n ) T(n) T(n) 的渐近表达式,是 T ( n ) T(n) T(n) 略去低阶项留下的主项,它比 T ( n ) T(n) T(n) 简单。
渐近分析的记号
在下面的讨论中,对所有 n n n , f ( n ) ≥ 0 , g ( n ) ≥ 0 f(n)\geq 0,\ g(n)\geq 0 f(n)≥0, g(n)≥0 。
-
渐近上界记号 O O O
O ( g ( n ) ) = { f ( n ) ∣ 存在正常数 c 和 n 0 使得对所有 n ≥ n 0 有 : 0 ≤ f ( n ) ≤ c g ( n ) } O(g(n))=\{f(n)|存在正常数c和n_0使得对所有n\geq n_0有:0\leq f(n)\leq cg(n)\} O(g(n))={f(n)∣存在正常数c和n0使得对所有n≥n0有:0≤f(n)≤cg(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) 的阶
-
渐近下界记号 Ω \Omega Ω
Ω ( g ( n ) ) = { f ( n ) ∣ 存在正常数 c 和 n 0 使得对所有 n ≥ n 0 有 : 0 ≤ c g ( n ) ≤ f ( n ) } \Omega(g(n))=\{f(n)|存在正常数c和n_0使得对所有n\geq n_0有:0\leq cg(n)\leq f(n)\} Ω(g(n))={f(n)∣存在正常数c和n0使得对所有n≥n0有:0≤cg(n)≤f(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) 的阶
-
非紧上界记号 o o o
o ( g ( n ) ) = { f ( n ) ∣ 对于任何正常数 c > 0 , 存在正数 c 和 n 0 使得对所有 n ≥ n 0 有 : 0 ≤ f ( n ) ≤ c g ( n ) } o(g(n))=\{f(n)|对于任何正常数c\gt 0,存在正数c和n_0使得对所有n\geq n_0有:0\leq f(n)\leq cg(n)\} o(g(n))={f(n)∣对于任何正常数c>0,存在正数c和n0使得对所有n≥n0有:0≤f(n)≤cg(n)}
等价于 f ( n ) g ( n ) → 0 , a s n → ∞ \frac{f(n)}{g(n)}\to 0,\ as\ n\to\infty g(n)f(n)→0, as 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) 的阶
-
非紧下界记号 ω \omega ω
ω ( g ( n ) ) = { f ( n ) ∣ 对于任何正常数 c > 0 , 存在正数 c 和 n 0 使得对所有 n ≥ n 0 有 : 0 ≤ c g ( n ) ≤ f ( n ) } \omega(g(n))=\{f(n)|对于任何正常数c\gt 0,存在正数c和n_0使得对所有n\geq n_0有:0\leq cg(n)\leq f(n)\} ω(g(n))={f(n)∣对于任何正常数c>0,存在正数c和n0使得对所有n≥n0有:0≤cg(n)≤f(n)}
等价于 f ( n ) g ( n ) → ∞ , a s n → ∞ \frac{f(n)}{g(n)}\to \infty,\ as\ n\to\infty g(n)f(n)→∞, as n→∞ 。
f ( n ) ∈ ω ( g ( n ) ) ⇔ g ( n ) ∈ o ( f ( n ) ) f(n)\in \omega(g(n))\Leftrightarrow g(n)\in o(f(n)) f(n)∈ω(g(n))⇔g(n)∈o(f(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) 的阶
-
紧渐近界记号 Θ \Theta Θ
Θ ( g ( n ) ) = { f ( n ) ∣ 存在正数 c 1 , c 2 和 n 0 使得对所有 n ≥ n 0 有 : c 1 g ( n ) ≤ f ( n ) ≤ c 2 g ( n ) } \Theta(g(n))=\{f(n)|存在正数c_1,c_2和n_0使得对所有n\geq n_0有:c_1g(n)\leq f(n)\leq c_2g(n)\} Θ(g(n))={f(n)∣存在正数c1,c2和n0使得对所有n≥n0有:c1g(n)≤f(n)≤c2g(n)}
Θ ( g ( n ) ) = O ( g ( n ) ) ∩ Ω ( g ( n ) ) \Theta(g(n))=O(g(n))\cap\Omega(g(n)) Θ(g(n))=O(g(n))∩Ω(g(n))
f ( n ) = Θ ( g ( n ) ) f(n)=\Theta(g(n)) f(n)=Θ(g(n)) 的确切意义是: f ( n ) ∈ Θ ( g ( n ) ) f(n)\in \Theta(g(n)) f(n)∈Θ(g(n)) 。
渐近分析中函数比较
- 【渐近上界记号】 f ( n ) = O ( g ( n ) ) ≈ a ≤ b f(n)=O(g(n))\approx a\leq b f(n)=O(g(n))≈a≤b
- 【渐近下界记号】 f ( n ) = Ω ( g ( n ) ) ≈ a ≥ b f(n)=\Omega(g(n))\approx a\geq b f(n)=Ω(g(n))≈a≥b
- 【紧渐近界记号】 f ( n ) = Θ ( g ( n ) ) ≈ a = b f(n)=\Theta(g(n))\approx a= b f(n)=Θ(g(n))≈a=b
- 【非紧上界记号】 f ( n ) = o ( g ( n ) ) ≈ a < b f(n)=o(g(n))\approx a\lt b f(n)=o(g(n))≈a<b
- 【非紧下界记号】 f ( n ) = ω ( g ( n ) ) ≈ a > b f(n)=\omega(g(n))\approx a\gt b f(n)=ω(g(n))≈a>b
渐近分析记号的若干性质
-
传递性
f ( n ) = Θ ( g ( n ) ) , g ( n ) = Θ ( h ( n ) ) ⇒ f ( n ) = Θ ( h ( n ) ) f(n)=\Theta(g(n)),\ g(n)=\Theta(h(n))\Rightarrow f(n)=\Theta(h(n)) f(n)=Θ(g(n)), g(n)=Θ(h(n))⇒f(n)=Θ(h(n))
f ( n ) = O ( g ( n ) ) , g ( n ) = O ( h ( n ) ) ⇒ f ( n ) = O ( h ( n ) ) f(n)=O(g(n)),\ g(n)=O(h(n))\Rightarrow f(n)=O(h(n)) f(n)=O(g(n)), g(n)=O(h(n))⇒f(n)=O(h(n))
f ( n ) = Ω ( g ( n ) ) , g ( n ) = Ω ( h ( n ) ) ⇒ f ( n ) = Ω ( h ( n ) ) f(n)=\Omega(g(n)),\ g(n)=\Omega(h(n))\Rightarrow f(n)=\Omega(h(n)) f(n)=Ω(g(n)), g(n)=Ω(h(n))⇒f(n)=Ω(h(n))
f ( n ) = o ( g ( n ) ) , g ( n ) = o ( h ( n ) ) ⇒ f ( n ) = o ( h ( n ) ) f(n)=o(g(n)),\ g(n)=o(h(n))\Rightarrow f(n)=o(h(n)) f(n)=o(g(n)), g(n)=o(h(n))⇒f(n)=o(h(n))
f ( n ) = ω ( g ( n ) ) , g ( n ) = ω ( h ( n ) ) ⇒ f ( n ) = ω ( h ( n ) ) f(n)=\omega(g(n)),\ g(n)=\omega(h(n))\Rightarrow f(n)=\omega(h(n)) f(n)=ω(g(n)), g(n)=ω(h(n))⇒f(n)=ω(h(n))
-
反身性
f ( n ) = Θ ( f ( n ) ) f(n)=\Theta(f(n)) f(n)=Θ(f(n))
f ( n ) = O ( f ( n ) ) f(n)=O(f(n)) f(n)=O(f(n))
f ( n ) = Ω ( f ( n ) ) f(n)=\Omega(f(n)) f(n)=Ω(f(n))
-
对称性
f ( n ) = Θ ( g ( n ) ) ⇔ g ( n ) = Θ ( f ( n ) ) f(n)=\Theta(g(n))\Leftrightarrow g(n)=\Theta(f(n)) f(n)=Θ(g(n))⇔g(n)=Θ(f(n))
-
互对称性
f ( n ) = O ( g ( n ) ) ⇔ g ( n ) = Ω ( f ( n ) ) f(n)=O(g(n))\Leftrightarrow g(n)=\Omega(f(n)) f(n)=O(g(n))⇔g(n)=Ω(f(n))
f ( n ) = o ( g ( n ) ) ⇔ g ( n ) = ω ( f ( n ) ) f(n)=o(g(n))\Leftrightarrow g(n)=\omega(f(n)) f(n)=o(g(n))⇔g(n)=ω(f(n))
-
算数运算
O ( f ( n ) ) + O ( g ( n ) ) = O ( m a x { f ( n ) , g ( n ) } ) O(f(n))+O(g(n))=O(max\{f(n),g(n)\}) O(f(n))+O(g(n))=O(max{f(n),g(n)})
O ( f ( n ) ) + O ( g ( n ) ) = O ( f ( n ) + g ( n ) ) O(f(n))+O(g(n))=O(f(n)+g(n)) O(f(n))+O(g(n))=O(f(n)+g(n))
O ( f ( n ) ) × O ( g ( n ) ) = O ( f ( n ) × g ( n ) ) O(f(n))×O(g(n))=O(f(n)×g(n)) O(f(n))×O(g(n))=O(f(n)×g(n))
O ( c f ( n ) ) = O ( f ( n ) ) O(cf(n))=O(f(n)) O(cf(n))=O(f(n))
g ( n ) = O ( f ( n ) ) ⇒ O ( f ( n ) ) + O ( g ( n ) ) = O ( f ( n ) ) g(n)=O(f(n))\Rightarrow O(f(n))+O(g(n))=O(f(n)) g(n)=O(f(n))⇒O(f(n))+O(g(n))=O(f(n))
最优算法
问题的计算时间下界为 Ω ( f ( n ) ) \Omega(f(n)) Ω(f(n)) ,则计算时间复杂性为 O ( f ( n ) ) O(f(n)) O(f(n)) 的算法是最优算法。