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

发布于 2024-09-28 01:19:15 字数 50 浏览 1 评论 0原文

是否可以通过保留一个计数器来查看算法经历了多少次迭代来完成,或者是否需要记录持续时间?

Could it be done by keeping a counter to see how many iterations an algorithm goes through, or does the time duration need to be recorded?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

平安喜乐 2024-10-05 01:19:15

当前接受的不会给您任何理论估计,除非您能够以某种方式将实验测量的时间与近似它们的函数相匹配。这个答案为您提供了一种手动技术来做到这一点并填补了这一空白。

您首先猜测算法的理论复杂度函数。对于越来越大的问题,您还可以通过实验测量实际的复杂性(操作数量、时间或您认为实用的任何内容)。

例如,假设您猜测算法是二次的。测量(说出)时间,并计算时间与您猜测的函数 (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

The currently accepted won't give you any theoretical estimation, unless you are somehow able to fit the experimentally measured times with a function that approximates them. This answer gives you a manual technique to do that and fills that gap.

You start by guessing the theoretical complexity function of the algorithm. You also experimentally measure the actual complexity (number of operations, time, or whatever you find practical), for increasingly larger problems.

For example, say you guess an algorithm is quadratic. Measure (Say) the time, and compute the ratio of time to your guessed function (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

. As n moves towards infinity, this ratio...

  • Converges to zero? Then your guess is too low. Repeat with something bigger (e.g. n^3)
  • Diverges to infinity? Then your guess is too high. Repeat with something smaller (e.g. nlogn)
  • Converges to a positive constant? Bingo! Your guess is on the money (at least approximates the theoretical complexity for as large n values as you tried)

Basically that uses the definition of big O notation, that f(x) = O(g(x)) <=> f(x) < c * g(x) - f(x) is the actual cost of your algorithm, g(x) is the guess you put, and c is a constant. So basically you try to experimentally find the limit of f(x)/g(x); if your guess hits the real complexity, this ratio will estimate the constant c.

注定孤独终老 2024-10-05 01:19:15

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

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

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

这将为您提供良好的“理论”估计。
另一方面,如果您想要真实的数字 - 请使用分析

Algorithm complexity is defined as (something like:)

the number of operations the algorithm does as a function
of its input size.

So you need to try your algorithm with various input sizes (i.e. for sort - try sorting 10 elements, 100 elements etc.), and count each operation (e.g. assignment, increment, mathematical operation etc.) the algorithm does.

This will give you a good "theoretical" estimation.
If you want real-life numbers on the other hand - use profiling.

猫性小仙女 2024-10-05 01:19:15

正如其他人提到的,理论时间复杂度是算法完成的 cpu 操作数量的函数。一般来说,处理器时间应该是该常数的一个很好的近似值。但实际运行时间可能会因多种原因而有所不同,例如:

  1. 处理器管道刷新
  2. 缓存未命中
  3. 垃圾收集
  4. 计算机上的其他进程

除非您的代码系统地导致其中一些事情发生,并且有足够数量的统计样本,否则您应该根据观察到的运行时间,对算法的时间复杂度有相当好的了解。

As others have mentioned, the theoretical time complexity is a function of number of cpu operations done by your algorithm. In general processor time should be a good approximation for that modulo a constant. But the real run time may vary because of a number of reasons such as:

  1. processor pipeline flushes
  2. Cache misses
  3. Garbage collection
  4. Other processes on the machine

Unless your code is systematically causing some of these things to happen, with enough number of statistical samples, you should have a fairly good idea of the time complexity of your algorithm, based on observed runtime.

荆棘i 2024-10-05 01:19:15

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

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

The best way would be to actually count the number of "operations" performed by your algorithm. The definition of "operation" can vary: for an algorithm such as quicksort, it could be the number of comparisons of two numbers.

You could measure the time taken by your program to get a rough estimate, but various factors could cause this value to differ from the actual mathematical complexity.

清音悠歌 2024-10-05 01:19:15

是的。

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

yes.

you can track both, actual performance and number of iterations.

肥爪爪 2024-10-05 01:19:15

我可以建议使用 ANTS 分析器吗?当您使用“实验”数据运行应用程序时,它将为您提供此类详细信息。

Might I suggest using ANTS profiler. It will provide you this kind of detail while you run your app with "experimental" data.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文