以下代码的重要内容是什么?

时间:2016-03-15 13:53:36

标签: big-o time-complexity

代码:

int temp = 0;
for (int h = 1; h <= n; h = h * 2)
{
   for (int i = 1; i <= n; i++)
   {
      for (int j = 1; j<=n; j++)
      {
         for (int k = 1; k<i; k++)
         {
            temp++
         }
      }
   }
}

根据我的计算,big-O lg n * n ^ 4 。 请指导。

编辑:谢谢大家的回复。我明白我犯了什么错误。我非常感谢所有参与的人。

4 个答案:

答案 0 :(得分:3)

for (int h = 1; h <= n; h = h * 2) // increment is pow(2). hence executed ln(n) times
{
   for (int i = 1; i <= n; i++) // increment is one. Executed n times
   {
      for (int j = 1; j<=n; j++)// increment is one. Executed n times
      {
         // increment is one. Executed i times. See below
         for (int k = 1; k<i; k++)
         {
            temp++
         }
      }
   }
}

k循环执行i次。 i的最大值为n。所以你可以认为它总是被执行n次(过近似)

复杂度= ln(n)* n * n * n = ln * pow(n,3)

另一种看待它的方法......让我交换循环和循环

for (int h = 1; h <= n; h = h * 2) // increment is pow(2). hence executed ln(n) times
    {
       for (int j = 1; j <= n; j++) // increment is one. Executed n times
       {
          // see below
          for (int i = 1; i<=n; i++)
          {
             for (int k = 1; k<i; k++)
             {
                temp++
             }
          }
       }
    }

现在看一下......(i,k)的执行总数是n*(n+1)/2。那么现在的复杂性是什么?

h * j *(i,k)= ln(n)* n *(n *(n + 1)/ 2)== ln(n)* pow(n,3)

答案 1 :(得分:2)

只是为了踢,我用不同的n:

值运行这段代码
               n                  temp               O?
     -----------        --------------        ---------
               1                     0
              10                  1800        1.8 x n^3
             100               3465000        3.5 x n^3
            1000            4995000000        5.0 x n^3
           10000         6999300000000        7.0 x n^3  (and took a LONG time!)

结论:log(n)* n ^ 3

答案 2 :(得分:1)

Knightrider基本上是对的,但如果你想要正确的数字,你就不能说&#34;我取i&#34;的最大值。

是的,它在f(n) = O(...)方面是正确的,但你也可以写f(n) = O(n^15),这也是正确的。

最后一个循环执行n次,然后执行n-1次,然后执行n-2次等,这是n+n-1+n-2+n-3....+3+2+1 n(n+1)/2。现在你可以将它乘以得到n(n+1)/2 = n^2/2 + n/2,在渐近运算中可以忽略常量,这意味着n^2/2 + n/2 = Theta(n^2+n),它也可以转换为n^2+n = Theta(n^2)

毕竟,结果没有改变,但你必须确定。

最终结果是n^3*log_2(n),如knightrider所述

答案 3 :(得分:1)

使用Sigma表示法分析算法的复杂性

为了完整起见:在分析嵌套和共同依赖循环的时间复杂度时,例如在算法中,Sigma符号可以是一个很好的工具

enter image description here

其中⌊x⌋和⌈x⌉是floor and ceiling functions

从上面可以看出,该算法的渐近行为的上限是O(n^3 log_2(n))

使用Sigma表示法估算实际迭代次数

Sigma符号分析除了是Big-O(-Ω,-Θ)分析的严格工具之外,如果我们对计算或估算实际迭代次数感兴趣还有用我们的算法。

我们比较估计的迭代次数 - 使用上面的≤符号之前的公式 - 与@JohnHascell:s答案中显示的实际迭代次数。

// our formula (pseudo-code / matlab-compliant)
numIt(n) = n*ceil(log2(n))*(n^2-n)/2;

// comparison with actual count:
--------------------------------------------------------- 
           n     actual # of iter.   estimated # of iter. 
               (from @JohnHascell)   (from formula above)
------------   -------------------   --------------------
           1                     0                      0
          10                 1 800                  1 800
         100             3 465 000              3 465 000
        1000         4 995 000 000          4 995 000 000
       10000     6 999 300 000 000      6 999 300 000 000
--------------------------------------------------------- 

我们看到公式中的计数与实际计数完全一致;在这种情况下,估计实际上是实际计数。