【发布时间】:2017-04-22 14:27:50
【问题描述】:
我正在考虑算法的复杂性分析,我想出了这个例子:有一个医疗中心有几个医生;每位医生每周的每个工作日都可以在一个小时的时间段内就诊。 现在,假设我们有一个医生集合,并且每个医生都有一个已排序的预定访问集合,如果我们想查找某个特定时间段是否有任何医生空闲,我们可以编写一个非常基本的算法来做到这一点: /p>
for (Doctor doc: doctors) {
for (Visit visit: doc.visits) {
if (visit.hour == hour && visit.day == day) {
return false;
}
if (visit.day > day) {
break;
}
}
}
return true;
虽然我知道这不是解决问题的最有效方法,但我想知道它的时间复杂度;一开始我考虑了 O(n^2) 的时间复杂度,因为医生和访问的数量会增加,并且代码包含两个嵌套循环,内部循环包含几个恒定时间操作。
但后来我认为医生的数量肯定有一个上限,即居住在中心国家的人口数量(如果我们甚至考虑外国医生,仍然有一个上限,世界人口~ 75 亿);所以时间复杂度似乎降低到线性 O(n),因为内部循环只执行了固定次数。在 Big-O 术语中:O(C*N) = O(n) 其中 C 是常数上限。
不满意,我还以为这个软件不会运行医疗中心一个多世纪,因为我确定在那段时间里它会被重写;所以该软件将只接受到 2117 年的访问,即 - 假设每年 230 个工作日,每天 8 个插槽,184k 个插槽,这也是一个上限。如果你认为这个软件可以持续一个多世纪,那么上限就变成了太阳的预期寿命(大约 50 亿年),之后地球上的生命就会消失。一个更高的上限,但仍然是一个上限。所以时间复杂度现在看起来 O(1),因为 O(C1*C2) = O(1) 其中 C1 是医生上限,C2 是访问上限。
这个推理正确吗?一般来说,在分析算法复杂性时将大数假设为常数是正确的吗?
【问题讨论】:
-
“假设 n 永远不会大于某个常数,f(n) 的复杂度是多少”不是一个有意义的问题。对于任意大的 n,复杂性必然需要考虑 f(n)。
-
使用你的论点,你可能会争辩说数组的快速排序是 O(1),因为世界上最大的计算机有(比如说)64TB 内存,这限制了最大数组快速排序的大小可以工作开。
-
@Paul Hankin:这正是我的想法。那么,如果计算机结构本质上是有限的(因此有上限),为什么还要谈论渐近复杂性呢?我错过了什么?
-
复杂性分析使用与现实不完全对应的计算抽象。尽管如此,它通常会提供有关实际程序效率的有用信息。
-
如果您阅读 Sedgewick 的一些书籍,您会发现他试图建模/预测实际运行时而不是复杂性。但它会导致更难的数学,我想这就是为什么它不是一种常见的技术。参见,例如:youtube.com/watch?v=-hz95qqOdx0
标签: algorithm time-complexity asymptotic-complexity