算法的效率

时间:2013-02-21 09:32:06

标签: algorithm

我是计算机科学专业的学生,​​我是算法新手。我们正在学习课堂设计和分析算法课程。 我想知道为什么算法的时间复杂度是用来衡量的 O(n)O(log n)等,而不是以秒或毫秒为单位衡量实际时间?

4 个答案:

答案 0 :(得分:3)

Asymptotic computational complexity对于讨论算法的理论方面很有用。不讨论实际执行时间的主要原因是:

  • 实际执行时间因硬件,输入大小和优化而有很大差异。
  • 它允许我们讨论和分析具有高甚至无限执行时间的算法。
  • 类别分类(也称为Big-O表示法)为我们提供了算法效率的有用描述,无论其实现如何,给出足够长的输入。例如,对于足够长的输入,O(log(n))算法比O(n)算法快,但对于较短的输入,后者可能更快。
  • 讨论与语言无关,适用于任何软件架构。

应始终考虑实际考虑因素,但Big-O是每个关于算法解决方案的讨论的基础。如果你不能Big-O分析你的算法,你的代码永远不会扩展。

答案 1 :(得分:3)

为什么效率不以秒/毫秒表示实际时间?

有很多(其中一些是显而易见的)我们不这样做的原因:

  • 实际时间因算法的实施而异。
  • 实际时间因编译器生成的代码(以及指定的所有优化选项)而异。
  • 实际时间因时间共享,通信开销(分布式算法)等而异。
  • 实际时间因运行程序的系统配置(时钟频率,缓存大小,网络拓扑等)而异。
  • 我们还希望了解算法如何根据问题的大小进行扩展。描述算法相对于问题大小的速度的函数更有用。

为什么效率不会被描述为输入大小的确切函数,并且会给出准确的运行时间?

  • 再次,系统配置(系统架构,时钟速率,指令集等)
  • 同样,编译器对代码的优化可能会改变一些系数。
  • 可能不容易导出复杂算法或算法的确切公式,其中确切的运行时间取决于输出的某些特征。

,然后吗

这就是为什么它被描述为属于一类函数。

这样做的好处是我们知道算法的可扩展性(关于输入大小),而不需要深入了解实现或实际系统的细节。我们甚至可以描述一类算法的最佳/最差时间复杂度(例如,Omega(n log n)用于基于比较的排序算法)。

这样做的缺点是常量被隐藏,只剩下最强大的术语。 2算法可以具有相同的时间复杂度,但是一个可以比另一个更快,因为它具有更小的常数(Floyd循环查找算法与布伦特循环查找算法)。一些具有巨大隐藏常数的算法仅在非常大的输入大小时才有用。因此,不应该仅根据时间复杂度选择算法,还需要考虑最大可接受的输入大小。

答案 2 :(得分:2)

执行单指令的时间取决于硬件,因为算法是人为的,所以最好以该特定格式返回答案。 Big O定义最坏情况N代表块代码执行的次数,其中n通常定义数组对象的元素数。

答案 3 :(得分:1)

要认识到的一个关键事项是,这些复杂性类不是用来描述算法的实际执行时间,而是用来描述最坏情况执行时间。

这很重要,因为一个递归的算法,并且具有复杂度类O(2 ^ N)可能会执行等效于O(1),如果由于传递了参数,它实际上不必携带输出递归,但是使用Big-O表示法时,您并没有描述算法的特定执行 - 再次,您将描述算法的最坏情况执行。

执行时间毫秒测量测量不同的东西。 Big-O表示法描述了上面提到的算法的最坏情况,但是它的运行方式不是特定于运行的特定平台,而毫秒时间测量只能描述单个特定机器上的单个特定执行。在普通的桌面系统上,特别是如果您使用C#.NET或Java等托管语言构建,每次运行算法时都会出现波动,例如垃圾收集 - 测量函数所需的时间执行一个时刻可能会给出3毫秒,下一分钟可能会给出5毫秒。在更快的计算机上,它可能只需要0.005毫秒 - 正如你所看到的,这样的测量很少告诉我们算法本身,这就是为什么你需要类似Big-O的东西 - 它专门讨论算法,而不是特定的执行特定系统在特定时刻的算法。