O grande: aninhado para loop com dependência

9

Recebi uma tarefa de casa com Big O. Estou preso a aninhados para loops que dependem do loop anterior. Aqui está uma versão alterada da minha pergunta de lição de casa, pois eu realmente quero entender:

sum = 0;
for (i = 0; i < n; i++ 
    for (j = 0; j < i; j++) 
        sum++;

A parte que está me excitando é a j < iparte. Parece que seria executado quase como um fatorial, mas com adição. Qualquer dica seria muito apreciada.

Rafael
fonte
Boa explicação aqui
saadtaame 17/09/12

Respostas:

10

Então, deixe-me esclarecer algumas coisas, você está interessado na notação big-O - isso significa limite superior . Em outras palavras, não há problema em contar mais etapas do que você realmente faz. Em particular, você pode modificar o algoritmo para

 ...
    for (j = 0; j < n; j++) 
 ...

Portanto, você tem dois loops aninhados, cada loop é executado vezes, o que fornece um limite superior de O ( n 2 )nO(n2)

Obviamente, você gostaria de ter uma boa estimativa para o limite superior. Portanto, para conclusão, queremos determinar um limite inferior. Isso significa que não há problema em contar menos etapas. Então considere a modificação

for (i = n/2; i < n; i++)
    for (j = 0; j < n/2; j++) 
        sum++;

Aqui, realizamos apenas algumas das iterações de loop. Mais uma vez que têm dois circuitos encaixados, mas desta vez que temos iterações por ciclo, o que mostra que têm, pelo menos, n 2 / 4 adições. Nesse caso, denotamos esse limite inferior assintótico por Ω ( n 2 ) . Como os limites inferior e superior coincidem, podemos até dizer que n 2 é um limite assintótico apertado e escrevemos Θ ( n 2 ) .n/2n2/4Ω(n2)n2Θ(n2)

Se você quiser saber mais, leia aqui .

A.Schulz
fonte
6
sum = 0;
for (i = 0; i < n; i++)
    for (j = 0; j < i; j++) 
        sum++;

Vamos traçar isso:

  • Quando i = 0, o loop interno não será executado ( 0<0 == false).
  • Quando i = 1, o loop interno será executado uma vez (para j == 0).
  • Quando i = 2, o loop interno será executado duas vezes. (para j == 0 e j == 1).

Este algoritmo incrementará sumo seguinte número de vezes:

x=1 1nx-1 1=0 0+1 1+2+3+4 ...+n-1 1=n(n-1 1)2

nn2-n2n2θ(n2)O(n2) umand Ω(n2)

KeithS
fonte
3

vamos ver se consigo explicar isso ...

Portanto, se o loop interno fosse j

Agora, para a primeira iteração, você faz n- (n-1) vezes no loop interno. na segunda vez, você faz n- (n-2) vezes no loop interno. Na enésima vez, você faz n- (nn) vezes, o que é n vezes.

se você calcular a média do número de vezes que passa pelo loop interno, seria n / 2 vezes.

Então você poderia dizer que isto é O (n * n / 2) = O (n ^ 2/2) = O (n ^ 2)

Isso faz sentido?


fonte
É um pouco estranho, mas acho que entendi! Obrigado! Pode demorar um pouco de tempo para afundar todo o caminho em haha
Então, se essa j < iparte era realmente j < i^2, o O resultante para essa parte seria n ^ 2/2?
Antes de tudo, observe que O (n ^ 2/2) = O (n ^ 2). Agora, se você alterá-lo para j <i ^ 2, estará executando (n- (n-1)) ^ 2 na primeira iteração e n ^ 2 na última iteração. Não lembro qual seria a notação big-O para o loop interno. O (n ^ 2) é um limite superior frouxo. Portanto, um limite superior solto para a coisa toda seria O (n ^ 3), mas esse loop interno é menor que O (n ^ 2). Isso faz sentido?