发现一个n之间的区别!和2 ^ n算法

时间:2012-02-22 21:00:29

标签: algorithm big-o time-complexity

我最近看到一些有趣的讨论,辩论一个给定的(“硬”)问题是否至少有2 ^ n或n!已知解决方案

我的问题是,除了实际走过算法并看到增长率之外,是否有一种启发式可以快速发现一个与另一个相比? IE浏览器。是否存在一些算法的快速可观察属性,使其显然是一个或哪个?

相关讨论:

2 个答案:

答案 0 :(得分:6)

没有算法可以确定程序的复杂性[根本]。它是Halting Problem的一部分 - 您无法确定某个算法是否会停止。 [你无法估计它是Theta(infinity)还是少于它的任何东西]

根据经验,通常 O(n!)算法在范围递减的循环中调用递归调用,而O(2^n)算法在每次调用中调用两次递归调用

注意:并非所有调用两次递归调用的算法都是O(2^n) - 快速排序是O(nlogn)算法的一个很好的例子,它也会调用两次递归调用。

编辑:例如:
SAT暴力解决方案O(2^n)

SAT(formula,vars,i):
  if i == vars.length:
      return formula.isSatisfied(vars)
  vars[i] = true
  temp = SAT(formula,vars,i+1)  //first recursive call
  if (temp == true) return true
  vars[i] = false
  return SAT(formula,vars,i+1)  //second recursive call

查找所有排列:O(n!)

permutations(source,sol):
  if (source.length == 0): 
      print sol
      return
  for each e in source: 
      sol.append(e)
      source.remove(e)
      permutations(source,sol) //recursive call in a loop
      source.add(e)
      sol.removeLast()

答案 1 :(得分:0)

如上所述,理论上不可能检查算法是O(2 ^ n)还是O(n!)。但是,您可以使用以下启发式方法:

  1. 对于不同的n值,计算步数F(n),求解
  2. 绘图n vs log(F(n))/ n
  3. 如果它看起来像一条扁平线(或平坦的线条),则为O(2 ^ n)
  4. 如果它看起来像是一个严格增加的函数,那么就是超指数
  5. 如果它看起来更符合x vs log(x)图,那么它“可能”是O(n!)