web-dev-qa-db-fra.com

Déterminer les temps d'exécution big-O de ces différentes boucles?

J'ai une série de questions dans lesquelles j'ai besoin de commentaires et de réponses. Je commenterai ce que je pense, ce n'est pas un devoir mais plutôt une préparation pour mon examen.

Mon principal problème est de déterminer les itérations d'une boucle pour différents cas. Comment pourrait-on essayer de comprendre cela?

Évaluez le temps d'exécution.

Q2.

 for(int i =0 ; i < =n ; i++) // runs n times
   for(int j =1; j<= i * i; j++) // same reasoning as 1. n^2
      if (j % i == 0)
         for(int k = 0; k<j; k++) // runs n^2 times? <- same reasoning as above.
            sum++;

Réponse correcte: N × N2 × N = O (N ^ 4)

Pour les questions ci-dessous, je n'ai pas les bonnes réponses.

Q3. une)

     int x=0; //constant
     for(int i=4*n; i>=1; i--) //runs n times, disregard the constant
         x=x+2*i;

Ma réponse: O (n)

b) Supposons pour simplifier que n = 3 ^ k

    int z=0;
    int x=0;
    for (int i=1; i<=n; i=i*3){ // runs n/3 times? how does it effect final answer?
       z = z+5;
       z++;
       x = 2*x;
    }

Ma réponse: O (n)

c) Supposons pour simplifier que n = k ^ 2,

   int y=0; 
   for(int j=1; j*j<=n; j++) //runs O(logn)?  j <= (n)^1/2
   y++; //constant

Ma réponse: O (logn)

ré)

  int b=0; //constant
  for(int i=n; i>0; i--) //n times
    for(int j=0; j<i; j++) // runs n+ n-1 +...+ 1. O(n^2) 
      b=b+5;

Ma réponse: O (n ^ 3)

e)

 int y=1;
 int j=0;
 for(j=1; j<=2n; j=j+2) //runs n times
    y=y+i;
 int s=0;
 for(i=1; i<=j; i++) // runs n times
 s++;

Ma réponse: O (n)

(F)

 int b=0;
 for(int i=0; i<n; i++) //runs n times
   for(int j=0; j<i*n; j++) //runs n^2 x n times? 
      b=b+5;

Ma réponse: O (n ^ 4)

(g) Supposons pour simplifier que n = 3k, pour un entier positif k.

   int x=0;
   for(int i=1; i<=n; i=i*3){  //runs 1, 3, 9, 27...for values of i. 
     if(i%2 != 0) //will always be true for values above
      for(int j=0; j<i; j++) // runs n times
        x++;
    }

Ma réponse: O (n x base log 3 n?)

(h) Supposons pour simplifier que n = k2, pour un entier positif k.

   int t=0;
   for(int i=1; i<=n; i++) //runs n times
      for(int j=0; j*j<4*n; j++) //runs O(logn)
         for(int k=1; k*k<=9*n; k++) //runs O(logn)
            t++;

Ma réponse: n x logn x log n = O (n log n ^ 2)

(i) Supposons pour simplifier que n = 2s, pour certains entiers positifs s.

   int a = 0;
   int k = n*n;
     while(k > 1) //runs n^2
     {
       for (int j=0; j<n*n; j++) //runs n^2
          { a++; }
        k = k/2;
    }

Ma réponse: O (n ^ 4)

(j)

  int i=0, j=0, y=0, s=0;
  for(j=0; j<n+1; j++) //runs n times
     y=y+j; //y equals n(n+1)/2 ~ O(n^2)
  for(i=1; i<=y; i++) // runs n^2 times
     s++;

Ma réponse: O (n ^ 3)

(k) int i = 1, z = 0; tandis que (z <n * (n + 1)/2) {// série arithmétique, s'exécute n fois z + = i; i ++; }

Ma réponse: O (n)

(m) Supposons pour simplifier que n = 2s, pour certains entiers positifs s.

  int a = 0;
  int k = n*n*n;
  while(k > 1) //runs O(logn) complexity
   {
     for (int j=0; j<k; j++) //runs n^3 times
      { a--; }
     k = k/2; 
    }

Ma réponse: O (n ^ 3 log n)

Question 4

http://i.stack.imgur.com/zMkt7.jpg

  • a) Vrai - puisque son borné ci-dessous par n ^ 2
  • b) Faux - f(n) pas strictement inférieur à g (n)
  • c) Vrai
  • d) Vrai délimité par n ^ 10
  • e) Faux - f(n) pas strictement inférieur à g (n)
  • f) Vrai
  • g) Vrai
  • h) false - car n'est pas égal à O (nlogn)
  • i) vrai
  • j) pas sûr
  • k) pas sûr
  • l) je ne sais pas - comment devrais-je même essayer cela? *

Merci d'avance.

19
warpstar

Passons en revue celui-ci à la fois.

Partie (a)

 int x=0; //constant
 for(int i=4*n; i>=1; i--) //runs n times, disregard the constant
     x=x+2*i;

Ma réponse: O (n)

Oui! C'est correct. La boucle s'exécute O(n) fois et fonctionne O(1)) par itération.

Partie (b)

int z=0;
int x=0;
for (int i=1; i<=n; i=i*3){ // runs n/3 times? how does it effect final answer?
   z = z+5;
   z++;
   x = 2*x;
}

Ma réponse: O (n)

Pas assez. Pensez aux valeurs de i à mesure que la boucle progresse. Il prendra la série de valeurs 1, 3, 9, 27, 81, 243, ..., 3k. Puisque i triplait à chaque itération, il prend des puissances successives de trois.

La boucle ne fait clairement que O(1) fonctionner par itération, donc la principale question ici est de savoir combien d'itérations il y aura. La boucle s'arrêtera lorsque i> n. Si nous laissons k être une itération arbitraire de la boucle, la valeur de i à l'itération k sera 3k. La boucle s'arrête lorsque 3k > n, ce qui se produit lorsque k> log3 n. Par conséquent, le nombre d'itérations n'est que de O (log n), donc la complexité totale est de O (log n).

Partie (c)

int y=0; 
for(int j=1; j*j<=n; j++) //runs O(logn)?  j <= (n)^1/2
    y++; //constant

Ma réponse: O (logn)

Pas assez. Notez que j continue de croître de façon linéaire, mais la boucle fonctionne aussi longtemps que j2 ≤ n. Cela signifie que dès que j dépasse √ n, la boucle s'arrête. Par conséquent, il n'y aura que O (√n) itérations de la boucle, et comme chacune fait O(1) travail, le travail total effectué est O (√n).

Partie (d)

int b=0; //constant
for(int i=n; i>0; i--) //n times
   for(int j=0; j<i; j++) // runs n+ n-1 +...+ 1. O(n^2) 
      b=b+5;

Ma réponse: O (n ^ 3)

Pas assez. En fait, vous comptez doublement une grande partie du travail que vous devez faire. Vous avez raison, la boucle interne fonctionnera n + (n-1) + (n-2) + ... + 1 fois, ce qui est O (n2) fois, mais vous résumez déjà à travers toutes les itérations de la boucle externe. Vous n'avez pas besoin de multiplier cette valeur par O(n) une fois de plus. La réponse la plus précise serait O (n2).

Partie (e)

int y=1;
int j=0;
for(j=1; j<=2n; j=j+2) //runs n times
   y=y+i;

int s=0;
for(i=1; i<=j; i++) // runs n times
   s++;

Ma réponse: O (n)

Oui! Exactement raison.

Partie (f)

int b=0;
for(int i=0; i<n; i++) //runs n times
    for(int j=0; j<i*n; j++) //runs n^2 x n times? 
       b=b+5;

Ma réponse: O (n ^ 4)

Encore une fois, je crois que vous surestimez. La boucle interne s'exécutera 0 + n + 2n + 3n + 4n + ... + n(n-1) = n (0 + 1 + 2 + ... + n - 1 ) fois, donc le travail total effectué est O (n3). Vous ne devez pas multiplier par le nombre d'exécutions de la boucle externe, car vous résumez déjà sur toutes les itérations. L'exécution la plus précise serait O (n3).

Partie (g)

int x=0;
for(int i=1; i<=n; i=i*3){  //runs 1, 3, 9, 27...for values of i. 
   if(i%2 != 0) //will always be true for values above
      for(int j=0; j<i; j++) // runs n times
         x++;
 }

Ma réponse: O (n x base log 3 n?)

La boucle externe s'exécutera en effet O (log n) fois, mais voyons combien de travail la boucle interne fait. Vous avez raison de dire que l'instruction if a toujours la valeur true. Cela signifie que la boucle intérieure fera 1 + 3 + 9 + 27 + ... + 3journal3 n travail. Cependant, cette somme résume (3)journal3 n + 1 - 1)/2 = (3n + 1)/2. Par conséquent, le travail total effectué ici est juste O (n).

Partie (h)

int t=0;
for(int i=1; i<=n; i++) //runs n times
   for(int j=0; j*j<4*n; j++) //runs O(logn)
      for(int k=1; k*k<=9*n; k++) //runs O(logn)
         t++;

Ma réponse: n x logn x log n = O (n log n ^ 2)

Pas assez. Regardez la deuxième boucle. Cela s'exécute en fait O (√n) fois en utilisant la même logique que l'une des parties précédentes. Cette troisième boucle interne exécute également O (√n) fois, et donc le travail total effectué sera O (n2).

Partie (i)

int a = 0;
int k = n*n;
while(k > 1) //runs n^2
{
    for (int j=0; j<n*n; j++) //runs n^2
       { a++; }
     k = k/2;
}

Ma réponse: O (n ^ 4)

Pas assez. La boucle externe commence par k initialisé à n2, mais notez que k est divisé par deux à chaque itération. Cela signifie que le nombre d'itérations de la boucle externe sera log (n2) = 2 log n = O (log n), la boucle externe ne s'exécute donc que O (log n) fois. Cette boucle intérieure fait O (n2) fonctionne, donc le temps d'exécution total est O (n2 log n).

Partie (j)

int i=0, j=0, y=0, s=0;
for(j=0; j<n+1; j++) //runs n times
   y=y+j; //y equals n(n+1)/2 ~ O(n^2)
for(i=1; i<=y; i++) // runs n^2 times
   s++;

Ma réponse: O (n ^ 3)

Fermer, mais pas tout à fait! La première boucle s'exécute dans le temps O(n) et au moment où elle est terminée, la valeur de j est Θ (n2). Cela signifie que la deuxième boucle s'exécute pendant le temps Θ (n2), donc le temps total passé est Θ (n2).

Partie (k)

 int i=1, z=0;
 while( z < n*(n+1)/2 )//arithmetic series, runs n times
 {
       z+=i; i++;
 }

Ma réponse: O (n)

C'est correct!

Partie (l)

C'est bizarre, il n'y a pas de partie (l).

Partie (m)

int a = 0;
int k = n*n*n;
while(k > 1) //runs O(logn) complexity
{
   for (int j=0; j<k; j++) //runs n^3 times
   { a--; }
   k = k/2; 
}

Ma réponse: O (n ^ 3 log n)

Fermer, mais pas tout à fait. Vous avez raison de dire que la boucle externe exécute O (log n) fois et que la boucle interne exécute O (n3) travailler sur la première itération. Cependant, regardez de plus près le nombre d'itérations de la boucle intérieure:

n3 + n3 / 2+ n3 / 4 + n3 / 8 + ...

= n3 (1 + 1/2 + 1/4 + 1/8 + ...)

≤ 2n3

Donc, le travail total effectué ici n'est en fait que O (n3), même s'il existe des itérations log n.

Question 4

Vos réponses sont toutes correctes à l'exception de celles-ci:

f) Vrai

C'est en fait faux. L'expression à gauche est

(3/2) n3/2 + 5n2 + lg n

qui est pas Ω (n2 √n) = Ω (n5/2)

Pour (j), notez que log n6 = 6 log n. Est ce que ça aide?

Pour (k), demandez si les deux côtés sont O et Ω l'un de l'autre. Que trouvez-vous?

Pour (l), utilisez le fait qu'unjournalb c = cjournalbune. Est ce que ça aide?

J'espère que cela t'aides!

31
templatetypedef