Undirected Single-Source Shortest Paths with Positive Integer

Werbung
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
Herunterladen