A diferença entre complexidade teórica e eficiência prática


7

Se eu tiver esse pseudocódigo:

for i=0 to n/2 do
   for j=0 to n/2 do 
       ... do anything ....

O número de iterações é n2/4.

Qual é a complexidade deste programa? É issoO(n2)?

Qual é a intuição formal / informal para qual é essa complexidade?

Em seguida, se eu tiver esse outro pseudocódigo:

for i=0 to n do
   for j=0 to n do 
       ... do anything ....

A complexidade é novamente O(n2) - isso está correto?

Existe alguma diferença entre eficiência na prática e complexidade teórica neste caso? Um deles é mais rápido que o outro?


11
Regra 3 de Rob Pike, como citado em The Art of Unix Programming : "Regra 3. Os algoritmos extravagantes são lentos quando npequenos e ngeralmente são pequenos. Os algoritmos extravagantes têm grandes constantes. Até que você saiba que nfrequentemente será grande, não seja chique. " Isso ocorre devido à diferença entre complexidade teórica e eficiência prática, que é habilmente definida nas respostas abaixo.
Curinga

@Wildcard Isso parece ser uma boa regra de ouro. A comparação de vários algoritmos de concorrentes seria ainda melhor.
G. Bach

@Wildcard Citação muito interessante. É sempre interessante pensar na complexidade quando você está projetando / implementando procedimentos, mas geralmente não os interrompo até que o procedimento em questão pareça um gargalo.
Auberon

Respostas:


7

Big O Formalmente

O(f(n))={g(n)|c>0,n0>0,n>n0:0g(n)cf(n)}

Big O Informally

O(f(n)) é o conjunto de funções que crescem mais lentamente (ou igualmente rápido) do que f(n). Isso significa que qualquer função que você escolherO(f(n))vamos chamá-la g(n)e você escolhe um tamanho suficientemente grande n, f(n) será maior queg(n). Ou, em outras palavras,f(n) acabará por superar qualquer função em O(f(n)) quando n cresce maior. n é o tamanho da entrada do seu algoritmo.


Como um exemplo. Vamos escolherf(n)=n2.

Nós podemos dizer que f(n)O(n3). Observe que, com o tempo, permitimos abuso de notação para que quase todo mundo escrevaf(n)=O(n3) agora.

Normalmente, quando avaliamos algoritmos, observamos a ordem deles. Dessa forma, podemos prever como o tempo de execução do algoritmo aumentará quando o tamanho da entrada (n) aumenta.

No seu exemplo, os dois algoritmos são de ordem O(n2). Portanto, o tempo de execução aumentará da mesma maneira (quadraticamente) quenaumenta. Seu segundo algoritmo será quatro vezes mais lento que o primeiro, mas isso é algo em que geralmente não estamos interessados ​​** teoricamente *. Algoritmos com a mesma ordem podem ter fatores diferentes (cna definição formal) ou em diferentes termos de ordem inferior na função que avalia o número de etapas. Mas geralmente é por causa dos detalhes da implementação e não estamos interessados ​​nisso.

Se você tiver um algoritmo executado em O(log(n)) tempo, podemos dizer com segurança que será mais rápido do que O(n) [1] porque log(n)=O(n). Não importa o quão ruim oO(log(n)) algoritmo é implementado, não importa quanto sobrecarga você coloque no algoritmo, ele sempre será [1] mais rápido que o O(n)algoritmo. Mesmo que o número de etapas nos algoritmos seja9999log(n)=O(log(n)) e 0.0001n=O(n), a O(log(n)) o algoritmo será eventualmente mais rápido [1].

Mas, talvez, na sua aplicação, n é sempre baixo e nunca será suficientemente grande para que o O(log(n))algoritmo será mais rápido na prática . Então, usando oO(n) algoritmo resultará em tempos de execução mais rápidos, apesar de n=O(log(n))

[1] se n é suficientemente grande.


11
A O(registron) nem sempre é mais rápido que um O(n)1. Depende do valor dene nas constantes ocultas. Um exemplo é a multiplicação rápida de matrizes, que na prática não é rápida.
Yuval Filmus 21/03

Por isso acrescentei: Se n for suficientemente grande. No caso mencionado, se as matrizes crescerem suficientemente grandes,O(euog(n))Será mais rápido, por definição
Auberon

Tudo o que você está dizendo já não está na minha resposta?
Auberon

7
O OP pergunta sobre a diferença entre teoria e prática, e você está ignorando isso. A notação assintótica é geralmente, mas nem sempre, útil na prática. Melhorar o tempo de execução quatro vezes pode fazer uma enorme diferença na prática, mas a notação assintótica é completamente alheia a ela.
Yuval Filmus 21/03

5

Auberon forneceu uma explicação muito boa do Big O . Vou tentar explicar o que isso significa para você.

Primeiro de você está certo. O primeiro exemplo de código possuin24iterações, mas ainda está na classe de complexidade O(n^2).

Por quê?

A coisa sobre classes de complexidade é que nós assumimos que fazer algo várias vezes não é que ruim para a execução.

Imagine um algoritmo com complexidade em O(2^n)execução por n=31 segundo.

Poderíamos executar isso 10 vezes e ainda esperar uma resposta após cerca de 10 segundos.

Agora imagine aumentar n10. O programa levará 2^10=1024segundos.

Então, os cientistas da computação basicamente disseram: " Cara, os principais fatores são irritantes. Vamos apenas assumir que n cresce até o infinito e comparar funções lá "

Que levam à Big O .

Na prática

Na prática, é muito bem possível que uma solução com muito pior complexidade seja executada muito mais rapidamente (para entradas "pequenas"). É fácil imaginar um programa que é executado, O(n)mas precisa de 10^10*niterações.

É O (n), mas mesmo uma O(2^n)solução poderia ser mais rápida para n pequeno.

Em suma:

O Big O é uma ferramenta útil. Mas você ainda precisa pensar na rapidez com que o algoritmo está em prática, pois ele descreve apenas quanto mais tempo será necessário se a entrada aumentar.


3

Se eu tiver esse pseudocódigo:

for i=0 to n/2 do
   for j=0 to n/2 do 
       ... do anything ....

O número de iteração é n2/4.

Na verdade, é (1 1+n/2)2=n2/4+n+1 1.

Qual é a complexidade deste programa? Está corretoO(n2)?

Isso depende inteiramente do que é "fazer qualquer coisa". Por exemplo, se "fazer qualquer coisa" for substituído pela linha

for k=0 to 2^n do {}

então o tempo de execução é Θ(n22n).

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.