Grundlegende Algorithmen Kapitel 4: Kürzeste Wege

Werbung
Grundlegende Algorithmen
Kapitel 4: Kürzeste Wege
Christian Scheideler
WS 2009
08.02.2010
Kapitel 4
1
Kürzeste Wege
Zentrale Frage: Wie komme ich am
schnellsten von A nach B?
B
A
08.02.2010
Kapitel 4
2
Kürzeste Wege
Zentrale Frage: Wie komme ich am
schnellsten von A nach B?
Fälle:
• Kantenkosten 1
• DAG, beliebige Kantenkosten
• Beliebiger Graph, positive Kantenkosten
• Beliebiger Graph, beliebige Kosten
08.02.2010
Kapitel 4
3
Einführung
Kürzeste-Wege-Problem:
• gerichteter Graph G=(V,E)
• Kantenkosten c:E→ℝ
• SSSP (single source shortest path):
Kürzeste Wege von einer Quelle zu allen
anderen Knoten
• APSP (all pairs shortest path):
Kürzeste Wege zwischen allen Paaren
08.02.2010
Kapitel 4
4
Einführung
42
0
-∞
5
-∞
-1
0
+∞
-∞
-∞
2
2
0
s
0
-2
-3
-1
-2
-1
-2
-3
µ(s,v): Distanz zwischen s und v
∞
µ(s,v) =
-∞
kein Weg von s nach v
Weg bel. kleiner Kosten von s nach v
min{ c(p) | p ist Weg von s nach v}
08.02.2010
Kapitel 4
5
Einführung
42
5
0
-∞
-∞
-1
0
+∞
-∞
0
-2
-3
2
0
s
-∞
2
-1
-2
-1
-2
-3
Wann sind die Kosten -∞?
Wenn es einen negativen Kreis gibt:
s
08.02.2010
C
v
Kapitel 4
c(C)<0
6
Einführung
Negativer Kreis hinreichend und notwendig
für Wegekosten -∞.
Negativer Kreis hinreichend:
s
Weg p
Weg q
C
v
c(C)<0
Kosten für i-fachen Durchlauf von C:
c(p) + i⋅c(C) + c(q)
Für i→∞ geht Ausdruck gegen -∞.
08.02.2010
Kapitel 4
7
Einführung
Negativer Kreis hinreichend und notwendig
für Wegekosten -∞.
Negativer Kreis notwendig:
• l: minimale Kosten eines einfachen Weges
von s nach v
• es gibt nichteinfachen Weg r von s nach v mit
Kosten c(r)<l
• r nicht einfach: Zerlegung in pCq, wobei C ein
Kreis ist und pq ein einfacher Pfad
• da c(r) < l≤c(pq) ist, gilt c(C)<0
08.02.2010
Kapitel 4
8
Kürzeste Wege
Graph mit Kantenkosten 1:
Führe Breitensuche durch.
3
2
4
1
3
3
1
4
s
2
2
08.02.2010
Kapitel 4
9
Kürzeste Wege in DAGs
Reine Breitensuche funktioniert nicht.
2
1
4
2
1
1
3
2
s
2
8
7
2
1
2
4
6
08.02.2010
1
1
3
1
2
9
5
1
Kapitel 4
10
Kürzeste Wege in DAGs
Korrekte Distanzen:
2
1
4
2
1
1
3
2
s
2
5
4
2
1
2
4
4
08.02.2010
1
1
3
1
2
6
5
1
Kapitel 4
11
Kürzeste Wege in DAGs
Strategie: nutze aus, dass Knoten in DAGs
topologisch sortiert werden können (alle
b erfüllen a<b)
Kanten a
4
2
2
1
3
s
08.02.2010
6
1
1
2
10
2
3
1
5
9
1
1
2
1
11
2
4
7
1 4
Kapitel
8
12
Kürzeste Wege in DAGs
Strategie: betrachte dann Knoten in der
Reihenfolge ihrer topologischen Sortierung
und aktualisiere Distanzen zu s
4
1
2
1
s
08.02.2010
4
6
1
3
3
2
2
5
2
3
1
1
2
10
2
9
1
2
2
7
46
5
1 4
Kapitel
5
46
1
4
1
11
6
8
13
Kürzeste Wege in DAGs
Strategie:
1. Topologische Sortierung der Knoten
2. Aktualisierung der Distanzen gemäß der
topologischen Sortierung
Warum funktioniert das??
08.02.2010
Kapitel 4
14
Kürzeste Wege in DAGs
Betrachte kürzesten Weg von s nach v.
Dieser hat topologische Sortierung (ti)i mit
ti<ti+1 for alle i.
t1
s
0
t2
c1
d1
c2
t3
t4
t5
d2
d3
d4
c3
c4
v
Besuch in topologischer Reihenfolge führt
zu richtigen Distanzen (di = ∑j≤i ci).
08.02.2010
Kapitel 4
15
Kürzeste Wege in DAGs
Betrachte kürzesten Weg von s nach v.
Dieser hat topologische Sortierung (ti)i mit ti<ti+1 für
alle i.
t1
s
0
t2
c1
d1
c2
t3
t4
t5
d2
d3
d4
c3
c4
v
Bemerkung: kein Knoten auf dem Weg zu v kann
Distanz < di zu s haben, da sonst kürzerer Weg
zu v möglich wäre.
08.02.2010
Kapitel 4
16
Kürzeste Wege in Graphen
Allgemeine Strategie:
• Am Anfang, setze d(s):=0 und d(v):=∞ für alle
Knoten
• besuche Knoten in einer Reihenfolge, die
sicherstellt, dass mindestens ein kürzester Weg
von s zu jedem v in der Reihenfolge seiner
Knoten besucht wird
• für jeden besuchten Knoten v, aktualisiere die
Distanzen der Knoten w mit (v,w)∈E, d.h. setze
d(w) := min{d(w), d(v)+c(v,w)}
08.02.2010
Kapitel 4
17
Kürzeste Wege in DAGs
Zurück zur Strategie:
1. Topologische Sortierung der Knoten
2. Aktualisierung der Distanzen gemäß der
topologischen Sortierung
Wie führe ich eine topologische
Sortierung durch?
08.02.2010
Kapitel 4
18
Kürzeste Wege in DAGs
Topologische Sortierung:
• Verwende eine FIFO Queue q
• Anfangs enthält q alle Knoten, die keine
eingehende Kante haben (Quellen).
• Entnehme v aus q und markiere alle (v,w)∈E.
Falls alle Kanten nach w markiert sind und w
noch nicht in q war, füge w in q ein. Wiederhole
das, bis q leer ist.
08.02.2010
Kapitel 4
19
Kürzeste Wege in DAGs
Beispiel:
•
: Knoten momentan in Queue q
• Nummerierung nach Einfügereihenfolge
2
1
6
4
2
1
5
1
3
3
1
08.02.2010
2
2
1
1
10
9
2
1
2
4
7
11
8
1 4
Kapitel
20
Kürzeste Wege in DAGs
Korrektheit der topologischen Nummerierung:
Knoten wird erst dann nummeriert, wenn alle
Vorgänger nummeriert sind.
2
1
6
4
2
1
5
1
3
3
1
08.02.2010
2
2
1
1
10
9
2
1
2
4
7
11
8
1 4
Kapitel
21
Kürzeste Wege in DAGs
Laufzeit: Zur Bestimmung aller Knoten ohne eingehende
Kante muss Graph einmal durchlaufen werden. Danach
wird jeder Knoten und jede Kante genau einmal
betrachtet, also Zeit O(n+m).
2
1
6
4
2
1
5
1
3
3
1
08.02.2010
2
2
1
1
10
9
2
1
2
4
7
11
8
1 4
Kapitel
22
Kürzeste Wege in DAGs
Bemerkung: topologische Sortierung kann nicht
alle Knoten nummerieren genau dann, wenn
Graph gerichteten Kreis enthält (kein DAG ist)
Test auf DAG-Eigenschaft
2
1
6
4
2
1
5
1
3
3
1
08.02.2010
2
2
1
1
10
9
2
1
2
4
7
11
8
1 4
Kapitel
23
Kürzeste Wege in DAGs
DAG-Strategie:
1. Topologische Sortierung der Knoten
Laufzeit O(n+m)
2. Aktualisierung der Distanzen gemäß der
topologischen Sortierung
Laufzeit O(n+m)
Insgesamt Laufzeit O(n+m).
08.02.2010
Kapitel 4
24
Dijkstras Algorithmus
Nächster Schritt: Kürzeste Wege für beliebige
Graphen mit positiven Kanten.
Problem: besuche Knoten eines kürzesten Weges
in richtiger Reihenfolge
s
w
0
d1
d2
d3
d4
v
Lösung: besuche Knoten in der Reihenfolge der
kürzesten Distanz zur Quelle s
08.02.2010
Kapitel 4
25
Dijkstras Algorithmus
• Am Anfang, setze d(s):=0 und d(v):=∞ für
alle Knoten. Füge s in Priority Queue q
ein, wobei die Prioritäten in q gemäß der
aktuellen Distanzen d(v) definiert sind.
• Wiederhole, bis q leer ist:
Entferne aus q (deleteMin) den Knoten v
mit niedrigstem d(v). Für alle (v,w)∈E,
setze d(w) := min{d(w), d(v)+c(v,w)}. Falls
w noch nicht in q war, füge w in q ein.
08.02.2010
Kapitel 4
26
Dijkstras Algorithmus
Beispiel: (
: aktuell,
: fertig)
1
1
∞
3
∞
2
1
2
∞
1
4
2
5
4
∞
1
s
08.02.2010
2
2
∞
2
∞
4
3
3
5
∞
Kapitel 4
1
5∞
2
27
Dijkstras Algorithmus
Procedure Dijkstra(s: NodeId)
d=<∞,…, ∞>: NodeArray of ℝ∪{-∞,∞}
parent=<⊥,…,⊥>:
⊥
⊥ NodeArray of NodeId
d[s]:=0; parent[s]:=s
q=<s>: NodePQ
while q =<> do
u:=q.deleteMin() // u: min. Distanz zu s in q
foreach e=(u,v)∈E do
if d[v] > d[u]+c(e) then // aktualisiere d[v]
if d[v]=∞ then q.insert(v) // v schon in q?
parent[v]:=u
// d[v] wird auf d[u]+c(e) gesetzt
q.decreaseKey(v, d[v]-(d[u]+c(e)))
08.02.2010
Kapitel 4
28
Dijkstras Algorithmus
Korrektheit:
• Angenommen, Algo sei inkorrekt.
• Sei v der Knoten mit kleinstem µ(s,v), der aus q entfernt
wird mit d[v]>µ(s,v).
• Sei p=(s=v1,v2,…,vk=v) ein kürzester Weg von s nach v.
• Weil alle c(e)>0 sind, steigt minimales d[w] in q monoton
an. Da d[vk-1]<d[vk], muss vk-1 vor vk aus q entfernt worden sein, und wegen der Annahme galt d[vk-1]=µ(s,vk-1)
• Bei Entfernung von vk-1 hat Algo überprüft, ob d[vk-1] +
c(vk-1,vk)<d[vk]. Das muss bei Annahme oben der Fall
gewesen sein, aber dann hätte Algo d[v] auf d[vk-1] +
c(vk-1,v)=µ(s,v) gesetzt, ein Widerspruch.
08.02.2010
Kapitel 4
29
Dijkstras Algorithmus
• TOp(n): Laufzeit von Operation Op auf Datenstruktur
mit n Elementen
Laufzeit:
TDijkstra = O(n(TDeleteMin(n)+TInsert(n)) + m⋅TdecreaseKey(n))
Binärer Heap: alle Operationen O(log n), also TDijkstra =
O((m+n)log n)
Fibonacci Heap: amortisiert
• TDeleteMin(n)=TInsert(n)=O(log n)
• TdecreaseKey(n)=O(1)
• Damit TDijkstra = O(n log n + m)
08.02.2010
Kapitel 4
30
Monotone Priority Queues
Einsicht: Dijkstras Algorithmus braucht keine
allgemeine Priority Queue, sondern nur eine
monotone Priority Queue.
Monotone Priority Queue: Folge der gelöschten
Elemente hat monoton steigende Werte.
Effiziente Implementierungen von monotonen
Priority Queues möglich, falls Kantenkosten
ganzzahlig.
08.02.2010
Kapitel 4
31
Bucket Queue
Annahme: alle Kantenkosten im Bereich [0,C].
Konsequenz: zu jedem Zeitpunkt enthält q Distanzen im Bereich [d,d+C] für ein d.
d+3
d+1
d
C=8
d+2
d+1
d+8
d+5
08.02.2010
Kapitel 4
32
Bucket Queue
Annahme: alle Kantenkosten im Bereich [0,C].
Konsequenz: zu jedem Zeitpunkt enthält q Distanzen im Bereich [d,d+C] für ein d.
Bucket Queue: Array B aus C+1 Listen und Variable dmin für aktuell minimale Distanz (mod C+1)
0
08.02.2010
1
2
3
….
Kapitel 4
C
33
Bucket Queue
0
1
2
3
….
C
• Jeder Knoten v mit momentaner Distanz d[v]
wird in Liste B[d[v] mod (C+1)] gespeichert
• Da momentane d[v]´s im Bereich [d,d+C] für ein
d sind, haben alle v in einem B[d] dasselbe d[v].
08.02.2010
Kapitel 4
34
Bucket Queue
0
1
2
3
….
C
• Insert(v): fügt v in B[d[v] mod (C+1)] ein. Laufzeit O(1).
• decreaseKey(v): entfernt v aus momentaner Liste und
fügt v in B[d[v] mod (C+1)] ein. Falls in v Position in der
Liste speichert, Laufzeit O(1).
• deleteMin(): solange B[dmin]=∅, setze dmin:=(dmin+1) mod
(C+1). Nimm dann einen Knoten u aus B[dmin] heraus.
Laufzeit O(C).
08.02.2010
Kapitel 4
35
Bucket Queue
0
1
2
3
….
C
• Insert(v), decreaseKey(v): Laufzeit O(1).
• deleteMin(): Laufzeit O(C).
• Laufzeit von Dijkstras Algo mit Bucket
Queue: O(n⋅C+m)
08.02.2010
Kapitel 4
36
Radix-Heap
Annahmen:
• alle Elemente haben eine maximale
Differenz von C zueinander
• Insert(e) fügt nur Elemente e ein mit
key(e)≥kmin (kmin: min. Schlüssel)
08.02.2010
Kapitel 4
37
Radix-Heap
Array B mit Listen B[-1] bis B[K], K=1+⌊log C⌋.
-1
0
1
2
….
K
Regel: Element e in B[min(msd(kmin,key(e)),K)]
msd(kmin,key(e)): höchstes Bit, in dem sich Binärdarstellungen von kmin und key(e) unterscheiden
(-1: kein Unterschied)
08.02.2010
Kapitel 4
38
Radix-Heap
Beispiel für msd(kmin,k):
• sei kmin=17 oder binär 10001
• k=17: msd(kmin,k)=-1
• k=18: binär 10010, also msd(kmin,k)=1
• k=21: binär 10101, also msd(kmin,k)=2
• k=52: binär 110100, also msd(kmin,k)=5
Berechnung von msd für a≠b:
msd(a,b)=⌊log(a⊕b)⌋
Zeit O(1) (mit entspr. Maschinenbefehlen)
08.02.2010
Kapitel 4
39
Radix-Heap
-1 0
1
2
….
K
min():
• gib kmin in B[-1] zurück
Laufzeit: O(1)
08.02.2010
Kapitel 4
40
Radix-Heap
insert(e): ( key(e)≥kmin )
• i:=min{msd(kmin,key(e)), K}
• speichere e in B[i]
Laufzeit: O(1)
delete(e): ( key(e)>kmin )
• lösche e aus seiner Liste B[j] raus
Laufzeit: O(1)
decreaseKey(e,∆): ( key(e) - ∆ ≥ kmin )
• rufe delete(e) und insert(e) mit key(e):=key(e) - ∆ auf
Laufzeit: O(1)
08.02.2010
Kapitel 4
41
Radix-Heap
deleteMin():
• Falls B[-1] besetzt, entnehme ein e aus B[-1]
(sonst kein Element mehr in Heap und fertig)
• finde minimales i, so dass B[i]≠∅
∅ (falls kein solches i
oder i=-1, dann fertig)
• bestimme kmin in B[i] (in O(1) Zeit möglich, falls z.B.
kmin-Werte in extra Feld min[-1..K] gehalten)
• verteile Knoten in B[i] über B[-1],…,B[i-1] gemäß
neuem kmin
Entscheidend: für alle e in B[j], j>i, gilt nach wie vor
msd(kmin,key(e))=j, d.h. sie müssen nicht verschoben
werden.
08.02.2010
Kapitel 4
42
Radix-Heap
-1
2
0
1
2
3
4
5
6
7
8
4
9
260
5
11
381
6
14
Wir betrachten Sequenz von deleteMin Operationen
08.02.2010
Kapitel 4
43
Radix-Heap
-1
9
0
1
2
11
14
3
4
5
6
7
8
260
381
Wir betrachten Sequenz von deleteMin Operationen
08.02.2010
Kapitel 4
44
Radix-Heap
Lemma 4.1: Sei B[i] die minimale nichtleere
Liste, i≥0. Sei xmin der kleinste Schlüssel
in B[i]. Dann ist msd(xmin,x)<i für alle
Schlüssel x in B[i].Alle Elemente in B[i] nach links
Beweis:
• x=xmin: klar
• x≠xmin: wir unterscheiden zwei Fälle:
1) i<K, 2) i=K
08.02.2010
Kapitel 4
45
Radix-Heap
Fall i<K:
Bitposition: i
altes kmin
a
0
xmin
a
1
a
1
x
0
Also muss msd(xmin,x)<i sein.
08.02.2010
Kapitel 4
46
Radix-Heap
Fall i=K:
Bitposition: j≥K
h
altes kmin
a
0
xmin
a
1
b
0
a
1
b
1
x
0
• Für alle x: kmin < xmin ≤ x ≤ kmin+C
• j = msd(kmin,xmin), h = msd(xmin,x)
08.02.2010
Kapitel 4
47
Radix-Heap
Fall i=K:
Bitposition: j≥K
h
altes kmin
a
0
xmin
a
1
b
0
a
1
b
1
x
0
• Wegen j≥K hat Binärdarstellung von jedem
übrigbleibenden x dasselbe Präfix a1b bis runter
zu Bitstelle j‘≤K, d.h. h<K
08.02.2010
Kapitel 4
48
Radix-Heap
-1
0
1
2
….
K
Konsequenz:
• jeder Knoten nur maximal K-mal verscho-ben in
Radix Heap
• Potenzial für amortisierte Analyse: Summe der
Positionen der Elemente im Radix-Heap
• insert(): amortisierte Laufzeit O(log C).
08.02.2010
Kapitel 4
49
Laufzeitvergleich
Laufzeit
Fibonacci-Heap Radix-Heap
insert
O(1)
O(log C) amor.
min
O(1)
O(1)
deleteMin
O(log n) amor.
O(1) amor.
delete
O(log n) amor.
O(1)
merge
O(1)
O(n)
decreaseKey O(1)
O(1)
08.02.2010
Kapitel 4
50
Radix Heap
-1
0
1
2
….
K
Amortisierte Laufzeiten:
• deleteMin(), decreaseKey(v): O(1).
• insert(v): O(log C).
Laufzeit von Dijkstras Algo mit Radix Heap:
O(m + n log C)
08.02.2010
Kapitel 4
51
Bellman-Ford Algorithmus
Nächster Schritt: Kürzeste Wege für beliebige
Graphen mit beliebigen Kantenkosten.
Problem: besuche Knoten eines kürzesten Weges
in richtiger Reihenfolge
s
w
0
d1
d2
d3
d4
v
Dijkstra Algo kann nicht mehr verwendet werden,
da er im Allgemeinen nicht mehr Knoten in der
Reihenfolge ihrer Distanz zu s besucht.
08.02.2010
Kapitel 4
52
Bellman-Ford Algorithmus
Beispiel für Problem mit Dijkstra Algo:
v
2
∞
2
0
-1
1
s
3
3
∞
∞
-1
1
-4
Knoten v hat falschen Distanzwert!
08.02.2010
Kapitel 4
53
Bellman-Ford Algorithmus
Lemma 4.2: Für jeden Knoten v mit µ(s,v) >
-∞ zu s gibt es einfachen Weg (ohne
Kreis!) von s nach v der Länge µ(s,v).
Beweis:
• Weg mit Kreis mit Kantenkosten ≥0:
Kreisentfernung erhöht nicht die Kosten
• Weg mit Kreis mit Kantenkosten <0:
Distanz zu s ist -∞ !
08.02.2010
Kapitel 4
54
Bellman-Ford Algorithmus
Folgerung: (Graph mit n Knoten)
Für jeden Knoten v mit µ(s,v)> -∞ gibt es
kürzesten Weg der Länge <n zu v.
Strategie: Durchlaufe (n-1)-mal sämtliche
Kanten in Graph und aktualisiere Distanz.
Dann alle kürzeste Wege berücksichtigt.
s
0
Durchlauf
08.02.2010
d1
1
d2
2
d3
3
Kapitel 4
d4
v
4
55
Bellman-Ford Algorithmus
Problem: Erkennung negativer Kreise
-2
1
s
∞
1
0
∞
1
-1
∞
-1
1
1
2
0
∞
-1
Einsicht: in negativem Kreis erniedrigt sich Distanz
in jeder Runde bei mindestens einem Knoten
08.02.2010
Kapitel 4
56
Bellman-Ford Algorithmus
Problem: Erkennung negativer Kreise
-2
1
s
1
0
-1
-1
1
0
-1
Zeitpunkt: kontinuierliche Distanzerniedrigung
startet spätestens in n-ter Runde (dann Kreis
mindestens einmal durchlaufen)
08.02.2010
Kapitel 4
57
Bellman-Ford Algorithmus
Keine Distanzerniedrigung möglich:
• Angenommen wir erreichen Zeitpunkt mit
d[v]+c(v,w)≥
≥d[w] für alle Kanten (v,w).
• Dann gilt (über Induktion) für jeden Weg p,
dass d[s]+c(p)≥d[w] für alle Knoten w.
• Falls sichergestellt ist, dass für den
≥c(p) zu
kürzesten Weg p nach w, d[w]≥
jedem Zeitpunkt ist, dann gilt am Ende
d[w]=µ(s,w).
08.02.2010
Kapitel 4
58
Bellman-Ford Algorithmus
Zusammenfassung:
• Keine Distanzerniedrigung mehr möglich
(d[v]+c(v,w)≥d[w] für alle w):
Fertig, d[w]=µ(s,w) für alle w
• Distanzerniedrigung möglich selbst noch in n-ter
Runde (d[v]+c(v,w)<d[w] für ein w):
Dann gibt es negative Kreise, also Knoten w mit
Distanz µ(s,w)=-∞. Ist das wahr für ein w, dann
für alle von w erreichbaren Knoten.
08.02.2010
Kapitel 4
59
Bellman-Ford Algorithmus
Procedure BellmanFord(s: NodeId)
d=<∞,…,∞>: NodeArray of ℝ∪{-∞, ∞}
parent=<⊥,…, ⊥>: NodeArray of NodeId
d[s]:=0; parent[s]:=s
for i:=1 to n-1 do // aktualisiere Kosten für n-1 Runden
forall e=(v,w)∈E do
if d[w] > d[v]+c(e) then // bessere Distanz möglich?
d[w]:=d[v]+c(e); parent[w]:=v
forall e=(v,w) ∈E do
// in n-ter Runde noch besser?
if d[w] > d[v]+c(e) then infect(w)
Procedure infect(v) // setze -∞-Kosten von v aus
if d[v]>-∞ then
d[v]:=-∞
forall (v,w)∈E do infect(w)
08.02.2010
Kapitel 4
60
Bellman-Ford Algorithmus
Laufzeit: O(n⋅m)
Verbesserungsmöglichkeiten:
• Überprüfe in jeder Aktualisierungsrunde,
ob noch irgendwo d[v]+c[v,w]<d[w] ist.
Nein: fertig!
• Besuche in jeder Runde nur die Knoten w,
für die Test d[v]+c[v,w]<d[w] sinnvoll (d.h.
d[v] hat sich in letzter Runde geändert).
08.02.2010
Kapitel 4
61
All Pairs Shortest Paths
Annahme: Graph mit beliebigen Kantenkosten, aber keine negativen Kreise
Naive Strategie für Graph mit n Knoten: lass
n-mal Bellman-Ford Algorithmus (einmal
für jeden Knoten) laufen
Laufzeit: O(n2 m)
08.02.2010
Kapitel 4
62
All Pairs Shortest Paths
Bessere Strategie: Reduziere n BellmanFord Anwendungen auf n Dijkstra Anwendungen
Problem: wir brauchen dazu nichtnegative
Kantenkosten
Lösung: Umwandlungsstrategie in nichtnegative Kantenkosten, ohne kürzeste Wege
zu verfälschen (nicht so einfach!)
08.02.2010
Kapitel 4
63
All Pairs Shortest Paths
Gegenbeispiel zur Erhöhung um Wert c:
Vorher
2
v
Kosten +1 überall
3
1
s
v
2
s
1
-1
2
0
: kürzester Weg
08.02.2010
Kapitel 4
64
All Pairs Shortest Paths
• Sei φ:V→ℝ eine Funktion, die jedem
Knoten ein Potenzial zuweist.
• Die reduzierten Kosten von e=(v,w) sind:
r(e) := φ(v) + c(e) - φ(w)
Lemma 4.3: Seien p und q Wege in G. Dann
gilt für jedes Potenzial φ: r(p)<r(q) genau
dann wenn c(p)<c(q).
08.02.2010
Kapitel 4
65
All Pairs Shortest Paths
Lemma 4.3: Seien p und q Wege in G. Dann
gilt für jedes Potenzial φ: r(p)<r(q) genau
dann wenn c(p)<c(q).
Beweis: Sei p=(v1,…,vk) ein beliebiger Weg
und ei=(vi,vi+1) für alle i. Es gilt:
r(p) = ∑i r(ei)
= ∑i (φ(vi) + c(e) - φ(vi+1))
= φ(v1) + c(p) - φ(vk)
08.02.2010
Kapitel 4
66
All Pairs Shortest Paths
Lemma 4.4: Angenommen, G habe keine
negativen Kreise und dass alle Knoten von s
erreicht werden können. Sei φ(v)=µ(s,v) für alle
v∈V. Mit diesem φ ist r(e)≥0 für alle e.
Beweis:
• nach Annahme ist µ(s,v)∈ℝ für alle v
• wir wissen: für jede Kante e=(v,w) ist
µ(s,v)+c(e)≥µ(s,w) (Abbruchbedingung!)
• also ist r(e) = µ(s,v) + c(e) - µ(s,w) ≥ 0
08.02.2010
Kapitel 4
67
All Pairs Shortest Paths
1. Füge neuen Knoten s und Kanten (s,v) für alle
v hinzu mit c(s,v)=0 (alle erreichbar!)
2. Berechne µ(s,v) nach Bellman-Ford und setze
φ(v):=µ(s,v) für alle v
3. Berechne die reduzierten Kosten r(e)
4. Berechne für alle Knoten v die Distanzen
µ(v,w) mittels Dijkstra Algo mit reduzierten
Kosten auf Graph ohne Knoten s
5. Berechne korrekte Distanzen µ(v,w) durch
µ(v,w)=µ(v,w)+φ(w)-φ(v)
08.02.2010
Kapitel 4
68
All Pairs Shortest Paths
a
Beispiel:
2
2
b
b
1
a
1
d
1
c
1
-1
c
-1
d
08.02.2010
Kapitel 4
69
All Pairs Shortest Paths
Schritt 1: künstliche Quelle
a
2
0
b
0
s
1
0
0
1
c
-1
d
08.02.2010
Kapitel 4
70
All Pairs Shortest Paths
Schritt 2: Bellman-Ford auf s
a
2
0
0
s
φ(a)=0
1
b
φ(b)=0
c
φ(c)=-1
0
0
1
-1
d
08.02.2010
Kapitel 4
φ(d)=0
71
All Pairs Shortest Paths
Schritt 3: r(e)-Werte berechnen
a
2
Die reduzierten Kosten von
e=(v,w) sind:
r(e) := φ(v) + c(e) - φ(w)
1
φ(a)=0
0
b
φ(b)=0
c
φ(c)=-1
0
d
08.02.2010
Kapitel 4
φ(d)=0
72
All Pairs Shortest Paths
Schritt 4: berechne alle Distanzen
µ(v,w) via Dijkstra
2
µ
a
b
c
d
08.02.2010
a
0
1
0
0
b
2
0
2
2
c
3
1
0
0
d
3
1
3
0
Kapitel 4
1
a
φ(a)=0
0
b
φ(b)=0
c
φ(c)=-1
0
d
φ(d)=0
73
All Pairs Shortest Paths
Schritt 5: berechne korrekte
Distanzen durch die Formel
µ(v,w)=µ(v,w)+φ(w)-φ(v)
µ
a
b
c
d
08.02.2010
a
0
1
1
0
b
2
0
3
2
c
2
0
0
-1
d
3
1
4
0
Kapitel 4
a
2
1
φ(a)=0
1
b
φ(b)=0
c
φ(c)=-1
-1
d
φ(d)=0
74
All Pairs Shortest Paths
Laufzeit des APSP-Algorithmus:
O(TBellman-Ford(n,m) + n⋅TDijkstra(n,m))
= O(n⋅m + n(n log n + m))
= O(n⋅m
⋅ + n2 log n)
unter Verwendung von Fibonacci Heaps.
08.02.2010
Kapitel 4
75
Transitive Hülle
Problem: Konstruiere für einen gerichteten
Graphen G=(V,E) eine Datenstruktur, die
die folgende Operation (speicher- und
zeit-)effizient unterstützt:
• Reachable(v,w): liefert 1, falls es einen
gerichteten Weg von v nach w in G gibt
und sonst 0
08.02.2010
Kapitel 4
76
Transitive Hülle
Lösung 1: verwende APSP Algorithmus
• Laufzeit zur Erstellung der DS:
O(n⋅m + n2 log n)
• Speicheraufwand: O(n2)
• Laufzeit von Reachable(v,w): O(1)
(nachschauen in Tabelle, ob µ(v,w)<∞ )
08.02.2010
Kapitel 4
77
Transitive Hülle
Einsicht: Kantenkosten jetzt egal. Daher
können wir alle Kantenkosten auf 1
setzen.
Lösung 2:
• verwende als APSP Algorithmus einfach
n-mal Breitensuche (1x von allen Knoten)
• Laufzeit: O(n(n+m))
08.02.2010
Kapitel 4
78
Transitive Hülle
Einsicht: Alle Knoten in einer starken ZHK
haben dieselbe Menge erreichbarer
Knoten. Daher reicht es, sie durch
Repräsentanten zu vertreten.
v
w
ZHK
ZHK
ZHK
08.02.2010
Kapitel 4
79
Transitive Hülle
Lösung 3: verwende ZHK-Algorithmus
• bestimme starke ZHKs
e
d
i
h
g
f
c
a
08.02.2010
b
Kapitel 4
80
Transitive Hülle
Lösung 3: verwende ZHK-Algorithmus
• bestimme ZHK-Graph (Repräsentanten)
e
i
c
a
08.02.2010
b
Kapitel 4
81
Transitive Hülle
Lösung 3: verwende ZHK-Algorithmus
• Wende APSP-Algo auf ZHK-Graph an
e
i
c
a
08.02.2010
b
Kapitel 4
82
Transitive Hülle
Reachable(v,w):
• Bestimme Repräsentanten rv und rw von v
und w
• rv=rw: gib 1 aus
• sonst gib Reachable(rv,rw) für ZHK-Graph
zurück
08.02.2010
Kapitel 4
83
Transitive Hülle
• Graph G=(V,E): n=|V|, m=|E|
• ZHK-Graph G’=(V’,E’): n’=|V’|, m’=|E’|
Datenstruktur:
• Berechnungszeit:
O(n + m + n’⋅(m’ + n’))
• Speicher: O(n + (n’)2)
Reachable(v,w): Laufzeit O(1)
08.02.2010
Kapitel 4
84
Transitive Hülle
Lösung 4: mit Matrixmultiplikation (auf ZHK-Graph)
(Siehe auch die DuA Vorlesung.)
• Erstelle Adjazenzmatrix A∈{0,1}n×n von G
(mit 1-Einträgen entlang Diagonale)
• Verwende für die Matrixmultiplikation das Boolesche
Produkt, d.h. für C=A⋅B gilt
ci,j= Vk(ai,k∧bk,j) (statt ci,j = ∑k (ai,k⋅bk,j) )
• Berechne A*=An-1. Es gilt dann:
a*i,j = 1 ⇔ es gibt gerichteten Weg von i nach j
• Zur Berechnung von An-1 sind nur O(log n) Matrixmultiplikationen notwendig.
• Zeit für Matrixmultiplikation nach Strassen: O(n2,81)
• Besser als Lösung 2, falls m´≈n´2.
08.02.2010
Kapitel 4
85
Ausblick
Matchingalgorithmen…
08.02.2010
Kapitel 4
86
Herunterladen