Der Grund für die Verwendung des Verkleinerungsschlüssels anstelle des erneuten Einfügens von Knoten besteht darin, die Anzahl der Knoten in der Prioritätswarteschlange klein zu halten, wodurch die Gesamtzahl der Warteschlangen der Prioritätswarteschlange klein und die Kosten für jeden Prioritätswarteschlangensaldo niedrig gehalten werden.
In einer Implementierung des Dijkstra-Algorithmus, der Knoten mit ihren neuen Prioritäten wieder in die Prioritätswarteschlange einfügt, wird der Prioritätswarteschlange für jede der m Kanten im Diagramm ein Knoten hinzugefügt. Dies bedeutet, dass sich in der Prioritätswarteschlange M Enqueue-Operationen und M Dequeue-Operationen befinden, was eine Gesamtlaufzeit von O (m T e + m T d ) ergibt , wobei T e die Zeit ist, die zum Einreihen in die Prioritätswarteschlange erforderlich ist, und T d ist Die Zeit, die erforderlich ist, um die Warteschlange aus der Prioritätswarteschlange zu entfernen.
In einer Implementierung des Dijkstra-Algorithmus, der den Verkleinerungsschlüssel unterstützt, beginnt die Prioritätswarteschlange, die die Knoten enthält, mit n Knoten darin und entfernt bei jedem Schritt des Algorithmus einen Knoten. Dies bedeutet, dass die Gesamtzahl der Heap-Warteschlangen n beträgt. Auf jedem Knoten wird möglicherweise einmal für jede Kante, die in ihn führt, ein Verkleinerungsschlüssel aufgerufen, sodass die Gesamtzahl der durchgeführten Verkleinerungsschlüssel höchstens m beträgt. Daraus ergibt sich eine Laufzeit von (n T e + n T d + T m k ), wobei T k die Zeit , um Anruf Abnahme-Schlüssel erforderlich ist.
Wie wirkt sich das auf die Laufzeit aus? Das hängt davon ab, welche Prioritätswarteschlange Sie verwenden. Hier ist eine kurze Tabelle, die verschiedene Prioritätswarteschlangen und die Gesamtlaufzeiten der verschiedenen Dijkstra-Algorithmusimplementierungen zeigt:
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)
Wie Sie sehen können, gibt es bei den meisten Arten von Prioritätswarteschlangen keinen Unterschied in der asymptotischen Laufzeit, und die Version mit abnehmendem Schlüssel wird wahrscheinlich nicht viel besser abschneiden. Wenn Sie jedoch eine Fibonacci-Heap- Implementierung der Prioritätswarteschlange verwenden, ist der Dijkstra-Algorithmus bei Verwendung des Abnahmeschlüssels tatsächlich asymptotisch effizienter.
Kurz gesagt, die Verwendung der Abnahmetaste und einer Warteschlange mit guter Priorität kann die asymptotische Laufzeit von Dijkstra über das Mögliche hinaus verringern, wenn Sie weiterhin Warteschlangen und Warteschlangen ausführen.
Abgesehen von diesem Punkt verwenden einige fortgeschrittenere Algorithmen, wie beispielsweise Gabows Shortest Paths-Algorithmus, den Dijkstra-Algorithmus als Unterprogramm und stützen sich stark auf die Implementierung des Abnahmeschlüssels. Sie nutzen die Tatsache, dass Sie, wenn Sie den Bereich der gültigen Entfernungen im Voraus kennen, basierend auf dieser Tatsache eine supereffiziente Prioritätswarteschlange erstellen können.
Hoffe das hilft!