web-dev-qa-db-fra.com

Quel est le meilleur: O (n log n) ou O(n^2)

D'accord, j'ai ce projet à faire, mais je ne le comprends pas. Le truc, c'est que j'ai 2 algorithmes. O (n ^ 2) et O (n * log2n)

Quoi qu'il en soit, je découvre dans les informations du projet que si n <100 , alors O (n ^ 2) est plus efficace, mais si n> = 100 , alors O ( n * log2n) est plus efficace. Je suis censé démontrer avec un exemple en utilisant des nombres et des mots ou en tirant une photo. Mais le fait est que je ne comprends pas cela et je ne sais pas comment le démontrer.

Quelqu'un ici peut m'aider à comprendre comment cela fonctionne?

Bravo d'avance!

EDIT: Merci à tous pour les réponses.

26
user3579272

Il suffit de demander wolframalpha si vous avez des doutes.

Dans ce cas, il est dit

     n log(n)
lim --------- = 0
       n^2

Ou vous pouvez également calculer la limite vous-même:

     n log(n)        log(n)   (Hôpital)       1/n          1
lim --------- = lim --------      =     lim ------- = lim --- = 0
       n^2             n                       1           n

Cela signifie que n^2 croît plus vite, donc n log(n) est plus petit (meilleur), lorsque n est suffisamment élevé.

25
Oriol

Bonne question. En fait, je montre toujours ces 3 images:

n = [0; dix]

enter image description here

n = [0; 100]

enter image description here

n = [0; 1000]

enter image description here

Donc, O(N*log(N)) est bien meilleur que O(N^2). Il est beaucoup plus proche de O(N) que de O(N^2).

Mais votre algorithme O(N^2) est plus rapide pour N < 100 dans la vie réelle. Il y a beaucoup de raisons pour lesquelles cela peut être plus rapide. Peut-être en raison d'une meilleure allocation de mémoire ou d'autres effets "non algorithmiques". Peut-être que l'algorithme O(N*log(N)) requiert une phase de préparation des données ou que les itérations O(N^2) sont plus courtes. Quoi qu'il en soit, la notation Big-O n'est appropriée qu'en cas d'assez grand Ns.

Si vous voulez démontrer pourquoi un algorithme est plus rapide pour les petits N, vous pouvez mesurer temps d'exécution de 1 itération et constante overhead pour les deux algorithmes, puis utilisez-les pour corriger le tracé théorique:

Exemple

enter image description here

Ou alors, mesurez simplement le temps d'exécution des deux algorithmes pour différentes données empiriques Ns et de tracé.

49
Stas

La notation Big-O est une notation de complexité asymptotique . Cela signifie qu'il calcule la complexité lorsque N est arbitrairement grand.

Pour les petits N, beaucoup d'autres facteurs entrent en jeu. Il est possible qu'un algorithme ait des itérations de boucle O (n ^ 2), mais chaque itération est très courte, tandis qu'un autre algorithme possède des O(n) itérations avec des temps très longs. itérations. Avec de grands Ns, l'algorithme linéaire sera plus rapide. Avec de petits Ns, l'algorithme quadratique sera plus rapide.

Donc, pour les petits N, mesurez simplement les deux et voyez lequel est le plus rapide. Pas besoin d'entrer dans la complexité asymptotique.

Incidemment, n'écrivez pas la base du journal. La notation Big-O ignore les constantes - O (17 * N) est identique à O (N). Depuis le journal2N est juste ln N / ln 2, la base du logarithme est juste une autre constante et est ignorée.

14
zmbq

Comparons-les,

D'une part nous avons:

n^2 = n * n

D'autre part nous avons:

nlogn = n * log(n)

Les mettre côte à côte:

n * n    versus    n * log(n)

Divisons par n qui est un terme courant pour obtenir:

n    versus    log(n)

Comparons les valeurs:

n = 10           log(n) ~ 2.3
n = 100          log(n) ~ 4.6
n = 1,000        log(n) ~ 6.9
n = 10,000       log(n) ~ 9.21
n = 100,000      log(n) ~ 11.5
n = 1,000,000    log(n) ~ 13.8

Donc nous avons:

n >> log(n) for n > 1

n^2 >> n log(n) for n > 1
7
Khaled.K

Tout d'abord, il n'est pas tout à fait correct de comparer la complexité asymptotique mélangée à la contrainte de N. I.E., je peux affirmer:

  • O(n^2) est plus lent que O(n * log(n)), car la définition de Big O notation inclura n is growing infinitely.

  • Pour N particulier, il est possible de dire quel algorithme est le plus rapide en comparant simplement N^2 * ALGORITHM_CONSTANT et N * log(N) * ALGORITHM_CONSTANT, où ALGORITHM_CONSTANT dépend de l'algorithme. Par exemple, si nous traversons un tableau deux fois pour effectuer notre travail, la complexité asymptotique sera O(N) et ALGORITHM_CONSTANT sera 2.

De plus, je voudrais mentionner cette O(N * log2N) dont je suppose que logariphm est basé sur 2 (log2N) est en fait identique à O(N * log(N)) en raison des propriétés logariphm.

1
Alexey Malev

Nous avons deux moyens de comparer deux Algo -> le premier moyen est très simple comparer et appliquer la limite

T1(n)-Algo1

T2(n)=Alog2

  lim  (n->infinite) T1(n)/T2(n)=m  

(i) si m = 0, Algo1 est plus rapide qu'Algo2

(ii) m = k Les deux sont identiques

(iii) m = infini Algo2 est plus rapide

* Deuxième façon assez simple, comparée à la première, il suffit de prendre un journal des deux mais il ne faut pas négliger la constante multiple

             Algo 1=log n

             Algo 2=sqr(n)

             keep log n =x

             Any poly>its log


   O(sqr(n))>o(logn)
0
MAYANK TYAGI