复杂性与运行时间的实际增长不匹配? (蟒蛇)

时间:2015-12-15 21:36:26

标签: python algorithm time-complexity complexity-theory

我在python中运行了2个代码然后测量完成所花费的时间。代码非常简单,只是递归最大值。这里是: 1。

def max22(L, left, right):
  if(left>=right):
    return L[int(left)]
  k = max22(L,left,(left+right-1)//2)
  p = max22(L, (right+left+1)//2,right)
  return max(k,p)


def max_list22(L):
  return max22(L,0,len(L)-1)
def max2(L):
  if len(L)==1:
    return L[0]
  l = max2(L[:len(L)//2])
  r = max2(L[len(L)//2:])
  return max(l,r)

第一个应该在O(logn)中运行(imo),第二个在O(n * logn)中运行。 但是,我测量了n = 1000,n = 2000和n = 4000的运行时间, 不知何故,这两种算法的增长似乎是线性的!这怎么可能?我的复杂性是错误的还是可以的? 感谢。

3 个答案:

答案 0 :(得分:3)

第一个算法不是O(log n),因为它会检查每个元素的值。可能会显示它是O(n)

至于第二种情况,你可能在这么小的尺度上注意到n和nlogn之间的差异。

答案 1 :(得分:2)

仅仅因为函数将搜索空间拆分为2然后以递归方式查看每一半并不意味着它在复杂性中具有log(n)因子。

在第一个解决方案中,您将搜索空间拆分为2,但随后最终检查每个每个元素。与丢弃搜索空间一半的二进制搜索不同,您正在检查两半。这意味着搜索中没有任何内容被丢弃,您最终会查看每个元素,从而使您的复杂度为O(n)。第二次实现也是如此。

答案 2 :(得分:0)

您的第一个算法在普通计算机上是O(n),因此您的测试表明这一点并不奇怪。你的第二个算法是O(n *登录),但如果使用正确的数组而不是列表,它将是O(n)。由于Python内置列表操作非常快,您可能还没有达到对数减速;尝试使用更像n=4000000的值,看看你得到了什么。

请注意,如果您可以并行运行两个递归调用(使用O(1)切片),则两个算法都可以在O(log n)时间内运行。当然,你需要O(n)处理器才能做到这一点,但如果你正在设计一个芯片,而不是编写一个程序,那么这种缩放就会很简单......