简体   繁体   English

计算这些算法的Big O复杂度?

[英]Calculating Big O complexity of these algorithms?

I am trying to figure out the Big O notation of the following 2 algorithms below but am having trouble. 我正在尝试找出以下两种算法的Big O表示法,但遇到了麻烦。

The first one is: 第一个是:

public static int fragment3 (int n){
int sum = 0;
for (int i = 1; i <= n*n; i *= 4)
  for (int j = 0; j < i*i; j++)
   sum++;
  return sum;
} //end fragment 3

The answer should be O(n^4) . 答案应该是O(n^4) When I try to do it myself this is what I get: I look at the first for loop and think it runs n^2 logn times. 当我自己尝试执行此操作时,这就是我得到的:我查看第一个for循环,并认为它运行了n^2 logn次。 Then for the inner for loop, it runs n times + the run time of the outer loop which is n^3 logn times. 然后对于内部for循环,它将运行n次+外循环的运行时间,即n^3 logn次。 I know this is wrong but just don't get it. 我知道这是错误的,但是不明白。

For the code fragment below, the answer is O(n^9) . 对于下面的代码段,答案是O(n^9)

public static int fragment6(int n) {
int sum = 0;
for(int i=0; i < n*n*n; i++) {
  if(i%100 == 0) {
    for(int j=0; j < i*i; j += 10)
      sum++;
  } // if
  else {
    for(int k=0; k <= i; k++)
      sum++;
  } // else
 } // outer loop

 return sum;
} // fragment 6

When I attempt it I get: n^3 for the outer for loop. 当我尝试它时,我得到:外层for循环为n^3 for the if statement I get n , for the second for loop I get n + the other for loop and if statement, making it n^5 . 对于if语句,我得到n ,对于第二个for循环,我得到n +另一个for循环和if语句,使其成为n^5 Finally, I get n for the final for loop and everything adds up to O(n^6) . 最后,对于最后一个for循环,我得到n,并且所有结果加起来为O(n^6)

What am I doing wrong and what is the correct way to get its O(n^9) complexity? 我在做什么错?获得O(n^9)复杂度的正确方法是什么?

For the first one. 对于第一个。

Let's look at the inner loop.. 让我们看一下内部循环。

At the first iteration of the outer loop (i=1) it runs 1 time. 在外循环的第一次迭代(i = 1)中,它运行1次。 At the second iteration (i=4) it runs 16 (4*4) times. 在第二次迭代(i = 4)时,它将运行16(4 * 4)次。 At the third iteration (i=16) it runs 256 (16*16) times. 在第三次迭代(i = 16)时,它将运行256(16 * 16)次。 In general, at the (k+1)-th iteration of the outer loop inner loop runs 通常,在外循环的第(k + 1)次迭代中,内循环运行 f1 times, as 时代,作为 f2 at that iteration. 在那个迭代中。 So the total number of iterations will be 所以迭代的总数将是

f3

Now, how many numbers in that sum we will have? 现在,我们这总数中将有多少个数字? To determine that we should have a look at the outer loop. 为了确定我们应该看看外部循环。 In it i grows as 在其中,我成长为 f2 , until it reaches ,直到达到 f4 . So the total number of iterations is 因此迭代总数为 f5 .

This means that the total number of runs of inner loop is 这意味着内部循环的运行总数为

f6 (by dropping all the numbers from the sum but the last one). (通过从总和中除去所有数字,最后一个除外)。

Now we know, that the inner loop runs at least 现在我们知道,内部循环至少会运行 f7 times, so we are not faster than O(n^4). 倍,所以我们不比O(n ^ 4)快。

Now, 现在,

f8

Solving for N, 求N

f9 where C is a constant, so we're not slower than O(n^4). 其中C是一个常数,所以我们不慢于O(n ^ 4)。

Your approach to computing big-O is flat-out wrong, and you've made computation errors. 您计算big-O的方法完全是错误的,并且您已经犯了计算错误。

In some common cases you can take the worst case number of iterations and multiply them together, but this isn't a sound method and fails for cases like this: 在某些常见情况下,您可以采用最坏情况的迭代次数并将它们相乘,但这不是一个可靠的方法,在以下情况下会失败:

for (i = 1; i < n; i *= 2) {
   for (j = 0; j < i; j++) {
      sum++;
   }
}

Here, the outer loop runs log_2(n) times, and the inner loop worst case is n iterations. 在这里,外循环运行log_2(n)次,内循环最坏的情况是n次迭代。 So the wrong method that you're using will tell you that the complexity of this code is O(n log n). 因此,您使用的错误方法将告诉您此代码的复杂度为O(n log n)。

The correct method is to count accurately the number of iterations, and approximate at the end only. 正确的方法是准确计算迭代次数,并仅在最后进行近似计算。 The number of iterations is actually: 迭代次数实际上是:

1 + 2 + 4 + 8 + ... + 2^k

where 2^k is the largest power of two less than n. 其中2 ^ k是小于n的2的最大幂。 This sum is 2^(k+1) - 1, which is less than 2n. 该和为2 ^(k + 1)-1,小于2n。 So the accurate complexity is O(n). 因此,准确的复杂度为O(n)。

Applying this idea to your first example: 将这个想法应用于您的第一个示例:

for (int i = 1; i <= n*n; i *= 4)
    for (int j = 0; j < i*i; j++)
        sum++

i takes the values 4^0, 4^1, 4^2, ..., 4^k where 4^k is the largest power of 4 less than or equal to n^2 . i取值4^0, 4^1, 4^2, ..., 4^k ,其中4^k是小于或等于n^2的4的最大幂。

The inner loop executes i^2 times for a given value of i . 对于给定的i值,内部循环执行i^2次。

So overall, the inner sum++ is executed this many times: 因此,总的来说,内部sum++会执行多次:

(4^0)^2 + (4^1)^2 + ... + (4^k)^2
= 2^0 + 4^2 + ... + 4^2k
= 16^0 + 16^1 + ... + 16^k
= (16^k - 1) / 15

Now by definition of k we have n^2/4 < 4^k <= n^2 . 现在根据k的定义,我们有n^2/4 < 4^k <= n^2 So n^4/16 < 4^2k <= n^4 , and since 16^k = 4^2k , we get that the total number of times the inner loop is executed is O( 16^k ) = O( n^4 ). 所以n^4/16 < 4^2k <= n^4 ,由于16^k = 4^2k ,我们得到内部循环执行的总次数是O( 16^k )= O( n^4 )。

The second example can be solved using a similar approach. 可以使用类似的方法来解决第二个示例。

First case: 第一种情况:

  • Last run of the inner-loop with i = n^2, runs for n^4. 上一次运行i = n ^ 2的内循环,运行n ^ 4。 The outer-loop up to n^2, but using exponential growth. 外循环最多为n ^ 2,但使用指数增长。 For summation the sum over all inner-loop runs but the last is less than the last run. 为了求和,所有内循环运行的总和,但最后一次小于最后一次运行。 So inner-loop is essentially contributing O(1). 因此,内环本质上是贡献O(1)。

Second case: 第二种情况:

  • 100 % n == 0 does not matter really in O thinking 100%n == 0在O思维中并不重要
  • else part does not matter, it is much less than main part 其他部分没关系,它比主体部分少得多
  • outer-loop runs from 0 to n^3 => n^3 外循环从0到n ^ 3 => n ^ 3
  • inner-loop runs from 0 to n^6 => n^6 内部循环从0到n ^ 6 => n ^ 6
  • outer-loop times inner-loop => n^9 外循环时间内循环=> n ^ 9

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM