【问题标题】:Asymptotic worst-case running time. Need some clarification渐近最坏情况运行时间。需要澄清一下
【发布时间】:2014-09-29 15:46:56
【问题描述】:

对于下面的mystery(n) 函数的伪代码,找到其渐近最坏情况运行时间f(n) 的严格上限和下限。也就是说,找到g(n) 使得f(n) ∈ Θ(g(n))。 (假设n为正整数)

Mystery (n ){                  
 c ←1                          | (constant)
 for i ←1 to n                 | n
   do for j ←i to n            | j
     do for k ← n down to n/2  | n/2
       do c ← c + 1            | (constant)
 print c                       | (constant)
}

总时间:(n/2)nj(不确定)

侧面的时间标签是我迄今为止发现的。对于这个问题,最好和最坏情况的运行时间似乎没有区别?此外,我怎样才能找到这种方法的严格上限和下限?任何建议都会很棒。或者我可以阅读的资源,因为我的教科书在这个主题上非常模糊。

【问题讨论】:

  • 尝试将其写为仅外循环上的操作总和(n^2/2 + (n-1)*n/2 + ...)

标签: algorithm big-o complexity-theory asymptotic-complexity


【解决方案1】:

j 不应出现在您的公式中,因为 j 也是 n 的函数。

每当您有一个依赖于外部循环变量的循环时,我发现查看求和公式来找出复杂性是最容易的。

所以外层循环肯定会运行n 次,而最内层循环肯定会运行n/2 次,但一般情况下是n/2 ∈ O(n)

那么让我们看看中间的循环。

中间循环在第一次迭代中运行(n-1) 次,然后在第二次迭代中运行(n-2) 次,一直到(n-n) 等于0 次。您可以将这些项重新排列为简单的 0 到 n 的总和。我们知道这个总和等于n(n+1)/2

由于这个公式代表了外循环和中间循环的组合,您可以简单地将最内循环相乘,得到最终公式n(n+1)n/(2*2) == n^2(n+1)/4

您应该意识到的一个概念是,由于c 只是一个计数器,并且在每次迭代时都会递增,所以c 可以被认为是该算法运行时复杂度的直接表示。

您可以通过计算c 来验证此结果。这是一个用 C 编写的示例程序来演示此算法:

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[]) {
  int c = 0;
  int n = 10;
  if (argc > 1) {
    n = atoi(argv[1]);
  }
  for (int i = 1; i <= n; ++i) {
    for (int j = i; j <= n; ++j) {
      /* Note that I've changed k to run from 0 to n/2 instead of n
         down to n/2, but this doesn't change the result. */
      for (int k = 0; k < n/2; ++k) {
        ++c;
      }
    }
  }
  printf("c == %d; n^2(n+1)/4 == %d\n", c, n*n*(n+1)/4);
}

这是上述程序对输入 2、4、8、32 和 64 的输出:

c == 3; n^2(n+1)/4 == 3
c == 20; n^2(n+1)/4 == 20
c == 144; n^2(n+1)/4 == 144
c == 8448; n^2(n+1)/4 == 8448
c == 66560; n^2(n+1)/4 == 66560

【讨论】:

  • 这非常有帮助!谢谢!我确实有一个问题,因为它与您的答案有关。用严格的上限和下限的大写θ表示法来说明这一点,我会简单地使用结果公式中最重要的项,对吗?这样 n^3 * n^2 将是 n^3,因为它在足够大的数据集中是最重要的。
  • 是的,只要你的意思是 (n^3 + n^2) 而不是 (n^3 * n^2),那就是真的。我假设这是一个错字,但以防万一 (n^3 * n^2) 为 n^5。
  • 是的,我写错了。简化得到的公式后,您剩下 n^3 作为最重要的术语。
【解决方案2】:
Mystery (n ){                  
 c ←1                          | (constant)
 for i ←1 to n                 | n
   do for j ←i to n            | j
     do for k ← n down to n/2  | n/2
       do c ← c + 1            | (constant)
 print c                       | (constant)
}

关于运行n 次的外循环是正确的。但是,下一个循环将在 i=1 时运行 n 次,在 i=2 时运行 n-1 次,...,在 i=n-1 时运行 2 次,在 i=n 时运行一次。平均而言,j 循环将运行n/2 次,所以这个中间循环也被认为是一个 O(n) 循环。当您组合所有三个嵌套循环时,这给出了 O(n^3) 的总运行时复杂度。

【讨论】:

    猜你喜欢
    • 2023-02-09
    • 1970-01-01
    • 2017-01-18
    • 1970-01-01
    • 2021-07-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多