渐近符号
我们来回顾一下什么是时间复杂度, 这是一个特殊的概念, 用来形式化的解释一个算法所需要的运行时间与输入规模的特定条件下的映射关系. 其中特定条件就是在之前的课程中所描述的最坏, 最优, 平均等条件. 用数学语言表达来看: 其中, 表示最终的运行时间, 表示输入规模, 通过一些额外标记, 如 来表述特定情况.
在数学中, 渐近(Asymptotic) 描述的是函数或序列在某个极限点附近的行为趋势. 本身就是一个函数, 当 时, 可能会无限接近另外一个函数或方程, 对其的分析, 便是本书中一般指的渐近分析. 即分析当自变量趋近于某个极限(在本书中通常表示 )时, 函数或序列如何逼近某个特定的值、曲线或增长模式, 而不一定严格达到它.
这也是我们为什么需要渐近分析的理由, 它帮助我们在面对一个足够大的数据规模(数据规模一般为自然数)时, 仍能较好的对算法的运行时间进行估计. 我们来回顾已经遇到过的两个渐近符号: 和 , 它们本质上是作用于函数的. 我们先将这个 所逼近的函数记作 , 对于 来说, 这两种渐近符号就是与 和其自身有关的集合, 即 (所以前文说 是非形式化的).
既然如此, 那让我们来对这个集合做正式定义:
记号
是本书中常用的渐近符号, 我们来分析一下这个定义:
- 是这个记号所代表集合的成员, 例如我们之前用的.
- 条件是: 存在正常量 和 , 使得所有的 有 . 其中 是一个临界值, 这个临界值之后(包括自身)的所有 都满足渐近关系.
在这里我们通过两个系数正常量 , 控制两个 使得这两个 把 夹在中间. 反着来说, 如果 在 之后被夹在 和 中, 那么 , 并称 是 的 渐近紧确(上下)界(Asymptotic Tight Bound), 简称 (紧)确界 .
xychart-beta
title "紧确上下界示例"
x-axis 0 --> 30
y-axis 0 --> 80
line [3, 0, 7, 8, 16, 32, 64, 128]
line [2, 4, 6, 8, 10, 12, 14, 16]
line [1, 10, 9, 8, 7, 6, 5, 4]
在上面这个图例中, 起点为 的函数为 , 函数为 , 的函数为 . 在 前面它们的大小很难看出规律, 在 之 后显现出, 此时 . 所以 时, , 这个时候夹逼的两个系数为 .
在分析算法一节中, 我们发现最高阶项决定一切, 从而将一个函数转化为关于渐近形式, 这在直觉上是对的, 不过现在我们要来证明:
假设, 我们的想法是对的, 那么, 对于 用除以上式得: 对于上面的 变形, 得 .
因为 , 所以上式最大肯定无法到达 , 可以让.
接着想要找到一个不小于零的最小值, 由于该式的特殊性, 这一步比较难, 设 , 可利用计算机求得: , , 所以可以让 .
所以, 现在选择 , , 即可证明 .
利用反证法, 我们也可以证明 : 假设存在 和 , 使得对所有 , 有 . 然而用 除该式, 得 , 因为 为常量, 所以对任意大的 , 该不等式不可能总成立.
上面的仅作为例子, 对于任意二次函数的证明可以参考练习与回答.
照这样, 我们也可以把其他的记号都定义出来:
记号1
记号在历史上出现的最早, 也最为常用(因为不需要像同时保证一个下界, 因此无需更复杂的数学证明)2.
在定义下一个记号之前让我们先缓一下, 在二分查找一节中我们提到了下面这个问题:
在上述算法中, 插入排序可以在时间内排序每个长度为的个子表(每个子表排序的时间复杂度为, 故). 同样不难看出, 合并子表的时间复杂度是, 综上就有该算法最坏情况下的时间复杂度为. 为了确保任何的取值不能使修改后算法时间复杂度高于原算法, .
让我们来尝试证明它: 这里的核心部分是: 对于, 若3, 试求的取值.
首先观察, 说明的渐近增长率4不超过, 应用我们刚刚所学的符号就可以把不等式转换成:
我们需要展示存在常数 和 , 使得对于所有 , 有:
两边同时除以(假设 ):
展开 , 并变形得:
为了对于所有的, 使上面表达式都成立, 我们需要考虑两种情况:
- 为常数(即 )
那么 也是常数.
因为 将会随 的增长趋向于无穷大
所以, 对于任何常数 , 存在 使得对于 , 不等式成立. 此时:
是满足要求的, 因为我们只需要保证渐近增长率不超过 即可, 同时满足下界当然是可以的, 这也体现了在某些条件下与的相互转换.
- 随 增长
由原不等式变形可得: . 下面的严谨证明我们需要用到下一节的内容, 这里我们简单思考一下:
一般情况下(), 的渐近增长率总小于, 所以上式等价于:
符号
很显然, 是上界, 是上下界都有, 那么此处的就应该能猜到是下界: 与上界的定义非常相似, 不证而明.
上面这三个渐近符号都有一个特点: 紧, 这里的上下界都是可达到的, 下一节中的内容则允许不达到. 另外我们还有另外一种定义方法, 通过函数来反向定义, 如: 这对于其他几种渐近符号也是通用的.
练习与回答
- 试较严格地证明函数 是 .
证明
根据定义, 需找到常数 和 , 使得对所有 , 有:
当 时, 和 因此: 取 , 当 时, 上界成立.
当 时, 和 均为非负数, 因此: 取 , 当 时, 下界成立.
综上, 取 , , , 满足 的条件. 因此, .
- 判断以下函数的渐近关系:
- 与
- 与
由题意, 易知上述两者均有. 详细证明略.
- 严格证明任意二次函数.
对任意二次函数的证明
对于任意二次函数:
需找到常数 和 , 使得对所有 , 有:
当 充分大时, 线性项 和常数项 可以被 放大: 因此: 取 , 则对所有 , 上界成立.
若 , 当 充分大时, 二次项 将主导其他项. 选择 使得: 这等价于: 取 , 则对所有 : 取 , 则下界成立.
在 的情况下, 上述分析对任意二次函数均成立.
-
有时也可读作或简单的记作 Big-O. 事实上, 其他两种符号也可对应的称作 Big-Theta 和 Big-Omega. 但这两者远没有 Big-O 使用得多. ↩
-
与等号的非形式化运用相似, 这里是对于渐近符号的不等式非形式化运用. 此处严格可表示为: ↩
-
渐近增长率(Asymptotic Growth Rate) 是计算机科学和数学中用于描述函数在输入规模 趋近于无穷大时的增长趋势的一种工具. 可以简单理解为渐近增长率就是一个函数渐近分析后的结果. ↩
-
从技术上来讲, 因为不明确下界, 所以一般通过 来描述一个算法的最坏情况. 然而, 绝大部分算法的最坏和最优情况的上下界都不相同, 再加上对一个算法的平均情况描述, 大多数时候就是最坏情况描述, 所以, 其实绝大部分渐近符号都只是在描述一个算法的最坏情况, 本书不对其进行过多区分. ↩