简体   繁体   English

为什么我们在谈论时间复杂度时使用渐近符号(因此忽略系数)?

[英]Why do we use asymptotic notations (thus ignoring coefficients) when talking about time complexity?

This question is different from "Why do we ignore coefficients in Big-O notation".这个问题与“为什么我们忽略 Big-O 表示法中的系数”不同。

When measuring time complexity we usually use Big-O notations which ignore the coefficients and non-dominant elements.在测量时间复杂度时,我们通常使用忽略系数和非主导元素的 Big-O 表示法。 However, don't 2N+C and N+C instructions result in significant differences in execution time, especially when the problem size grows very large?但是,2N+C 和 N+C 指令不会导致执行时间的显着差异,尤其是当问题规模变得非常大时? The former will take twice more time than the latter, which could be two weeks compared with one week in real-world large scale computation.前者将比后者多花费两倍的时间,与现实世界大规模计算中的一周相比,这可能是两周。

Examples include quicksort vs. other O(NlogN) sort algorithms and the trivial O(N^3) matrix multiplication vs. Strassen's algorithm (which can be slower because the leading coefficient is much larger even with less exponent)示例包括快速排序与其他 O(NlogN) 排序算法以及琐碎的 O(N^3) 矩阵乘法与 Strassen 算法(可能会更慢,因为即使指数较小,前导系数也会大得多)

In short: because it's too hard.简而言之:因为它太难了。

Accurately finding out what those coefficient are requires a model of hardware: assigning a cost to every single primitive used by the algorithm.准确找出这些系数是什么需要硬件 model:为算法使用的每个原语分配一个成本。 In presence of modern optimizing compilers, out-of-order execution and memory cache hierarchies this is a nigh intractable problem.在存在现代优化编译器、乱序执行和 memory 缓存层次结构的情况下,这是一个几乎难以解决的问题。

If you want some estimate of their values, it's much easier (and likely more accurate) to figure out the asymptotic complexity formula, run some benchmarks on different problem sizes and fit the coefficients to the obtained data.如果您想要对它们的值进行一些估计,那么计算渐近复杂度公式会更容易(并且可能更准确),针对不同的问题大小运行一些基准测试并将系数拟合到获得的数据。

We use asymptotic notation so we can talk about the efficiency of algorithms , not the efficiency of specific computers.我们使用渐近符号,所以我们可以谈论算法的效率,而不是特定计算机的效率。

If you write program that takes f(n) seconds to run on your machine...如果您编写的程序需要 f(n) 秒才能在您的机器上运行...

The same program might take f(n)/10 seconds on a much faster machine, but that's still O(f(n)).同样的程序在速度更快的机器上可能需要 f(n)/10 秒,但这仍然是 O(f(n))。

The same program might take f(n)*10 seconds on a much slower machine, but that's still O(f(n)).在慢得多的机器上,相同的程序可能需要 f(n)*10 秒,但这仍然是 O(f(n))。

Some machine could have different hardware, so it's faster at, say, floating point math, but slower at memory access.有些机器可能有不同的硬件,所以它在浮点数学上更快,但在 memory 访问时更慢。 The time it takes to run your program on that machine may be faster or slower, depending on the specific input, but it will still be O(f(n)).在该机器上运行程序所需的时间可能会更快或更慢,具体取决于特定的输入,但它仍然是 O(f(n))。

The time it takes to run a program depends on a lot of things, but the asymptotic complexity is a property of the algorithm itself.运行程序所需的时间取决于很多因素,但渐近复杂度是算法本身的属性。 That's why we use it to evaluate algorithms.这就是我们使用它来评估算法的原因。

Because big-O notation tells you about an algorithm's performance independent of the language, compiler/interpreter, or platform being used.因为大 O 表示法告诉您算法的性能与所使用的语言、编译器/解释器或平台无关。 Contrary to popular belief, big-O doesn't predict the run-time.与流行的看法相反,big-O 不能预测运行时间。 Instead, it tells you how the algorithm scales with input.相反,它会告诉您算法如何随输入扩展 However long it takes for a given size input, an algorithm that has O(n 2 ) complexity will asymptotically take 4 times as long if you double the size of the input, 100 times as long if you increase the input by a factor of 10, etc., regardless of your choices of languages, compilers, or platforms.无论给定大小的输入需要多长时间,如果将输入的大小加倍,具有 O(n 2 ) 复杂度的算法将渐近花费 4 倍的时间,如果将输入增加 10 倍,则将花费 100 倍的时间等,无论您选择何种语言、编译器或平台。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM