简体   繁体   English

如何找到以下代码的最坏情况的复杂性?

[英]How do I find worst-case complexity of the following code?

Need to know the worst-case complexity of the following code, would be grateful if you could provide the steps of how to solve it. 需要知道以下代码的最坏情况的复杂性,如果您能提供解决问题的步骤,将不胜感激。 I was thinking of the answer n^3logn, but not sure. 我在想答案n ^ 3logn,但不确定。

int complexity(int n)
  int i,j,c
  for(i=1; i < n; i=i*3)
    for(j=n; j < n*n; j++)
      c++
  for(i=c; i > 0; i--)
    if(random(0...999) > 0)
      for(j=0; j < 3*n; j++)
        c++
    else
      for(j=2*n*n; j > 0; j--)
        c++
  return c

Let's look at the first nested loop 让我们看一下第一个嵌套循环

for(i=1; i < n; i=i*3)
    for(j=n; j < n*n; j++)
        c++

The outer loop runs log(n) times [log base 3, but base changes is multiplying by a constant which does not effect the asymptotic complexity] and the inner loop n^2 times, thus after this loop c = n^2 * log(n) . 外循环运行log(n)次[以3为底的对数,但底数变化乘以一个不会影响渐近复杂性的常数],而内循环运行n^2次,因此在此循环之后c = n^2 * log(n)

For the second loop: 对于第二个循环:

for(i=c; i > 0; i--)
    if(random(0...999) > 0)
       for(j=0; j < 3*n; j++)
          c++
   else
      for(j=2*n*n; j > 0; j--)
        c++

In the worst case the else case always happens, so we can modify it to 在最坏的情况下, else情况总是会发生,因此我们可以将其修改为

for(i=c; i > 0; i--)
  for(j=2*n*n; j > 0; j--)
    c++

The outer loop happens c times, which is O(n^2 * log(n)) and the inner loop increments c by 2*n^2 , so c is incremented by 2 * n^2 * n^2 * log(n) , adding the initial value we get that c (and thus the overall complexity) is in O(2*n^4*log(n) + n^2 * log(n)) = O(n^4 * log(n)) 外环发生c倍,这是O(n^2 * log(n))和所述内环增量c2*n^2 ,所以c被增加2 * n^2 * n^2 * log(n) ,加上初始值,我们得出c (以及整体复杂度)为O(2*n^4*log(n) + n^2 * log(n)) = O(n^4 * log(n))

I hope I'm not just doing your homework for you. 我希望我不仅为您做功课。 In future I recommend showing your thought processes thus far, rather than just your final answer. 今后,我建议您显示到目前为止的思维过程,而不只是最终的答案。

Let's look at this code one section at a time. 让我们一次来看一下这段代码。

int complexity(int n)
    int i,j,c
    for(i=1; i < n; i=i*3)
        for(j=n; j < n*n; j++)
            c++

So in the outer loop, i goes from 1 to n, but each time i is tripled. 因此,在外循环中,我从1到n,但是每次将我增加三倍。 This means it will finish after log_3(n) loops. 这意味着它将在log_3(n)循环后完成。 Changing base of log is just a constant factor, which doesn't matter in computational complexity, so we can just say log(n). 更改日志基数只是一个常量因素,与计算复杂性无关,因此我们可以说log(n)。

The inner loop has j going from n to n^2. 内循环使j从n变为n ^ 2。 O(n^2 - n) = O(n^2) since lower powers are dwarfed by higher ones (ie quadratic dwarfs linear). O(n ^ 2-n)= O(n ^ 2),因为较低的幂比较高的幂小(即,线性的二次方矮)。

So putting this all together, the first section has computational complexity O(n^2 logn). 因此,将所有这些放在一起,第一部分的计算复杂度为O(n ^ 2 logn)。 Now let's look at the second section. 现在让我们看第二部分。

for(i=c; i > 0; i--)
    if(random(0...999) > 0)
        for(j=0; j < 3*n; j++)
            c++
    else
        for(j=2*n*n; j > 0; j--)
            c++
return c

Now because the outer loop's initialization depends on c, we need to know what c is. 现在,由于外循环的初始化取决于c,因此我们需要知道c是什么。 c was incremented every time in the first two nested loops, so c's value is proportional to n^2 logn. 在前两个嵌套循环中,c每次都会增加,因此c的值与n ^ 2 logn成正比。 Thus the outer loop will run O(n^2 logn) times. 因此,外循环将运行O(n ^ 2 logn)次。

For the inner loops, remember we are always considering the worst-case scenario. 对于内部循环,请记住,我们始终在考虑最坏的情况。 So the random number generator is a bit misleading: compute the computational complexity of both j loops, and assume the worst case always happens. 因此,随机数发生器有点误导性:计算两个j循环的计算复杂度,并假设最坏的情况总是发生。

The first j loop goes from 0 to 3n, which is simply O(n). 第一个j循环从0到3n,即O(n)。 The second j loop goes from 2n^2 to 0 which is simply O(n^2). 第二个j循环从2n ^ 2变为0,即O(n ^ 2)。 Since the second case is worse, we assume it always happens (even though this is highly improbable). 由于第二种情况更糟,因此我们假定它总是会发生(即使这种情况不太可能发生)。 So the inner loop is O(n^2). 因此,内部循环为O(n ^ 2)。

Multiplying the two nested loops together, we get O(n^2 logn xn^2) = O(n^4 logn). 将两个嵌套循环相乘,我们得到O(n ^ 2 logn xn ^ 2)= O(n ^ 4 logn)。

Finally, remember we have to see which of the two sections dominated. 最后,请记住我们必须看到两个部分中的哪个占主导地位。 The first section was O(n^2 logn) and the second was O(n^4 logn), so we want O(n^2 logn + n^4 logn). 第一部分是O(n ^ 2 logn),第二部分是O(n ^ 4 logn),因此我们需要O(n ^ 2 logn + n ^ 4 logn)。 The latter term obviously dominates, so the final answer is O(n^4 logn). 后一项显然占主导地位,因此最终答案是O(n ^ 4 logn)。

Hope this helps. 希望这可以帮助。 Please ask if some part was unclear. 请询问是否不清楚。

ps The current top answer states that c will be ~n^3/3. ps当前的最高答案表明c将为〜n ^ 3/3。 Because i is tripling every time, this is incorrect; 因为我每次都三倍,这是不正确的; it will be n^2 log_3(n). 它将是n ^ 2 log_3(n)。 Otherwise their work is correct. 否则他们的工作是正确的。

The way to solve this is to work out a formula that gives c as a function of n . 解决此问题的方法是制定一个公式 ,将c作为n的函数。 (We can use the number of c++ operations as a proxy for the overall number of operations.) (我们可以将c++操作的数量用作总操作数量的代理。)

In this case, the random function means that you can't get an exact formula. 在这种情况下, random函数意味着您无法获得精确的公式。 But you can work out two formulae, one for the case where random always returns zero, and the other for the case where random always returns > zero. 但是您可以计算出两个公式,一个公式用于random总是返回零的情况,另一个用于random总是返回>零的情况。

How do you work out the formula / formulae? 您如何计算公式? Maths! 数学!

Hint: the worst-case will be one of the two cases that I mentioned above. 提示:最坏的情况将是我上面提到的两种情况之一。 (Which one? The one whose complexity is worst, of course!) (当然是哪一个?复杂度最差的那个!)

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

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