【发布时间】:2009-06-02 18:57:21
【问题描述】:
Big-O 表示法[1] 在实践中失败的例子有哪些?
也就是说:算法的 Big-O 运行时间什么时候会预测算法 A 比算法 B 快,而实际运行时算法 B 会更快?
稍微宽泛一点:关于算法性能的理论预测何时与观察到的运行时间不匹配?非 Big-O 预测可能基于搜索树中的平均/预期旋转次数,或排序算法中的比较次数,表示为因子乘以元素数量。
澄清:
尽管有些答案是这样说的,但 Big-O 表示法是旨在预测算法性能。也就是说,它是一个有缺陷的工具:它只谈论渐近性能,并且模糊了常数因子。它这样做是有原因的:它旨在预测算法性能,而与您在哪台计算机上执行算法无关。
我想知道的是这个:这个工具的缺陷什么时候表现出来?我发现 Big-O 表示法相当有用,但远非完美。有哪些陷阱、边缘情况和陷阱?
我正在寻找的一个示例:使用斐波那契堆而不是二进制堆运行 Dijkstra 的最短路径算法,得到 O(m + n log n) 时间与 O((m+n) log n) , 对于 n 个顶点和 m 个边。您预计斐波那契堆迟早会提高速度,但在我的实验中从未实现过速度提高。
(没有证据的实验证据表明,在均匀随机边权重上运行的二叉堆花费 O(1) 时间而不是 O(log n) 时间;这是实验的一个大问题。另一个需要计算的问题是对 DecreaseKey 的预期调用次数。
[1] 实际上,失败的不是 notation,而是 notation 所代表的 concepts,以及预测算法性能的理论方法。 反迂腐>
关于接受的答案:
我接受了一个答案,以突出我希望得到的答案。存在许多同样好的不同答案:) 我喜欢这个答案的地方在于,它提出了一个通用规则,用于何时 Big-O 表示法“失败”(当缓存未命中主导执行时间时),这也可能增加理解(在某种意义上我不知道如何最好地表达 ATM)。
【问题讨论】:
-
与stackoverflow.com/questions/842242/…类似(但不是完全重复)
-
我不会说 Big-O 有缺陷,只是有限。说它有缺陷就像说
-
您的说明有误。它不是一个有缺陷的工具,因为这意味着它给出了错误的答案。它没有。这是一个可证明是正确的工具。问题是人们滥用它来回答它无法回答的问题。如果你只用符号来描述它能够描述的东西,那么就没有缺陷。一旦您尝试使用它来描述实际性能,它就会失败,因为它没有所有相关信息。它的目的不是预测算法性能,而是预测算法的可扩展性。当问题规模变大时,算法会变慢多少?
-
如果你想知道(最坏情况下的)速度,你需要知道大 O、输入的大小、算法的常数因子以及在现实世界中的实现细节。问题实际上应该是“Big-O 什么时候还不够”,而不是“Big-O 什么时候失败”。随着大 O 复杂度之间的差异减小,n 减小,您需要越来越多地关注这些其他因素。
-
我对您的编辑的问题只是您称其为“有缺陷”。 ;) 我不认为限制是工具的失败。是我正在打字的键盘的限制,我不能用它去法国旅行吗?它只是不是为了那个。如果我想去法国旅行,我会买机票,而不是键盘。我认为这正是该符号有用的原因:因为它区分了不同的与性能相关的问题。它不会告诉您程序将如何执行,它会告诉您算法一个方面的确切属性。
标签: algorithm language-agnostic theory big-o