web-dev-qa-db-fra.com

N ou nlog (n) est-il meilleur que le temps constant ou logarithmique?

Dans le didacticiel de Princeton sur Coursera, le professeur explique les fonctions courantes de l'ordre de croissance rencontrées. Il dit que les durées de fonctionnement linéaires et linéaires sont "ce pour quoi nous nous efforçons" et son raisonnement était que lorsque la taille d'entrée augmente, le temps de fonctionnement augmente également. Je pense que c'est là qu'il a fait une erreur car je l'ai déjà entendu parler d'un ordre de croissance linéaire comme insatisfaisant pour un algorithme efficace.

Pendant qu'il parlait, il a également montré un graphique qui traçait les différents temps de fonctionnement - les temps de fonctionnement constants et logarithmiques semblaient être plus efficaces. Est-ce que c'était une erreur ou est-ce vrai?

11
template boy

Vous manquez le contexte plus large dans lequel ces déclarations doivent avoir été faites. Différents types de problèmes ont des exigences différentes, et ont souvent même des limites théoriques sur la quantité de travail absolument nécessaire pour les résoudre, quels que soient les moyens.

Pour des opérations telles que le tri ou l'analyse de chaque élément d'une collection simple, vous pouvez faire une limite inférieure stricte du nombre d'éléments dans la collection pour ces opérations, car la sortie dépend de chaque élément de l'entrée. [1] Ainsi, O(n) ou O (n * log (n)) sont les meilleurs que l'on puisse faire.

Pour d'autres types d'opérations, comme l'accès à un seul élément d'une table de hachage ou d'une liste liée, ou la recherche dans un ensemble trié, l'algorithme n'a pas besoin d'examiner toutes les entrées. Dans ces paramètres, une opération O(n) serait terriblement lente.

[1] D'autres noteront que le tri par comparaison a également une borne inférieure n * log (n), à partir d'arguments théoriques de l'information. Il existe des algorithmes de tri non comparatifs qui peuvent battre cela, pour certains types d'entrée.

14
Phil Miller

C'est une erreur prise dans le contexte que les fonctions O(n) et O (n log n) ont une meilleure complexité que O(1) et O fonctions (log n). Lors de la recherche de cas typiques de complexité en notation O:

O(1) < O(log n) < O(n) < O(n log n) < O(n^2)

Notez que cela ne signifie pas nécessairement qu'ils seront toujours meilleurs en termes de performances - nous pourrions avoir une fonction O(1) qui prend beaucoup de temps à exécuter même si sa complexité n'est pas affectée par nombre d'éléments. Une telle fonction aurait une meilleure apparence en grande notation O qu'une fonction O (log n), mais pourrait en fait fonctionner moins bien en pratique.

De manière générale: une fonction avec une complexité plus faible (en grande notation O) surclassera une fonction avec une plus grande complexité (en grande notation O) lorsque n est suffisamment élevé.

35
Conduit

Les algorithmes avec un comportement sublinéaire comme O(1) ou O(Log(N)) sont spéciaux en ce qu'ils ne nécessitent pas de regarder tous les éléments. D'une certaine manière, c'est une erreur car s'il y a vraiment N éléments, il faudra O(N) juste pour les lire ou les calculer.

Les algorithmes sous-linéaires sont souvent possibles après un certain prétraitement. Pensez à la recherche binaire dans une table triée, en prenant O (Log (N)). Si les données sont initialement non triées, il en coûtera O (N Log (N)) pour les trier en premier. Le coût du tri peut être équilibré si vous effectuez de nombreuses recherches, disons K, sur le même ensemble de données. En effet, sans le tri, le coût des recherches sera O (K N), et avec un pré-tri O (N Log (N) + K Log (N)). Vous gagnez si K >> Log (N).

Cela dit, quand aucun prétraitement n'est autorisé, le comportement O(N) est idéal, et O (N Log (N)) est également assez confortable (pour un million d'éléments, Lg (N) est seulement 20). Vous commencez à crier avec O (N²) et pire.

3
Yves Daoust

D'une manière générale, ce que nous visons, c'est le mieux que nous puissions faire. Mais selon ce que nous faisons, cela pourrait être O (1), O (log log N), O (log N), O (N), O (N log N), O (N2), SUR3), ou (ou certains algorithmes) peut-être O (N!) ou même O (2N).

Par exemple, lorsque vous avez affaire à une recherche dans une collection triée, la recherche binaire est triviale et donne une complexité O (log N). Si la distribution des éléments de la collection est raisonnablement prévisible, nous pouvons généralement faire encore mieux - autour de O (log log N). Sachant cela, un algorithme qui était O(N) ou O (N2) (pour quelques exemples évidents) serait probablement assez décevant.

D'un autre côté, le tri est généralement un peu plus complexe - les "bons" algorithmes gèrent O (N log N), et les plus pauvres sont généralement autour de O (N2). Par conséquent, pour trier un algorithme O(N) est en fait très bon (en fait, uniquement possible pour les types d'entrées plutôt contraints), et nous pouvons à peu près compter sur le fait que quelque chose comme O (log log N) n'est tout simplement pas possible.

Pour aller encore plus loin, nous serions heureux de gérer une multiplication matricielle dans seulement O (N2) au lieu du O habituel (N3). Nous serions extatique pour obtenir des réponses optimales et reproductibles au problème du voyageur de commerce ou au problème de somme de sous-ensemble dans seulement O (N3), étant donné que les solutions optimales à celles-ci nécessitent normalement O (N!).

3
Jerry Coffin

Il a dit que ces algorithmes sont ce que nous recherchons, ce qui est généralement vrai. De nombreux algorithmes ne peuvent pas être améliorés mieux que le temps logarithmique ou linéaire, et bien que le temps constant soit meilleur dans un monde parfait, il est souvent impossible à atteindre.

1
StilesCrisis

le temps constant est toujours meilleur parce que la complexité du temps (ou de l'espace) ne dépend pas de la taille du problème ... n'est-ce pas une excellente fonctionnalité? :-)

alors nous avons O(N) puis Nlog (N)

le saviez-vous? des problèmes avec une complexité temporelle constante existent!

par exemple.

soit A [N] un tableau de N valeurs entières, avec N> 3. Recherche et algorithme pour dire si la somme des trois premiers éléments est positive ou négative.

1
Gianluca Ghettini

Ce que nous recherchons, c'est efficacité, dans le sens de concevoir des algorithmes avec une complexité temporelle (ou spatiale) qui ne dépasse pas leur limite inférieure théorique.

Par exemple, en utilisant des algorithmes basés sur la comparaison, vous ne pouvez pas trouver une valeur dans un tableau trié plus rapidement que Omega (Log (N)), et vous ne pouvez pas trier un tableau plus rapidement que Omega (N Log (N)) - dans le pire des cas Cas.

Ainsi, la recherche binaire O(Log(N)) et Heapsort O (N Log (N)) sont des algorithmes efficaces, tandis que la recherche linéaire O(N) et Bubblesort O (N²) ne le sont pas.

La borne inférieure dépend du problème à résoudre, pas de l'algorithme.

0
Yves Daoust

Oui, le temps constant, c'est-à-dire O(1) est meilleur que le temps linéaire O(n) parce que le premier ne dépend pas de la taille d'entrée du problème). L'ordre est O(1)> O (logn)> O (n)> O (nlogn). Temps linéaire ou linéaire thimique que nous recherchons car aller pour O(1) pourrait ne pas être réaliste car dans chaque algorithme de tri, nous avons au moins besoin de quelques comparaisons que le professeur essaie de prouver avec son analyse de comparaison d'arbre de décision où il essaie de trier trois éléments abc et prouve une limite inférieure de nlogn. sa "complexité du tri" dans la conférence Mergesort.

0
Vijay Bhatt