【问题标题】:Runtime of a loop that decays exponentially?以指数方式衰减的循环的运行时间?
【发布时间】:2013-10-10 17:33:11
【问题描述】:

其中n 是函数的输入,可以是任何整数。

i = n, total = 0; 
while (i > 0) {      
 for (j=0; j<i; j++) 
   for (k=0; k<i; k++) 
     total++;      
 i = i/4; 
} 

这个函数的时间复杂度是多少?

【问题讨论】:

  • 它是O(n ^ 2 log n)
  • n ^ 2 log &lt;4&gt; n(对数基数 = 4)
  • @GrijeshChauhan 对数底数无关紧要。
  • 这个问题似乎是题外话,因为它是关于理论计算机科学的,并且没有显示任何研究工作。
  • 什么时候代码复杂性离题了?

标签: algorithm math big-o asymptotic-complexity recurrence


【解决方案1】:

考虑这一点的一种方法是独立查看循环。

这个内循环嵌套:

for (j=0; j<i; j++) 
   for (k=0; k<i; k++) 
     total++;

将执行总共 Θ(i2) 次操作,因为每个循环独立运行 i 次。

现在,让我们看看外循环:

while (i > 0) {      
    /* do Theta(i^2) work */   
    i = i/4; 
} 

这个循环最多会运行 1 + log4 i 次,因为在每次迭代中 i 被削减 1/4 倍,而这只会发生 1 + log4 i 次,然后 i 降至零。那么,问题是要完成多少工作。

解决这个问题的一种方法是为完成的总工作编写一个简单的递归关系。我们可以将循环视为尾递归函数,其中每次迭代都执行 Θ(i2) 工作,然后对大小为 4 的子问题进行递归调用。这给出了以下递归:

T(n) = T(n / 4) + Θ(n2).

应用主定理,我们看到 a = 1、b = 4 和 c = 2。由于 logb a = log4 1 = 0 和 0 Master Theorem says (by Case 3) 为Θ(n2)。因此,完成的总功为 Θ(n2)。

这是另一种思考方式。循环的第一次迭代执行 n2 工作。接下来是 (n / 4)2 = n2 / 16 工作。接下来是 (n / 64)2 = n2 / 256 工作。事实上,循环的迭代 x 将完成 n2 / 16x 个工作。因此,完成的总工作由下式给出

n2(1 + 1 / 16 + 1 / 162 + 1 / 163 + ...)

≤n2(1 / (1 - 1/16))

= Θ(n2)

(这里使用sum of an infinite geometric series 的公式)。

希望这会有所帮助!

【讨论】:

  • 很好的解释。如何让“Big Theta”看起来像一个大 Theta?
  • @mrip:我正在使用 HTML 实体 Θ。很漂亮!
  • 酷!谢谢!我猜他们也有 &Omega
【解决方案2】:

运行时间为O(n^2)total递增的次数与n^2/(1-1/16)渐近,约为1.067 n^2。 复发会是

T(n) = n^2 + T(n/4)
     = n^2 + n^2/16 + T(n/16)
     = n^2 (1 + 1/16 + 1/16^2 + ...)
     = n^2 / (1 - 1/16)

【讨论】:

  • 为什么在任何地方都没有 log base 4?
  • 因为 log base 4 不是运行时间等式的一部分。
  • @BlazArt- 尽管循环运行 log_4 n 次,但每次迭代完成的工作量呈几何级数减少。几何级数之和不包括对数项。通常,如果您以对数方式多次迭代并且每次执行相同数量的工作,就会出现对数项。如果工作以几何方式下降,就像这里的情况一样,您往往看不到对数项。
  • @templatetypedef 我只是有些困惑,但是您的行“通常,如果您以对数方式多次迭代并且每次执行相同数量的工作,就会发生日志项。”纠正了我的困惑非常感谢您的回答。
【解决方案3】:

这段代码片段:

i = n, total = 0; 
while (i > 0) {      
 for (j=0; j<i; j++) 
   for (k=0; k<i; k++) 
     total++;      
 i = i/4; 
}

相当于这个:

for ( i = n ; i > 0 ; i = i / 4 )
    for ( j = 0 ; j < i ; j ++) 
        for ( k = 0 ; k < i ; k ++)
            total ++;

因此,有条不紊地(经过经验验证),您可以使用 Sigma 表示法获得以下内容:*

非常感谢WolframAlpha

【讨论】:

    猜你喜欢
    • 2020-08-09
    • 2015-06-18
    • 1970-01-01
    • 2019-10-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多