Big(O)可以通过测量得到肯定吗?

时间:2015-04-10 00:44:47

标签: algorithm big-o

我们假设您设计了一种算法,您可能认为该算法在O(n)中运行。如果我用1000输入测量运行的时间,然后将输入增加10倍,然后再次测量。如果运行时间几乎是第一次尝试的10倍,我可以推断O(n)是正确的吗?

这有多愚蠢?显然重复测试会提供更好的准确性,但我想知道这是否有意义。

4 个答案:

答案 0 :(得分:12)

通常,答案是“是”'。如果将问题大小增加10并且时间增加10,那么您可能正确地假定为O(N)。但是,这个数字不太可能如此美丽。

如果从1,000到10,000,O(N.logN)算法大致上升了13倍(参见下面的bc)。那距离10不远,你可能会错误地认为增加12表示O(N.logN)而不是O(N)。但是,如果你增加10并且时间增加大约100,你很可能会处理非线性算法 - O(N 2 )。所以,2分是不够的,但它是指示性的。多次运行和更多数据点都有帮助。

但是,有时会有其他东西开始。例如,您可能会突然开始使用这么多内存,以致您的程序被分页而不是仅仅运行。即使在给定足够资源的情况下算法仍然是线性的,它也会大幅减速。

另外,请注意缓存效果和优化效果。缓存可以使事情看起来更快。如果优化器断定计算被忽略,则可能会消除整个计算。所以你必须谨慎。

但是,运气好的话,你可以将问题扩展几个数量级(或者至少是几个不同的数字),然后对它是线性还是其他东西进行合理的猜测。< / p>

O(N.logN)为1,000对10,000

$ bc -l
n=1000
n*l(n)
6907.75527898213705205000
a=n*l(n)
m=n*10
m*l(m)
92103.40371976182736070000
b=m*l(m)
b/a
13.33333333333333333333
quit
$

答案 1 :(得分:6)

与其他答案相反,我会说&#34;不&#34;。但是,你可以得到一个很好的猜测(甚至不是估计,因为这里不合适)。这可能意味着&#34;经常&#34;。

问题是,你永远不会知道常数因素。 Big Oh是无症状的行为(在无限远中),除了最成长的术语之外,这是非常有用的。所以在数学上你不能确认你的假设。

首先,当无症状行为在现实应用中无用时,这里有大量算法和用例。仅仅因为&#34;典型的用例&#34;输入分布下降。这种情况更常见。你仍然可以测试/&#34;估计&#34;它

但也有一种情况,即最佳算法具有如此大的常数因子,因此不适用于现代系统。我所知道的最好的例子是large number multiplication algorithms

然而,有些系统会近似于#34; (更好地说猜测)算法的复杂性类。我不确定codility是通过代码分析来测量它还是通过代码分析来猜测它们,但是他们能够做到:https://codility.com/public-report-detail/

可以做的是运行算法,更改输入大小,运行测试并使数据适合模型。这很简单。然后你可以说,对于测试的输入范围,算法表现为 O(class(n))。 (这可能具有实际意义,甚至比理论上的渐近复杂性更有价值。)

请注意,选择测试点并非易事。基本上,如果你的算法表现得很快&#34;快速&#34;那么你需要将输入大小率提高到下一个类。例如。如果您有类似(100n+n!)的内容,则可以n={1,10,100},因为它会kill执行时间。但是,n={1,2,3,4,5,6,7}未获取n!部分(确定7!5040,但对于n^2则会更加困难。)

最重要的是,得到一个好的猜测当然是可能的,但除了大多数简单的情况之外,它可能很棘手且难以做到,遗憾的是很难判断案件是否棘手。

此外,这个讨论纯粹是理论上的,省略了硬件效应。我听说过n^2表现优于n^log n的算法,因为前者总是(非常)缓存友好,但我不能接受它,我无法回想起源代码。

答案 2 :(得分:2)

根据实际程序的运行时绘制输入大小是一个非常有用的工具,可以让您了解代码的实际执行情况。一般来说,认为你可以使用它来推断复杂性是危险的。

这是一个解决方法的实际例子。

良好的快速排序实现将阵列分成三个部分:小于枢轴,等于枢轴,大于枢轴。这意味着快速排序随机数组64位整数(事实上,对任何固定大小数据类型的随机数组进行排序)使用O(n)比较,因为最终每个子数组都是常量。

不幸的是,你无法凭经验看到这一点:如果你根据比较次数绘制n,图形看起来像n * log(n),直到输入数组远大于2 ^ 64个元素。即使你有足够的内存,你的编程语言可能也不允许你索引那个大小的数组。

这个例子也证明了经验测量给出了有趣的数据(代码在实际输入上的执行方式与n * log(n)相似),并且复杂性为您提供了一个理论但实际上无用的事实,即渐近增长是线性的。

答案 3 :(得分:2)

除了别人说的话。有时平均情况和最坏情况可能不同,最坏的情况可能很难找到。一个着名的例子是quicksort,其O(n log n)平均行为(滥用O符号?)和O(n^2)最坏情况行为。如果你有一个&#34;黑盒子&#34;算法(好吧,程序),如果没有关于算法的知识,这样的最坏情况可能难以实验。