Tutoriel sur la complexité de l'espace des algorithmes [double]
-
25-10-2019 - |
Question
J'ai toujours eu du mal à calculer le temps Big-O et de la complexité de l'espace des algorithmes que j'écris.
Quelqu'un peut-il nous montrer une bonne ressource pour étudier plus sur la complexité de l'espace des algorithmes il.
EDIT: J'avais recherché des tutoriels avant de poster ici. Malheureusement, tous les tutoriels se concentrent sur la complexité des temps d'exécution et d'écriture à peine plus que quelques lignes sur la complexité de l'espace.
La solution
Selon l'endroit où vous voulez sauter, cette peut être bon pied-Dipper. wiki est également de haute qualité, et va un peu plus en profondeur. Cette est un bon premier cycle ou texte diplômé introduction de niveau supérieur, et sera dans le théorème linéaire speedup, une grande raison pour laquelle les informaticiens utilisent la notation grand-O du tout lors de la discussion algorithme runtimes. En un mot, il dit que vous pouvez toujours obtenir un facteur linéaire dans l'amélioration de la vitesse en lançant une quantité exponentielle d'argent au matériel.
La grâce de la notation Big-O est qu'il nous permet de rejeter le « changement lâche » au large des extrémités de nos formules de coûts. Cela se justifie par l'hypothèse implicite que nous nous soucions seulement le cas limite où la taille de notre entrée va à l'infini, et les plus étendues, nos coûts dominent les autres.
Effectuer une analyse de la complexité vous devez d'abord choisir une mesure pour votre entrée, puis décidez quelle ressource dont la consommation que vous souhaitez mesurer, puis de compter la quantité prise par l'algorithme lorsqu'il est exécuté sur l'entrée d'une taille donnée. Par convention, la taille d'entrée est nommée N
. ressources typiques sont nombre de « étapes » exécutées ou les éléments stockés dans tous les conteneurs, mais ce ne sont que des exemples (populaires). Pour le contraste, les algorithmes de tri par comparaison se concentrent souvent exclusivement sur le nombre de swaps effectués.
La taille de l'entrée est généralement pas le seul fait déterminant dans combien de temps l'algorithme prend pour exécuter ou la quantité d'espace dont il a besoin. Par exemple, le temps d'exécution de type d'insertion est radicalement différente entre les entrées de longueur égale présentées dans l'ordre déjà triés et inverse triés. Voilà pourquoi on parle de Le pire cas par rapport à Moyen-cas complexité (ou le meilleur des cas, etc.) En demandant par exemple « Quelle est la pire chose qui pourrait arriver ? », nous pouvons décider de l'étape par la source et l'utilisation nombre.
complexité moyenne-cas sont difficiles, car ils exigent la connaissance de la distribution des entrées possibles. complexité pire cas sont des distributions indépendantes des entrées et nous fournissent des limites supérieures dures, ce qui en pratique sont souvent tous nous avons besoin.
Par exemple, si un algorithme tel que Bubble Sort prend un tableau d'éléments en entrée , une mesure typique est la longueur du tableau. Supposons que nous voulons compter le nombre de swaps qu'il fait dans le pire des cas. Voici le code de pseudo pour elle, tirée de Wikipedia:
procedure bubbleSort( A : list of sortable items )
repeat
swapped = false
for i = 1 to length(A) - 1 inclusive do:
if A[i-1] > A[i] then
swap( A[i-1], A[i] )
swapped = true
end if
end for
until not swapped
end procedure
Notez qu'il est essentiellement deux boucles de for
, une une intérieure emboîtée dans l'autre. Les chiffres de boucle interne de 1
à length(A) - 1
, et rend les échanges de N - 1
maximales exactement quand le plus grand élément de la matrice est à l'avant. La boucle externe répète ce processus aussi longtemps que toute permutation a eu lieu la dernière passe. En supposant un précédent passage le plus défavorable, l'élément non triés précédemment le plus grand sera en place à la fin de la liste, diminue efficacement la distance nous pouvons passer le prochain plus grand élément non triés par un. Ainsi, chaque passage un fait moins swap, et nous nous retrouvons avec
N + (N-1) + (N-2) + ... + 2 + 1 = N * (N + 1) / 2 = 1/2 * N^2 + N/2
Dans la notation Big-O cela devient
O(1/2 * N^2 + N/2) = O(1/2 * N^2) = O(N^2)
Ici, on laisse tomber le terme linéaire (N/2
) puisqu'il sera dominé par une quadratique N -> inf
. Ensuite, on laisse tomber le 1/2
principal facteur constant car il est essentiellement un détail de matériel. Notez que c'est une motivation humaine: l'intelligence de grand-O » est sa définition fournit un cadre rigoureuxpour le logement de nos motivations. Avère ce cadre dit que nous laissons tomber les principaux facteurs constants.
L'élaboration d'une preuve rigoureuse de la complexité est une compétence en soi, et sachant définitions seul ne vous aidera pas beaucoup avec elle. noreferrer"> preuve par induction pré-conditions et post-conditions autour de chaque passage d'une boucle. Avis dans mon argumentation informelle je prends en compte l'itération précédente lorsque raisonnant sur l'actuel: ceci est la pensée inductive. « Mathématiques discrètes », « preuve par induction », « combinatoires » et « comptage » sont tous les bons mots-clés à rechercher. (Oui, "comptage" lui-même est une branche des mathématiques et il est dur ).
Une fois que vous avez prouvé une formule, « réduction » en grand-O est une compétence différente et nécessite essentiellement de savoir un peu calcul (limites.) Finalement, vous serez en mesure de tailler les branches loin ennuyeux dans vos preuves en établissant que les termes qu'ils instaurent seront dominées par une autre, on connu.