Universität Konstanz Mathematisch-naturwissenschaftliche Sektion Fachbereich Mathematik und Statistik Wintersemester 2001/02 Mikkel Thorup: Undirected Single-Source Shortest Paths with Positive Integer Weights in Linear Time Seminar: Leiterin: Betreuung: Effiziente Algorithmen Prof. Dr. Dorothea Wagner Frank Schulz Referentin: Annemarie Kastelsky Anschrift: e-mail: Markgrafenstraße 53 78467 Konstanz [email protected] Fächer: Fachsemester: Französisch, Mathematik 8 1 Einleitung Das Single-Source Shortest Paths Problem (SSSP-Problem) ist eine klassische Problemstellung. Gegeben ist ein Graph mit ganzzahligen positiven Kantengewichten und einem ausgezeichneten Knoten s. Gesucht werden kürzeste Wege von s zu allen anderen Knoten im Graphen. Im Folgenden ist dieser Graph zusätzlich ungerichtet. Diese Problemstellung wurde durch den Algorithmus von Dijkstra (1959) gelöst. Dieser war Grundlage für die weitere Entwicklung von Algorithmen zu diesem Problem. Da einige Elemente dieses Algorithmus auch in den Linearzeitalgorithmus von Thorup eingehen, wird zunächst der Algorithmus von Dijkstra kurz vorgestellt. Anschließend werden zwei Etappen auf dem Weg zu Thorups Linearzeitalgorithmus nachgezeichnet, die die andere Vorgehensweise seines Algorithmus zeigen. Der erste Schritt ist die Entwicklung des Algorithmus A, der das SSSPProblem löst, wenn sich der Graph so in Teilmengen aufteilen lässt, dass alle Kanten zwischen den Teilmengen mindestens Gewicht 2α haben. Im zweiten Schritt wird diese Einschränkung durch die Einführung einer Komponentenhierarchie wieder verallgemeinert. Diese führt zu den Algorithmen B und C, in denen minimale Komponenten besucht werden. Schließlich wird kurz aufgezeigt, wie dieser Algorithmus effizienter gestaltet werden kann, so dass man eine lineare Laufzeit erhält. Abschließend werden die Ergebnisse von Thorup vorgestellt. 1 2 2.1 Grundlagen und der Algorithmus von Dijkstra Grundlagen Definitionen Sei G = (V, E), |V | = n, |E| = m ein zusammenhängender ungerichteter Graph mit einer Kantengewichtsfunktion ` : E → N und einem ausgezeichneten Knoten s ∈ V . Falls (v, w) 6∈ E setzt man `(v, w) := ∞. d(v) ist die Distanz (= kürzester Weg) von s nach v. D(v) ist eine Weglänge von s nach v, also gilt immer D(v) ≥ d(v). S Teilmenge, S ⊆ V , so dass ∀v ∈ S : D(v) = d(v) ∀v 6∈ S : D(v) = minu∈S {d(u) + `(u, v)} Knoten besuchen Man kann einen Knoten v 6∈ S nur besuchen, wenn D(v) = d(v) gilt. v wird zur Menge S dazugenommen und für die Nachbarknoten w von v wird D(w) neu bestimmt: Für alle (v, w) ∈ E, w 6∈ S : D(w) = min{D(w), D(v) + `(v, w)} Folgerung Um Knoten besuchen zu können, ist es also nötig zu wissen, für welche v D(v) = d(v) gilt. Lemma 1 Wenn für ein v ∈ V \ S D(v) minimal ist, dann gilt D(v) = d(v). Beweis: Sei u der erste Knoten außerhalb von S auf einem kürzesten Weg von s nach v. Dann gilt D(u) = d(u) nach Definition von S. D(v) ≥ d(v) ≥ d(u) = D(u) ≥ D(v), da D(v) nach Voraussetzung minimal ist. Also gilt D(v) = d(v). Lemma 2 min D(V \ S) = min d(V \ S) ist nicht fallend. 2 Beweis: Zeigen zunächst die Gleichheit: Falls S = V gilt min D(V \ S) = min d(V \ S) = min ∅ = ∞. (min ∅ = ∞ nach Definition.) Andernfalls existiert ein v ∈ V \ S mit d(v) minimal. Sei u der erste Knoten außerhalb von S auf einem kürzesten Weg von s nach v. Dann ist D(u) = d(u) ≤ d(v) (Lemma 1). Da für v d(v) minimal ist, gilt d(u) = d(v). Also folgt: min D(V \ S) ≤ D(u) = d(u) = d(v) = min d(V \ S). Andererseits ist für alle w ∈ V D(w) ≥ d(w) und somit min D(V \ S) ≥ min d(V \ S). Daraus folgt: min D(V \ S) = min d(V \ S). Zeigen nun: min d(V \ S) ist nicht fallend: d(w) ändert sich nicht für alle w ∈ V . S wird größer, also sucht man das minimale d(w) in einer immer kleineren Menge S \ V mit konstanten dWerten. min d(V \ S) kann also höchstens größer werden. 2.2 Algorithmus von Dijkstra Der Algorithmus von Dijkstra beruht auf Lemma 1 und Lemma 2. Algorithmus von Dijkstra 0:v=s D1 Setze D(v) := ∞ : sonst s:v=s D2 Setze V or(v) := nil : sonst D3 S := ∅ D4 Solange V \ S 6= ∅ D 4.1 Finde u ∈ V \ S mit D(u) minimal D 4.2 Setze S := S ∪ {u} D 4.3 Für alle v ∈ {w ∈ V |w ∈ V \ S und (u, w) ∈ E} führe aus: D 4.3.1 Falls D(u) + `(u, v) < D(v) D 4.3.1.1 Setze D(v) := D(u) + `(u, v) D 4.3.1.2 Setze V or(v) := u 3 a Beispiel: 5 3 s 12 b @ @ 1@ @ 15 @ e Beginn: 1. Durchlauf (Schleife) 2. Durchlauf 3. Durchlauf 4. Durchlauf 5. Durchlauf 6. Duchlauf 7. Durchlauf @ @ 8 11 @ @ @ 2 c d 1 f S=∅ D(s) = 0, für alle v 6= s : D(v) = ∞ S = {s} D(b) = 3, D(e) = 1 S = {s, e} D(b) = 3, D(f ) = 16 S = {s, e, b} D(a) = 8, D(c) = 15, D(f ) = 16 S = {s, e, b, a} D(c) = 15, D(d) = 16, D(f ) = 16 S = {s, e, b, a, c} D(d) = 16, D(f ) = 16 S = {s, e, b, a, c, d} D(f ) = 16 S = {s, e, b, a, c, d, f } Wie leicht ersichtlich ist, müssen für diesen Algorithmus die Knoten nach D(v) sortiert werden. Das bedeutet, um den Algorithmus von Dijkstra in Linearzeit implementieren zu können, ist es nötig, in Linearzeit sortieren zu können (Fredman und Tarjan 1987). Andererseits setzt Sortieren in Linearzeit voraus, dass der Algorithmus von Dijkstra in Linearzeit implementiert werden kann (Thorup 1996). Folgerung Da es nicht möglich ist, die Knoten in Linearzeit nach D(v) zu sortieren, ist es also zur Entwicklung eines Linearzeitalgorithmus für das SSSP-Problem nötig, sich von Dijkstras Algorithmus zu lösen und andere Techniken zu verwenden. Wir suchen daher eine andere Bedingung, so dass zwar gilt D(v) = d(v), aber eventuell D(v) ≥ min D(V \ S). 4 3 3.1 Entwicklung des Algorithmus A Die andere Bedingung Lemma 3 Sei die Knotenmenge von V in disjunkte Teilmengen V1 , . . . , Vk aufteilbar, so dass alle Kanten zwischen den Teilmengen mindestens Gewicht δ haben. Für ein i und v ∈ Vi \ S gelte D(v) = min D(Vi \ S) ≤ min D(V \ S) + δ. Dann gilt D(v) = d(v). Beispiel: a 5 3 s b 12 @ @ @ @ 1 @ @ @ @ 15 e @ @ @ @ @ 8 11 @ @ @ c 2 d 1 f V lässt sich in zwei Teilmengen V1 = {s, a, b, e} und V2 = {c, d, f } aufteilen. Alle Kanten zwischen den Teilmengen V1 und V2 haben ein Gewicht ≤ δ = 8. Sei nun S = {s, b, e} wie nach dem zweiten Durchlaufen der Schleife des Algorithmus von Dijkstra. Dann gilt die zweite Bedingung des Lemma 3 für i = 2 und v = c: Für c ∈ V2 \S = {c, d, f } gilt: D(c) = 15 = min D(V2 \S), da D(f ) = D(c) = ∞ und 15 ≤ min D(V \ S) + 8, denn V \ S = {a, c} mit D(a) = 8 und D(c) = 15. Beweis: Sei u der erste Knoten außerhalb von S auf einem kürzesten Weg von s nach v. Dann ist D(u) = d(u). Falls u ∈ Vi , folgt wie bei Lemma 1: D(v) ≥ d(v) ≥ d(u) = D(u) ≥ D(v), also D(v) = d(v). Sei u 6∈ Vi . Dann haben alle Kanten zwischen V \ Vi (3 u) und Vi (3 w) Gewicht δ. Also folgt: D(v) ≥ d(v) ≥ d(u) + δ = D(u) + δ. Vor Vor Andererseits gilt: D(u) + δ ≥ min D(V \ S) + δ = min D(Vi \ S) = D(v). Daraus folgt D(v) = d(v). 5 3.2 Technische Voraussetzungen Um dieses Ergebnis in einen Algorithmus umsetzen zu können, müssen zwei technische Voraussetzungen erfüllt werden. Eine Voraussetzung für den Algorithmus A und den späteren Linearzeitalgorithmus ist das RAM-Modell, die andere Vorausetzung die Verwendung von Buckets. RAM-Modell Bei diesem Modell ist der Speicher in adressierbare Wörter der Länge ω eingeteilt. So werden alle Gewichte und Weglängen als Binärzahlen der Länge ≤ ω gespeichert. Innerhalb des RAM-Modells wird es manchmal vorgezogen, sich auf so genannte AC 0 -Operationen zu beschränken. Diese beinhalten die Addition, die shift“-Operation aber keine Multiplikation. ” Die shift“-Operation ” Die shift“-Operation wird als x i notiert, was für 2xi steht. ” Beispiel: x=6 in Binärzahlen: 110 6 1 = 261 = 3 11 6 6 2 = 22 = 1 1 Betrachtet man statt der Dezimalzahlen die Binärzahlen, so sieht man, dass bei einer Zahl x durch die shift“-Operation gerade die i letzten Stellen ge” ” strichen“ werden. Buckets Ein Bucket B ist eine Menge, in die beliebige Elemente in konstanter Zeit eingefügt werden können und aus der ein beliebiges Element in konstanter Zeit wieder entfernt werden kann. Solche Buckets können zum Beispiel als doppeltverkettete Liste implementiert werden. Das RAM-Modell ermöglicht durch die Adressierbarkeit der Wörter die Erstellung eines Arrays mit ` Buckets B(1) bis B(`), so dass in konstanter Zeit Elemente in B(i) eingefügt oder aus B(i) entfernt werden können. Mit diesen Voraussetzungen lässt sich nun ein Algorithmus formulieren, der auf Graphen angewandt werden kann, die die Bedingung aus Lemma 3 erfüllen. Dazu wählt man δ := 2α . Die Indizes der Teilmengen i ∈ {1, . . . , k} werden so in Buckets einsortiert, dass i ∈ B(Vi \ S) α. 6 Anzahl der benötigten Buckets D(v) ≤ ∞ P heißt, es gibt einen Weg von s nach v mit Länge D(v). Es gilt: D(v) ≤ e∈E `(e). DerPmaximale Index ≤ ∞ eines nichtleeren Buckets ist begrenzt durch ∆ = e∈E `(e) α. Die benötigten Bucketindizes sind folglich 0, 1, . . . , ∆, ∞. Insgesamt benötigt man also ∆ + 2 Buckets. 3.3 Algorithmus A Algorithmus A löst das SSSP-Problem, wenn V in Teilmengen V1 , . . . , Vk aufgeteilt ist, wobei alle Kanten zwischen den Teilmengen mindestens Gewicht 2α haben. S := {s} D(s) := 0 für alle v 6= s : D(v) := `(s, v) A2 für ix := 0, 1, . . . , ∆, ∞: B(ix) := ∅ A3 für i := 1, . . . , k: füge i in B(min D(Vi \ S) α) ein A4 für ix := 0 bis ∆ A 4.1 solange B(ix) 6= ∅ A 4.1.1 nimm i ∈ B(ix) A 4.1.2 nimm v ∈ Vi \ S mit D(v) minimal A 4.1.3 für alle (v, w) ∈ E, w ∈ /S A 4.1.3.1 sei j so, dass w ∈ Vj A 4.1.3.2 D(w) := min{D(w), D(v) + `(v, w)} falls min D(Vj \ S) α verringert wird, verschiebe j nach B(min D(Vj \ S) α) A 4.1.4 S := S ∪ {v} falls min D(Vi \ S) α vergrößert wird, verschiebe i nach B(min D(V \ S) α) A1 7 a Beispiel: 5 s 3 12 b @ @ @ @ 1 @ @ @ @ 15 e @ @ @ @ @ 8 11 @ @ @ c 2 d 1 f α = 3, V1 = {s, a, b, e}, V2 = {c, d, f } A 1 S = {s}, D(s) = 0, D(b) = 3, D(e) = 1, für alle anderen v: D(v) = ∞ A 2 ∆ = 58 3 = 7 A 3 (Der Übersicht halber steht nun V1 statt i = 1 bzw. V2 statt i = 2:) V1 ∈ B(0), V2 ∈ B(∞) 1. Durchlauf 2. Durchlauf 3. Durchlauf 4. Durchlauf 5. Durchlauf 6. Durchlauf B(0) nimm V1 , nimm e, da D(e) = 1 minimal in V1 D(f ) = 16, also V2 ∈ B(2) S = {s, e} B(0) nimm V1 , nimm b, da D(b) = 3 minimal in V1 D(c) = 15, also V2 ∈ B(1) D(a) = 8 S = {s, e, b} und V1 ∈ B(1) B(1) nimm V2 , nimm c, da D(c) = 15 minimal in V2 D(d) = 17 S = {s, e, b, c} und V2 ∈ B(2) B(1) nimm V1 , nimm a, da D(a) = 8 minimal in V1 D(d) = 16 S = {s, e, b, c, a} und V1 ∈ B(∞) B(2) nimm V2 , nimm f , da D(f ) = 16 minimal in V2 S = {s, e, b, c, a, f } B(2) nimm V2 , nimm d, da D(d) = 16 minimal in V2 S = {s, e, b, c, a, f, d} und V2 ∈ B(∞) 8 Korrektheit Die Korrektheit des Algorithmus A beruht auf dem Einsortieren der i in entsprechende Buckets und folgt aus Lemma 3. min D(Vi \ S) min D(V \ S) ≤ ⇐⇒ min D(Vi \S) ≤ min D(V \S)+2α 2α 2α min D(Vi \ S) α ≤ min D(V \ S) α ⇐⇒ min D(Vi \ S) ≤ D(V \ S) + δ Es gilt: min D(V \ S) α = mini (min D(Vi \ S) α). Wenn i also im nichtleeren Bucket mit dem kleinsten Index ist, gilt: min D(Vi \ S) α = min D(V \ S) α. Sei nun ix der kleinste Index eines nichtleeren Buckets. Falls i ∈ B(ix) und für v ∈ Vi \ S D(v) minimal ist, gilt: Lemma 3 D(v) = min D(Vi \ S) ≤ min D(V \ S) + δ =⇒ D(v) = d(v) Laufzeit Die Laufzeit des Algorithmus A ist in O(m + ∆)+ Kosten für das Behalten von min D(Vi \ S) für jedes i. Diese Laufzeit kann verringert werden, indem man min D(Vi \ S) rekursiv behält und indem man die Anzahl der Buckets verringert. Für letzteres genügt es, α groß zu wählen. Folgerung Wir suchen nun eine rekursive Bedingung, um D(v) = d(v) schließen zu können. 9 4 4.1 Entwicklung eines rekursiven Algorithmus Komponentenhierarchie Definition Gi ist ein Subgraph von G, dessen Kantenmenge die Kanten von G sind mit `(e) ≤ 2i . G0 besteht aus einzelnen Knoten. ω ist die Wortlänge, das heißt, alle Kantengewichte und Weglängen sind ≤ 2ω , also Gω = G. Auf dem i-ten Level sind die Komponenten von Gi . Die Komponente auf dem i-ten Level, die v enthält, wird mit [v]i bezeichnet. Diese Komponentenhierarchie lässt sich auch als Baum darstellen. In dieser Darstellung sind die Blätter die Komponenten, die nur aus einem Knoten bestehen. Die Wurzel ist der Knoten [v]r = G mit minimalem r. Beispiel: a [s]4 @ @ 8 5 11 @ @ @ 12 @ 3 s @ b @ @ @ @ @@ @ @ @ @ @ @ @ 1@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ 15 @ @ @ e @ @ @ @ @ @ c 2 PPP P [s]3 QQ [s]2 d [s]1 1 @ @ [b]1 [a]2 [a]1 [s]0 [c]2 [c]1 @ @ [d]1 JJ JJ f [c]3 [e]0 [b]0 [a]0 [c]0 [f ]0 [d]0 Lemma 4 Falls [v]i 6= [w]i dann ist dist(v, w) ≥ 2i . Beweis: Da [v]i 6= [w]i enthält jeder Weg von v nach w eine Kante mit Gewicht ≥ 2i . Definition [w]i−1 mit [w]i = [v]i heißt Kind von [v]i , das heißt w ∈ [v]i Beispiel: In der Darstellung als Baum sind Kinder gerade die direkten Nachfolger eines Knotens. Notation [v]− i := [v]i \ S, [v]− i muss dabei nicht zusammenhängend sein. 10 Definition − [v]i heißt min-child von [v]i+1 , falls min(D([v]− i )) i = min(D([v]i+1 )) i Beispiel: Sei S = {s, e, b}: [s]3 ist min-child von [s]4 : D(a) = 8 min(D([s]− 3 )) 3 = 1 min(D([s]− 4 )) 3 = 1 [c]3 ist min-child von [s]4 : D(c) = 15 min(D([c]− 3 )) 3 = 1 min(D([s]− 4 )) 3 = 1 [c]1 ist min-child von [c]2 : D(c) = 15 min(D([c]− 1 )) 1 = 7 min(D([c]− 2 )) 1 = 7 [d]1 ist nicht min-child von [c]2 : D(d) = 16 min(D([d− 1 )) 1 = 8 − min(D([c2 )) 1 = 7 Definition [v]i heißt minimal, falls [v]− i 6= ∅ und für m = i, . . . , r − 1 gilt: [v]i ist min-child von [v]i+1 . Die Bedingung [v]− i 6= ∅ ist wichtig für den Fall V = S. Falls V = S, ergibt − sich min(D([v]i )) = min ∅ = ∞ für alle [v]i . Dann sind alle [v]i minimal. Durch die Bedingung [v]− i 6= ∅ ist im Fall V = S kein [v]i minimal. Beispiel: Sei S = {s, e, b}: a ist minimal und c ist minimal. Lemma 5 − Falls v 6∈ S und [v]i minimal ist, gilt min(D([v]− i )) = min(d([v]i )). Insbesondere falls [v]0 = {v} minimal ist, gilt D(v) = d(v). 4.2 Algorithmus B und Algorithmus C Damit ergibt sich ein rekursives Vorgehen, um eine minimale Komponente zu besuchen: Für Kinder [v]i−1 von [v]i wird überprüft, ob min(D([w]− i−1 )) i − 1 = − min(D([v]i )) i − 1 = ix([v]i ), wobei ix([v]i ) ein Index ist. Dies geschieht so lange bis ein [v]0 = {v} gefunden ist, das minimal ist. Dann kann man dieses v besuchen. 11 Algorithmus B Eingabe: Graph G = (V, E) mit einer Kantengewichtsfunktion ` und einem ausgezeichneten Knoten s. Ausgabe: D mit D(v) = d(v) = dist(s, v) für alle v ∈ V . B1 B2 B3 B4 S := {s} D(s) := 0 für alle v 6= s: D(v) := `(s, v) Visit ([s]ω ) Gib D aus Algorithmus C Der Algorithmus Visit ([v]i ) setzt voraus, dass [v]i minimal ist. Visit ([v]i ) C C C C 1 2 3 3.1 falls i = 0, besuche v und gehe zurück falls v noch nie besucht wurde: ix([v]i ) := min D([v]− i ) i−1 wiederhole bis [v]− = ∅ oder bis ix([v] ) i erhöht wird: i i solange es ein Kind [w]i−1 von [v]i gibt, so dass min D([w]− i−1 ) i − 1 = ix([v]i ) C 3.1.1 sei [w]i−1 ein Kind von [v]i mit min D([w]− i−1 ) i − 1 = ix([v]i ) C 3.1.2 Visit ([w]i−1 ) C 3.2 erhöhe ix([v]i ) um 1 Beispiel: a [s]4 @ @ 8 5 11 @ @ @ 12 @ 3 s @ b @ @ @ @ @@ @ @ @ @ @ @ @ @ @ @ @ @ @1 @ @ @ @ @ @ @ @ @ @ @ 15 @@ e @ @ @ @ @ @ @ c 2 PPP P [s]3 QQ [s]2 d [s]1 1 @ @ [b]1 [a]2 [a]1 JJ [s]0 f 12 [c]3 [c]2 [c]1 @ @ [d]1 JJ [e]0 [b]0 [a]0 [c]0 [f ]0 [d]0 S = {s} D(e) = 1 D(b) = 3 S = {s, e} D(b) = 3 D(f ) = 16 S = {s, e, b} D(a) = 8 D(c) = 15 Visit ([s]4 ) ix([s]4 ) = 0 Kind [s]3 : min D([s]− 3 ) 3 = 0 = ix([s]4 ) Visit ([s]3 ) ix([s]3 ) = 0 Kind[s]2 : min D([s]− 2 ) 2 = 0 = ix([s]3 ) Visit ([s]2 ) ix([s]2 ) = 0 Kind [b]1 : min D([b]− 1 ) 1 = 1 6= ix([s]2 ) Kind [s]1 : min D([s]− 1 ) 1 = 0 = ix([s]2 ) Visit ([s]1 ) ix([s]1 ) = 1 6 ix([s]1 ) Kind [s]0 : min D([s]− 0) 0 = ∞ = − Kind [e]0 : min D([e]0 ) 0 = 1 = ix([s]1 ) Visit ([e]0 ) ix([s]1 ) = 2 ix([s]2 ) = 1 Kind [s]2 : min D([s]− 2 ) 2 = 0 = ix([s]3 ) Visit([s]2 ) Kind [b]1 : min D([b]− 1 ) 1 = 2 = ix([s]2 ) Visit([b]1 ) ix([b]1 ) = 2 Kind [b]0 : min D([b]− 0 ) 0 = 2 = ix([b]1 ) Visit ([b]0 ) ix([b]1 ) = 3 ix([s]2 ) = 2 Kind [a]2 : min D([a]− 2 ) 2 = 1 6= ix([s]3 ) ix([s]3 ) = 1 Kind [c]3 : min D([c]− 3 ) 3 = 1 = ix([s]3 ) Visit ([c]3 ) .. . 13 5 Ausblick auf die Entwicklung des Linearzeitalgorithmus Um eine lineare Laufzeit zu erhalten ist es nun nötig, die Komponentenhierarchie zu verfeinern. Dies geschieht, indem man einen so genannten Komponentenbaum konstruiert. Dieser entspricht im Wesentlichen der schon vorgestellten Baumdarstellung der Komponentenhierarchie, allerdings fehlen die Knoten [v]i mit [v]i = [v]i+1 . Es gibt im Komponentenbaum also keine Knoten mit nur einem Nachfolger, daher ist die Anzahl der Knoten ≤ 2n − 1. Wenn man von einem solchen Komponentenbaum ausgeht, lässt sich der Algorithmus C so verbessern, dass seine Laufzeit in O(m) ist. Dazu ist es wiederum nötig, den Komponentenbaum in Linearzeit konstruieren zu können. Dies erfolgt über die Konstruktion eines Minimum Spanning Tree (MST), was aber auch in Linearzeit möglich ist (Fredman und Willard 1994). 14 6 Ergebnis Satz 1 Für das SSSP-Problem in ungerichteten Graphen mit ganzzahligen positiven Kantengewichten gibt es einen deterministischen Algorithmus mit Laufzeit O(m). Einwände Gegen dieses Ergebnis können zwei Einwände vorgebracht werden. Der Linearzeitalgorithmus verwendet atomic heaps bei der Konstruktion des 20 MST. Zum einen sind atomic heaps nur für 212 definiert und zum anderen benötigt man für atomic heaps Multiplikation, was aber keine AC 0 -Operation ist. Folgerung Dies bedeutet, für die Praxis muss man Lösungen finden, die ohne die Verwendung von atomic heaps auskommen. Dies ist möglich, indem man auf andere Verfahren zur Konstruktion eines MST zurückgreift. Satz 2 Auf einer RAM mit Standard AC 0 -Operationen gibt es einen deterministischen Algorithmus für das SSSP-Problem für ungerichtete Graphen mit ganzzahligen positiven Kantengewichten mit Laufzeit O(α(m, n)m). Endergebnis: Es gibt einen Linearzeitalgorithmus für das SSSP-Problem in ungerichteten Graphen mit ganzzahligen positiven Kantengewichten, aber diese optimale Lösung ist nicht für Implementationen geeigenet. Es gibt jedoch implementierbare Varianten für die praktische Anwendung. Literatur: Mikkel Thorup(1999): Undirected Single-Source Shortest Paths with Positive Integer Weights in Linear Time. Journal of the ACM 46,3. Seite 362-394. 15