Comment calculer l'ordre (grand O) pour des algorithmes plus complexes (par exemple quicksort)
Je sais qu'il y a tout un tas de questions à propos de big O la notation, j'ai déjà vérifié:
- Un anglais simple explication de Big O
- Big O, comment calculez-vous/en approchant?
- Big O La Notation Des Devoirs--Fragment De Code De L'Algorithme D'Analyse?
pour n'en nommer que quelques-unes.
Je sais par "intuition" comment le calculer pour n
, n^2
, n!
et, donc, mais je suis complètement perdu sur la façon de la calculer pour les algorithmes qui sont log n
, n log n
, n log log n
et si.
Ce que je veux dire, je sais que le Tri Rapide est n log n
(en moyenne).. mais, pourquoi? Même chose pour la fusion/peigne, etc.
Quelqu'un pourrait-il m'expliquer en un pas trop les maths-y comment calculez-vous cela?
La raison principale est que Im sur le point d'avoir un gros entretien, et je suis sûr qu'ils vont vous demander ce genre de choses. J'ai fait des recherches depuis quelques jours maintenant, et tout le monde semble avoir une explication de pourquoi le tri à bulles est n^2 ou illisible explication (pour moi) sur Wikipédia
Vous devez vous connecter pour publier un commentaire.
Le logarithme est l'opération inverse de l'exponentiation. Un exemple de l'exponentiation est lorsque l'on double le nombre d'éléments à chaque étape. Ainsi, une échelle logarithmique de l'algorithme de souvent de moitié le nombre d'éléments à chaque étape. Par exemple, la recherche binaire tombe dans cette catégorie.
De nombreux algorithmes nécessitent un nombre logarithmique de grands pas, mais à chaque grande étape nécessite O(n) unités de travail. Mergesort tombe dans cette catégorie.
Habituellement, vous pouvez identifier ces types de problèmes par la visualisation d'un arbre binaire équilibré. Voici par exemple la fusion de tri:
En haut à l'entrée, comme les feuilles de l'arbre. L'algorithme crée un nouveau nœud en triant les deux nœuds au-dessus d'elle. Nous savons que la hauteur d'un arbre binaire équilibré est O(log n) il y a donc O(log n) grandes étapes. Toutefois, la création de chaque nouvelle ligne prend O(n) de travail. O(log n) grandes étapes de O(n) le travail de chacun que mergesort est O(n log n) dans l'ensemble.
Généralement, O(log n) algorithmes de ressembler à la fonction ci-dessous. Ils arrivent à jeter la moitié des données à chaque étape.
Tout en O(n log n) algorithmes de ressembler à la fonction ci-dessous. Ils séparent les données dans la moitié, mais ils doivent tenir compte de ces deux moitiés.
Où do_simple_case() prend O(1) fois et de les combiner() ne prend pas plus de O(n) fois.
Les algorithmes n'ont pas besoin de diviser les données exactement de moitié. Ils pourraient diviser en un tiers et deux tiers, et que ce serait bien. Pour le cas moyen de la performance, de la scission en deux en moyenne est suffisante (comme QuickSort). Tant que la récursivité est fait sur des morceaux de (n/quelque chose) et (n - n/quelque chose), c'est correct. Si c'est le brisant en (k) et (n-k), alors la hauteur de l'arbre sera en O(n) et pas de O(log n).
Vous pouvez généralement revendication de log n pour les algorithmes où il moitiés de l'espace/temps, à chaque fois qu'il exécute. Un bon exemple de ceci est un binaire de l'algorithme (par exemple, la recherche binaire). Vous choisissez soit de gauche ou de droite, qui ensuite les axes de l'espace que vous êtes à la recherche de moitié. Le modèle de reprises de faire la moitié est log n.
log
signifie logarithme base 2 au lieu de la base 10, qui est normalement supposé. journal n signifie que le numéro qui vous aurait à augmenter de 2 à n. donc journal 8 est de 3, journal 16 est de 4, etc...Pour certains algorithmes, l'obtention d'un serré en partance pour le temps d'exécution par le biais de l'intuition est presque impossible (je ne pense pas que je vais jamais être capable de deviner un
O(n log log n)
temps d'exécution, par exemple, et je doute que quelqu'un pourra jamais attendre de vous que vous). Si vous pouvez obtenir vos mains sur le CLRS Introduction aux Algorithmes de texte, vous trouverez un joli traitement approfondi de notation asymptotique qui est appropriée rigoureux sans être complètement opaque.Si l'algorithme est récursif, un moyen simple de tirer un encadrement est d'écrire une récidive et pour le résoudre, soit de manière itérative ou à l'aide de la Maître Théorème ou d'une autre façon. Par exemple, si vous ne cherchez pas à être super rigoureux à ce sujet, la meilleure façon d'obtenir QuickSort est temps d'exécution est à travers le Maître Théorème -- QuickSort implique de partitionnement de la matrice en deux relativement égale des sous-tableaux (il devrait être assez intuitif de voir que c'est
O(n)
), et puis l'appel de QuickSort de manière récursive sur ces deux sous-tableaux. Ensuite, si nous les laissonsT(n)
désigner le temps d'exécution, nous avonsT(n) = 2T(n/2) + O(n)
, qui, par le Maître de la Méthode estO(n log n)
.Découvrez le "phone book" exemple donné ici: Qu'est ce qu'un anglais simple explication de la "Big O" notation?
Rappelez-vous que Big-O est tout au sujet de échelle: comment faire beaucoup plus d'opération de cet algorithme nécessite que l'ensemble de données se développe?
O(log n) règle générale, vous pouvez couper le jeu de données en deux à chaque itération (par exemple, la recherche binaire)
O(n log n) signifie que vous effectuez un O(log n) opérations de pour chaque élément dans votre jeu de données
je suis assez sûr " O(n log log n)' n'a pas de sens. Ou si elle le fait, elle simplifie en bas à O(n log n).O(n log log n)
algorithmes existent. Par exemple: portal.acm.org/citation.cfm?id=975984Je vais tenter de faire une analyse intuitive de pourquoi Mergesort est n log n, et si vous pouvez me donner un exemple de n log log n de l'algorithme, je peux travailler à travers elle aussi.
Mergesort est un exemple de tri qui fonctionne par le partage d'une liste d'éléments à plusieurs reprises jusqu'à ce que seuls les éléments et la combinaison de ces listes ensemble. Le fonctionnement principal dans chacun de ces fusions est la comparaison et chaque fusion nécessite tout au plus n comparaisons où n est la longueur des deux listes combinées. À partir de ce que vous pouvez tirer de la récidive et de résoudre facilement, mais nous allons éviter cette méthode.
Plutôt de considérer comment Mergesort va se comporter, nous allons faire une liste et de le diviser, puis prendre les moitiés et de diviser à nouveau, jusqu'à ce que nous avons n partitions de longueur 1. J'espère qu'il est facile de voir que cette récursivité ne vont log (n) de profondeur jusqu'à ce que nous avons divisé la liste dans notre n partitions.
Maintenant que nous avons que chacun de ces n partitions doivent être fusionnées, puis une fois ceux-ci sont regroupées au niveau suivant devront être fusionnés, jusqu'à ce que nous avons une liste de longueur n de nouveau. Reportez-vous à la page wikipedia graphique pour un exemple simple de ce processus http://en.wikipedia.org/wiki/File:Merge_sort_algorithm_diagram.svg.
Maintenant tenir compte de la quantité de temps que prendra ce processus, nous allons avoir log (n) les niveaux et à chaque niveau, nous aurons à la fusion de toutes les listes. Il s'avère que chaque niveau prendra n le temps de fusion, parce que nous allons la fusion d'un total de n éléments à chaque fois. Ensuite, vous pouvez assez facilement voir qu'il va prendre la n log (n) le temps de trier un tableau avec mergesort si vous prenez l'opération de comparaison pour être l'opération la plus importante.
Si quelque chose n'est pas clair ou j'ai sauté quelque part s'il vous plaît laissez-moi savoir et je peux essayer d'être plus verbeux.
Modifier La Seconde Explication:
Laissez-moi réfléchir, si je peux vous expliquer cela mieux.
Le problème est décomposé en un tas de petites listes et puis les petites listes sont triées et regroupées jusqu'à ce que vous revenir à la liste originale qui est maintenant triée.
Lorsque vous cassez les problèmes que vous avez plusieurs niveaux de la taille d'abord vous allez avoir deux listes de taille: n/2, n/2, alors au prochain niveau, vous aurez quatre listes de taille: n/4, n/4, n/4, n/4, au niveau suivant, vous devrez n/8, n/8 ,n/8 ,n/8, n/8, n/8 ,n/8 ,n/8 cela continue jusqu'à n/2^k est égal à 1 (chaque subdivision est la longueur divisée par une puissance de 2, et non pas toutes les longueurs sera divisible par quatre, alors il ne sera pas tout à fait cette jolie). Cela est répété à la division par deux et peuvent continuer à la plupart des log_2(n) fois, parce que 2^(log_2(n) )=n, donc plus de division par 2 devrait permettre d'obtenir une liste de taille zéro.
Maintenant, la chose importante à noter est qu'à chaque niveau on a n d'éléments pour chaque niveau de la fusion prendra n le temps, parce que la fusion est une opération linéaire. Si il y a log(n), les niveaux de la récursivité ensuite, nous allons effectuer cette opération linéaire log(n) fois, par conséquent, notre temps de course sera n log(n).
Désolé si ce n'est pas très utile.
Lors de l'application d'un divide-and-conquer algorithme où vous partition le problème en sous-problèmes jusqu'à ce qu'il est si simple qu'il est trivial, si le partitionnement se passe bien, la taille de chaque sous-problème est n/2 ou penser de cela. C'est souvent à l'origine de la
log(n)
que les cultures en place dans le big-O de la complexité:O(log(n))
est le nombre d'appels récursifs nécessaire lors du partitionnement va bien.n
, c'est juste une (plus ou moins) constante de la quantité de traitement. Puisque les constantes sont ignorés dans le Big-O de notation, un divide-and-conquer algorithme de type binaire de recherche est O(log n).