La raison de l'utilisation de la touche de diminution plutôt que de la réinsertion de nœuds est de maintenir le nombre de nœuds dans la file d'attente prioritaire faible, ce qui réduit le nombre total de files d'attente prioritaires et le coût de chaque solde de file d'attente prioritaire faible.
Dans une implémentation de l'algorithme de Dijkstra qui réinsère les nœuds dans la file d'attente prioritaire avec leurs nouvelles priorités, un nœud est ajouté à la file d'attente prioritaire pour chacun des m arêtes du graphique. Cela signifie qu'il y a m opérations de mise en file d'attente et m opérations de mise en file d'attente sur la file d'attente prioritaire, ce qui donne un temps d'exécution total de O (m T e + m T d ), où T e est le temps nécessaire pour mettre en file d'attente la file d'attente prioritaire et T d est le temps nécessaire pour se retirer de la file d'attente prioritaire.
Dans une implémentation de l'algorithme de Dijkstra qui prend en charge la clé de décroissance, la file d'attente prioritaire contenant les nœuds commence par n nœuds et à chaque étape de l'algorithme supprime un nœud. Cela signifie que le nombre total de files d'attente du tas est n. Chaque nœud aura une touche de diminution appelée potentiellement une fois pour chaque arête qui y mène, de sorte que le nombre total de touches de diminution effectuées est d'au plus m. Cela donne un temps d'exécution de (n T e + n T d + m T k ), où T k est le temps nécessaire pour appeler la touche de diminution.
Alors, quel effet cela a-t-il sur l'exécution? Cela dépend de la file d'attente prioritaire que vous utilisez. Voici un tableau rapide qui montre les différentes files d'attente de priorité et les temps d'exécution globaux des différentes implémentations d'algorithme de Dijkstra:
Queue | T_e | T_d | T_k | w/o Dec-Key | w/Dec-Key
---------------+--------+--------+--------+-------------+---------------
Binary Heap |O(log N)|O(log N)|O(log N)| O(M log N) | O(M log N)
Binomial Heap |O(log N)|O(log N)|O(log N)| O(M log N) | O(M log N)
Fibonacci Heap | O(1) |O(log N)| O(1) | O(M log N) | O(M + N log N)
Comme vous pouvez le voir, avec la plupart des types de files d'attente prioritaires, il n'y a vraiment pas de différence dans l'exécution asymptotique, et la version à clé réduite ne fera probablement pas beaucoup mieux. Cependant, si vous utilisez une implémentation de tas de Fibonacci de la file d'attente prioritaire, alors en effet l'algorithme de Dijkstra sera asymptotiquement plus efficace lors de l'utilisation de la touche de diminution.
En bref, l'utilisation de la touche de diminution, plus une bonne file d'attente prioritaire, peut faire tomber le runtime asymptotique de Dijkstra au-delà de ce qui est possible si vous continuez à faire des files d'attente et des retraits.
Outre ce point, certains algorithmes plus avancés, tels que l'algorithme des chemins les plus courts de Gabow, utilisent l'algorithme de Dijkstra comme sous-programme et s'appuient fortement sur l'implémentation de la clé décroissante. Ils utilisent le fait que si vous connaissez à l'avance la plage de distances valides, vous pouvez créer une file d'attente prioritaire super efficace sur cette base.
J'espère que cela t'aides!