如何通过“实验”测试时间复杂度?

时间:2010-10-20 19:10:57

标签: algorithm time-complexity

可以通过保持计数器来查看算法经历的迭代次数,还是需要记录持续时间来完成?

6 个答案:

答案 0 :(得分:9)

目前接受的不会给你任何理论估计,除非你能以某种方式使用实验测量的时间拟合近似它们的函数。这个答案为您提供了一种手动技术,可以填补这一空白。

首先,猜测算法的理论复杂度函数。您还可以通过实验测量实际复杂性(操作次数,时间或任何您认为实用的内容),以解决日益严重的问题。

例如,假设你猜算法是二次的。测量(说)时间,并计算时间与猜测函数的比率(n ^ 2):

for n = 5 to 10000 //n: problem size
  long start = System.time()
  executeAlgorithm(n)
  long end = System.time()
  long totalTime = end - start

  double ratio = (double) time / (n * n)
end

。随着n向无穷大方向移动,这个比例......

  • 收敛为零?然后你的猜测太。用更大的东西重复(例如n ^ 3)
  • 发散到无穷大?然后你的猜测太。用较小的东西重复(例如nlogn)
  • 收敛到正常数?答对了!你的猜测是钱(至少接近你尝试的n值的理论复杂度)

基本上,使用大O表示法的定义,f(x) = O(g(x)) <=> f(x) < c * g(x) - f(x)是算法的实际成本,g(x)是您的猜测,c是一个常数。所以基本上你试着通过实验找到f(x)/g(x)的限制;如果您的猜测达到真正的复杂程度,则此比率将估算常数c

答案 1 :(得分:5)

算法复杂度定义为(类似于:)

  

算法作为函数执行的操作数   它的输入大小。

因此,您需要尝试使用各种输入大小的算法(即排序 - 尝试排序10个元素,100个元素等),并计算算法所做的每个操作(例如,赋值,递增,数学运算等)。

这将给你一个很好的“理论”估计 如果你想要现实生活中的数字 - 请使用profiling

答案 2 :(得分:2)

正如其他人所提到的,理论时间复杂度是算法完成的cpu操作次数的函数。通常,处理器时间应该是模数常数的良好近似值。但实际运行时间可能因许多原因而有所不同,例如:

  1. 处理器管道刷新
  2. 缓存未命中
  3. 垃圾收集
  4. 机器上的其他进程
  5. 除非您的代码系统地导致其中某些事情发生,并且有足够数量的统计样本,否则您应该根据观察到的运行时间对算法的时间复杂度有一个相当好的了解。

答案 3 :(得分:1)

最好的方法是实际计算算法执行的“操作”次数。 “操作”的定义可以有所不同:对于诸如快速排序之类的算法,它可以是两个数字的比较次数。

可以衡量你的程序获得粗略估计所花费的时间,但是各种因素可能导致这个值与实际的数学复杂性不同。

答案 4 :(得分:0)

您可以同时跟踪实际性能和迭代次数。

答案 5 :(得分:0)

我建议使用ANTS探查器。当您使用“实验性”数据运行应用程序时,它将为您提供此类详细信息。