Angenommen, ich habe einen gerichteten Graphen mit Kantengewichten aus dem Bereich in dem K konstant ist. Wie kann ich den Algorithmus / die Datenstruktur ändern und die zeitliche Komplexität auf O ( | V | + | E | ) verbessern, wenn ich versuche, den kürzesten Weg mithilfe des Dijkstra-Algorithmus zu finden ?
algorithms
data-structures
shortest-path
weighted-graphs
user1675999
quelle
quelle
Antworten:
Wenn Kantengewichte Ganzzahlen in , können Sie Dijkstra so implementieren, dass sie in O ( K | V | + | E | ) Zeit ausgeführt werden, gemäß dem Vorschlag von @ rrenaud. Hier ist eine explizitere Erklärung.{ 0 , 1 , … , K.}} O ( K.| V.| + | E.| )
Zu jedem Zeitpunkt befinden sich die (endlichen) Schlüssel in der Prioritätswarteschlange in einem Bereich , wobei D der Wert des letzten aus der Prioritätswarteschlange entfernten Schlüssels ist. (Jeder Schlüssel ist mindestens D , da die durch den Dijkstra-Algorithmus entfernte Tastenfolge nicht abnimmt und jeder Schlüssel höchstens D + K ist , da jeder Schlüssel den Wert d [ u ] + w t ( u , w ) für hat eine Kante ( u ,{ D , D + 1 , … , D + K.}} D. D. D + K. d[ u ] + w t ( u , w ) wobei d [ u ] der Abstand von der Quelle zu einembereits entferntenScheitelpunkt u ist, also d [ u ] ≤ D. )( u , w ) d[ u ] u d[u]≤D
Aus diesem Grund können Sie die Prioritätswarteschlange mit einem kreisförmigen Array der Größe K + 1 implementieren , wobei jede Zelle einen Bucket enthält. Speichern Sie jeden Scheitelpunkt mit dem Schlüssel k im Bucket in Zelle A [ h ( k ) ], wobei h ( k ) = k mod ( K + 1 ) . Behalten Sie den Überblick von D . Führen Sie die folgenden Schritte aus:A[0..K] K+1 k A[h(k)] h(k)=kmod(K+1) D
delete-min : Während ist leer, Inkrement D . Löschen Sie dann einen Scheitelpunkt aus A [ h ( D ) ] und geben Sie ihn zurück .A[h(D)] D A[h(D)]
Einfügen mit Schlüssel : Fügen Sie den Scheitelpunkt zum Eimer von A [ h ( k ) ] hinzu .k A[h(k)]
Verkleinerungsschlüssel auf k ' : Verschieben Sie den Scheitelpunkt von A [ h ( k ) ] nach A [ h ( k ' ) ] .k k′ A[h(k)] A[h(k′)]
Einfügen und Verringern sind Operationen mit konstanter Zeit, daher beträgt die Gesamtzeit, die für diese Operationen aufgewendet wird, . Die Gesamtzeit im Lösch-min wird O ( | V | ) und der Endwert D . Der Endwert von D ist der maximale (endliche) Abstand von der Quelle zu einem beliebigen Scheitelpunkt (weil eine Löschmin, die i Iterationen benötigt, D um i erhöht ). Der maximale Abstand beträgt höchstens K ( | V | - 1O(|V|+|E|) O(|V|) D D i D i weil jeder Pfad höchstens | hat V | - 1 Kanten. Somit beträgt die Gesamtzeit, die der Algorithmus benötigt, O ( K | V | + | E | ) .K(|V|−1) |V|−1 O(K|V|+|E|)
quelle
Ich gehe hier davon aus, dass eine ganze Zahl ist und die Kantengewichte ganzzahlig sind. Andernfalls kauft es Ihnen nicht wirklich etwas. Sie können Gewichte immer neu skalieren, sodass die minimale Kante 1 und die maximale Kante K gekostet hat. Das Problem ist also identisch mit dem Standardproblem des kürzesten Pfades.K 1 K
quelle
Sie können die topologische Sortierung verwenden, um die Lösung zu finden. Lassen Sie die Quelle den Grad 0 haben. Gehen Sie dann von jeder Kante zur Quelle. Wenn ein anderer Scheitelpunkt den Grad 0 hat, stellen Sie ihn in die Warteschlange und fahren Sie damit fort. In diesem Fall (ohne Zyklus innerhalb des Graphen) kann V + E erreicht werden, da es jeden Scheitelpunkt und jede Kante einmal und nur einmal durchlaufen würde.
quelle