这段代码的运行时是什么

时间:2018-03-13 08:06:46

标签: python runtime time-complexity asymptotic-complexity orders

def mystery11(n):
  if n < 1: return n
  def mystery12(n):
    i = 1
    while i < n:
      i *= 2
    return i
  return mystery11(n/2) + mystery11(n/2) + mystery12(n-2)

我对上面的代码有疑问。我完全理解,如果没有对mystery12的最后一次递归调用,代码的运行时(mystery11)将是theta(n)。但我不相信在每个级别theta(log(n))工作正在进行中。

在第一级,我们做log(n),在下一级,我们做2log(n / 2),然后4log(n / 4)......但是看起来不像log(n)在每个级别(感觉更接近第二级的2log(n)和第三级的4log(n)等。)

我也尝试过Wolfram Alpha,我得到了no solutions exist。 但是在没有log(n)项的情况下工作正常。

那么,这个解决方案是否正确theta(nlog(n))?如果没有,实际解决方案是什么?

聚苯乙烯。抱歉,如果我的帖子中的任何内容都不是礼仪,这是我第二次在Stackoverflow上发帖。发表评论,我会解决它。

2 个答案:

答案 0 :(得分:0)

对不起,我无法理解你的问题是什么。

我似乎不太清楚。

无论是什么,

我根据你的'神秘'代码做了数学计算。

让我们说'm1'是神秘的11,'m2'是个谜.12。

没有m2,

时间成本就是这样。

m1(n)
= 2*m1(n/2)
= 2*( m1(n/4) + m1(n/4) ) = 4*m1(n/4)
= .....
= 2^k * m1( n / 2^k )

对于产生2 ^ k n的k,

2 ^ k = n。

然后m1(n)的时间成本是n * m1(1)= n。

m2的时间成本显然是log(n)。

使用m2,

这样的时间成本变化。

m1(n)
= 2*m1(n/2) + log(n)
= 2*( m1(n/4) + m1(n/4) + log(n) ) + log(n) = 4*m1(n/4) + ( log(n) + 2log(n) )
= ....
= 2^k * m1(n/2^k) + ( log(n) + 2log(n) + 4log(n) ... 2^(k-1)*log(n) )
= 2^k * m1(n/2^k) + log(n) * ∑( 2^(k-1) ) ( where k is from 1 to k )
= 2^k * m1(n/2^k) + log(n)/2 * ∑( 2^k )
= 2^k * m1(n/2^k) + log(n)/2 * ( 2^(k+1) - 1 )
= 2^k * m1(n/2^k) + 2^k * log(n) - log(n)/2

就像前一个一样,

表示生成2 ^ k n的k,

2^k * m1(n/2^k) + 2^k * log(n) - log(n)/2
= n * m1(1) + n*log(n) - log(n)/2 = n + n*log(n) - log(n)/2

我相信你可以从这里做其余的事。

聚苯乙烯。如果不是你要求的话我很抱歉。

答案 1 :(得分:0)

由于mystery12独立于任何外部函数/变量,因此我们先来看看它。

在while循环j迭代后i = 2^j。因此,最大循环数由公式2^j >= nj = ceil(log2(n))给出,其中ceil向上舍入到最接近的整数。

现在为mystery11。每个调用包含2个带有参数mystery11的{​​{1}}的递归调用,以及带有参数n / 2的{​​{1}}调用。这给出了时间复杂度递归关系(mystery12是一些正常数):

enter image description here

您已经正确推断出递归深度为n - 2。精确值为C。使用一个舍入的数字仅与自身的差异小于1的事实,我们可以消除一些舍入括号:

enter image description here

让我们首先检查m ~ log n。出现问题 - 对数内的表达式可能是负数。这可以通过以下事实来缓解:m = ceil(log2(n)) 永远不会执行B - 即在此边缘情况下其复杂性可以被截断为mystery12。因此,总和是从上面界限:

enter image description here

我们使用n - 2 < 1的泰勒展开。因此,在我们的分析中可以忽略O(1),因为它已经被第一个词遮盖了。

现在来检查一下log。这是一个稍微繁琐的总结,我将使用Wolfram Alpha来计算:

enter image description here

  

因此,B的总时间复杂度为 A ,而不是预测的mystery11

这是为什么?原因在于每个递归调用Θ(n)工作&#34; - Θ(n log n)此处与log n传递给n的初始值(整体时间复杂度中的n)不同。在每个递归级别mystery11呈指数级下降,因此:

  

我们无法将每次通话完成的工作量与递归通话次数相乘。

这一般适用于复杂性分析。