【问题标题】:Program/algorithm to find the time complexity of any given program找出任何给定程序的时间复杂度的程序/算法
【发布时间】:2009-09-22 16:32:25
【问题描述】:

我想知道是否可以“编写一个程序算法找出任何给定程序的时间复杂度作为输入。

输入:任何程序 (P) [以任何语言或特定语言]

输出:该程序的时间复杂度 (P)。

之前有没有尝试过编写这样的程序? 是否有任何算法可用于此目的?

如果是这样,请提供必要的链接、参考资料或任何可能的指导。

【问题讨论】:

标签: algorithm time-complexity


【解决方案1】:

没有。这是不可能的。这是halting problem. 的一种形式

【讨论】:

  • +1:在你能证明程序 P 停止之前,你无法证明它的时间复杂度。
  • 但是对于非图灵完备的语言来说,这可能是可能的 :) (而且这种语言的用处是一个悬而未决的问题)
  • 忽略关于停机问题的理论知识。看起来你可以编写一个程序,给你一个粗略的估计,然后假设程序最终会结束。
  • @corymatthews:不。你不能得到一个“粗略的估计”。你要么有一个程序,你可以为复杂性争论 - 作为一个数学练习 - 并且是对的。或者您有一个无法证明终止的程序;在这种情况下,你不能再做任何事情了。
  • 如果 cory 的程序存在,那么即使它只适用于已知会停止的问题,它也会一劳永逸地解决这个恼人的 P=NP 问题。只需针对旅行商问题的“尝试存在于伪并行中的每个程序”算法运行它,并找出它是否具有多项式复杂性。如果是,P=NP,如果不是 P!=NP。由于没有解决 P=NP,所以不存在这样的程序。
【解决方案2】:

证明任意算法的复杂性是不可能的,但原则上你可以估计它:

  1. 选择 n,输入的大小
  2. 运行算法
  3. 观察 t(n),为大小为 n 的输入运行算法所需的时间
  4. 选择另一个 n,重复第 2 步和第 3 步,直到获得大量数据
  5. 在 n、n^k、log(n)、n log(n)、n! 或任何其他上回归 t(n) 可能合适的术语
  6. 选择具有统计意义的术语并声明 是您估计的算法复杂度

这种方法有很多陷阱

  1. 这不能证明什么,只能估计
  2. 如果 t(n) 对于大 n 变得非常大,则需要很长时间才能 为您的分析收集足够的数据
  3. 除非您使用巨大的值,否则这种方法可以通过多种方式被愚弄 n.例如,这个算法看起来像 O(1),除非你使用 astronomical n的值

    sleep for 10 days
    run an O(n log(n)) sorting algorithm
    

其他 SO 用户可以想出更多。但在某些情况下,例如当您对算法进行复杂性分析并希望通过经验验证它时,这仍然是一种有用的方法。

【讨论】:

  • 问题出在第 3 步:您不能确定程序会永远因任意输入而停止。这就是停机问题。结果是,即使这种估计方法通常也不会产生有用的度量。
  • 更糟糕的是,有些终止算法仍然需要直到宇宙热寂才能产生答案。在开始尝试运行它并收集数据之前,您可能应该知道这一点。
  • 是的,但如果你有一个公差说 MAX t(n),该方法可用于对小于 t(n) 的时间进行估计(只需在 Max t(n) 之后强制终止进程) 时间)。它不会告诉你程序是否会停止,但你会发现算法的运行时间得到“这个程序运行时间太长以至于它实际上对我不可用”的结果。
  • 我不会说这通常没有用。您想要进行基准测试的大多数算法都会轻易停止。正如 mobrule 指出的那样,这并不能证明任何关于运行时的事情,但它确实提供了有用的统计测试。
  • 为了实际目的,渐近行为在任何情况下都是完全、完全无关的。如果运行时间超过一年,我实际上从来没有写过一个我关心它的运行时间的程序,而一年远低于限制,因为 N 趋于无穷大。如果您所谓的算法在某些输入上没有停止,那么您遇到的问题比您无法通过这种方法测量其表观复杂度(对于小 N)更糟糕......
【解决方案3】:

我们不能在算法本身中引入更多变量,并以与我们手动执行相同的方式找到复杂性。 例如,我们可以在插入排序中有一个变量,比如 n=0,它会跟踪算法的整个循环部分,然后给出答案为 O(n^2)

【讨论】:

  • 您仍然需要在许多不同的输入上运行它。它是自我观察的,而不是您手动计算平均值并不会改变 那个 事实。但是,如果您的日常活动生活在某种不断使用的动态系统中,那么是的,自我观察/意识是一个非常好的主意,IMO。系统的主管部分会观察和检测哪些部分需要改进,然后选择另一种算法。
【解决方案4】:

好吧,我认为您可以通过假设所有情况来做到这一点。 1:喜欢先做一个模块,可以提取每条指令 2:做一个指令数据库,与程序指令相匹配。 3:通过获取您在数据库中设置的适当时间复杂度来计算复杂度,仅此而已。

【讨论】:

    猜你喜欢
    • 2021-09-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-05
    • 2018-02-21
    • 1970-01-01
    相关资源
    最近更新 更多