Folien

Werbung
Erinnerung VL 20.06.2016
I Graphtraversierung (DFS, topologische Sortierung und mehr)
I Kürzeste Wege: Problemstellung, Algorithmen
I Analoger Algorithmus
I Dijkstras Algorithmus: Idee, Korrektheit
I Heute: mehr zu Dijkstra, (Bellman-Ford)
KIT Institut für Theoretische Informatik
1
I . . . doch zunächst
KIT Institut für Theoretische Informatik
2
Feedback Vorlesungsbefragung
I Vielen Dank für die zahlreichen Kommentare!
I Wiederkehrende Kommentare:
I
Im Hörsaal zu laut, Mikro zu leise, bärtiger Dozent war netter
I
Zu langsam, zu schnell, langweilig, zu viele Anforderungen
Gut: wenige Folien, schlecht: wenige Folien, zu voll
I
Mehr Beispiele/Bilder, Pseudocode in Monospace
KIT Institut für Theoretische Informatik
3
Erinnerung: analoger Algorithmus
M
0
Distance to M
R
5
Lösung ohne Rechner:
I Kanten
→
Fäden
I Kantengewicht
L
Q
Fadenlänge
I Knoten
→
Knoten
I Dann: Am Startknoten
anheben.
11
13
15
O
→
H
G
N
F
K P
E
C
17
17
18
19
20
S
V
J
W
KIT Institut für Theoretische Informatik
4
Dijkstra: Implementierung?
initialize
d,
parent
all nodes are non-scanned
∃ non-scanned node u with d[u] < ∞
u := non-scanned node v with minimal d[v ]
relax all edges (u, v ) out of u
u is scanned now
while
Wichtigste Operation: nde
u
KIT Institut für Theoretische Informatik
5
Prioritätsliste
Wir speichern ungescannte erreichte Knoten in
adressierbarer Prioritätsliste
Schlüssel ist
Q.
d[v ].
Knoten speichern handles.
oder gleich items
KIT Institut für Theoretische Informatik
6
Implementierung ≈ BFS mit PQ statt FIFO
Function Dijkstra(s
: NodeId) : NodeArray×NodeArray
// returns (d, parent)
Initialisierung:
d=h∞, . . . , ∞i : NodeArray
of
R ∪ {∞}
//
parent=h⊥, . . . , ⊥i
parent[s]:=
: NodeArray
tentative distance from root
of NodeId
s
Q : NodePQ
d[s] := 0; Q .insert(s)
//
// self-loop signals root
unscanned reached nodes
KIT Institut für Theoretische Informatik
7
: NodeId) : NodeArray×NodeArray
d = h∞, . . . , ∞i; parent[s]:= s ; d[s] := 0; Q .insert(s)
while Q 6= 0
/ do
u := Q .deleteMin
// scan u
foreach edge e = (u, v ) ∈ E do
if d[u] + c(e) < d[v ] then
d[v ]:= d[u] + c(e)
parent[v ] := u
//
if v ∈ Q then Q .decreaseKey(v )
else Q .insert(v )
return (d, parent)
Function Dijkstra(s
s
u
scanned
//
relax
update tree
u
v
reached
KIT Institut für Theoretische Informatik
8
Beispiel
Operation
2 3
2
b
c
a
2
9
5
s
10
8
1
0
e
f
4 d
0
7
10
2 3 5
7
2
a
b
c
2
9
5
s
10
8
1
0
e
f
4 d
0
7
6
6
deleteMin
relax
relax
7
2 3 5
2
a
c
b
2
9
5
s
10
8
1
0
f
e
4 d
6 0 6 7
2 3 5
7
2
a
c
b
2
9
5
s
10
8
1
0
e
f
4 d
10 0 6 7
2 3 5
7
2
a
b
c
2
9
s
10 5 1
8
0
f
e
4 d
6 0 6 7
2
3
relax
2
relax
relax
9
relax
(e, 6)
e →b
8
e →c
0
e →d
deleteMin
relax
(b, 5)
b→c
1
b→e
deleteMin
relax
(a, 2)
a→b
deleteMin
relax
(s, 0)
s →a
10
s →d
deleteMin
relax
2 3 5
2
a
b
c
2
9
5
s
10
8
1
0
e
f
4 d
7
10 0
Queue
(s)
insert
4
(d, 6)
d →s
5
d →b
deleteMin
(c, 7)
h(s, 0)i
hi
h(a, 2)i
h(a, 2), (d, 10)i
h(d, 10)i
h(b, 5), (d, 10)i
h(d, 10)i
h(c, 7), (d, 10)i
h(e, 6), (c, 7), (d, 10)
h(c, 7), (d, 10)i
h(c, 7), (d, 10)i
h(c, 7), (d, 10)i
h(d, 6), (c, 7)i
h(c, 7)i
h(c, 7)i
h(c, 7)i
hi
KIT Institut für Theoretische Informatik
9
Dijkstra: Laufzeit
Function Dijkstra(s
: NodeId) : NodeArray×NodeArray
Initialisierung:
d=h∞, . . . , ∞i : NodeArray of R ∪ {∞}
// O(n)
parent=h⊥, . . . , ⊥i : NodeArray of NodeId
// O(n)
parent[s]:= s
Q : NodePQ
// unscanned reached nodes, O(n)
d[s] := 0; Q .insert(s)
KIT Institut für Theoretische Informatik
10
Dijkstra: Laufzeit
: NodeId) : NodeArray×NodeArray
d = {∞, . . . , ∞}; parent[s]:= s ; d[s] := 0; Q .insert(s)
while Q 6= 0
/ do
u := Q .deleteMin
foreach edge e = (u, v ) ∈ E do
if d[u] + c(e) < d[v ] then
d[v ]:= d[u] + c(e)
parent[v ] := u
if v ∈ Q then Q .decreaseKey(v )
else Q .insert(v )
return (d, parent)
Function Dijkstra(s
//
O(n)
≤ n×
≤ m×
// ≤ m×
// ≤ m×
// ≤ m×
// ≤ m×
// ≤ n×
//
//
KIT Institut für Theoretische Informatik
11
Dijkstra: Laufzeit
: NodeId) : NodeArray×NodeArray
d = {∞, . . . , ∞}; parent[s]:= s ; d[s] := 0; Q .insert(s)
while Q 6= 0
/ do
u := Q .deleteMin
foreach edge e = (u, v ) ∈ E do
if d[u] + c(e) < d[v ] then
d[v ]:= d[u] + c(e)
parent[v ] := u
if v ∈ Q then Q .decreaseKey(v )
else Q .insert(v )
return (d, parent)
Function Dijkstra(s
//
O(n)
≤ n×
≤ m×
// ≤ m×
// ≤ m×
// ≤ m×
// ≤ m×
// ≤ n×
//
//
Insgesamt:
TDijkstra = O m · TdecreaseKey (n) + n · (TdeleteMin (n) + Tinsert (n))
KIT Institut für Theoretische Informatik
11
Laufzeit
Dijkstras ursprüngliche Implementierung: naiv
I insert:
O(1)
I decreaseKey:
I deleteMin:
d[v ]:= d[u] + c(u, v )
O(1)
O(n)
d[v ]:= d[u] + c(u, v )
d
komplett durchsuchen
TDijkstra = O m · TdecreaseKey (n) + n · (TdeleteMin (n) + Tinsert (n))
TDijkstra59 = O(m · 1 + n · (n + 1))
= O m + n2
KIT Institut für Theoretische Informatik
12
Laufzeit
Bessere Implementierung mit Binary-Heap-Prioritätslisten:
I insert:
O(log n)
I decreaseKey:
I deleteMin:
O(log n)
O(log n)
TDijkstra = O m · TdecreaseKey (n) + n · (TdeleteMin (n) + Tinsert (n))
TDijkstraBHp = O(m · log n + n · (log n + log n))
= O((m + n) log n)
KIT Institut für Theoretische Informatik
13
Laufzeit
(Noch) besser mit Fibonacci-Heapprioritätslisten:
I insert:
O(1)
I decreaseKey:
I deleteMin:
O(1)
(amortisiert)
O(log n)
(amortisiert)
TDijkstra = O m · TdecreaseKey (n) + n · (TdeleteMin (n) + Tinsert (n))
TDijkstraFib = O(m · 1 + n · (log n + 1))
= O(m + n log n)
Aber: konstante Faktoren in
O(·)
sind hier gröÿer!
KIT Institut für Theoretische Informatik
14
Analyse im Mittel
Modell: Kantengewichte sind zufällig auf die Kanten verteilt
Dann gilt:
m
E[TDijkstraBH(ea)p ] = O m + n log n log
n
Beweis: In Algorithmen II
KIT Institut für Theoretische Informatik
15
Monotone ganzzahlige Prioritätslisten
Beobachtung: In Dijkstras Algorithmus steigt das Minimum in der
Prioritätsliste monoton.
Das kann man ausnutzen.
u.U. bis herunter zu
schnellere Algorithmen
O(m + n).
Details: in Algorithmen II
KIT Institut für Theoretische Informatik
16
Negative Kosten
Was machen wir, wenn es Kanten mit negativen Kosten gibt?
Es kann Knoten geben mit
s p
u C
q v
s p
d[v ] = −∞
(2)
uC
q v ...
Wie nden wir heraus, welche das sind?
Endlosschleifen vermeiden!
KIT Institut für Theoretische Informatik
17
Zurück zu Basiskonzepten (Abschnitt 10.1 im Buch)
Lemma:
∃
kürzester
s v -Pfad P =⇒ P
ist OBdA einfach (eng. simple)
Beweisidee: (Kontraposition)
Fall:
¬∃
s p
v
über negativen Kreis erreichbar
kürzester
u C
⇒
s v -Pfad (sondern beliebig viele
q v ...
q v s p
(2)
uC
Sonst: betrachte beliebigen nicht-einfachen
Alle Kreise streichen
immer kürzere)
s v -Pfad.
einfacher, nicht längerer Pfad.
KIT Institut für Theoretische Informatik
18
Mehr Basiskonzepte
Übung, zeige:
Teilpfade kürzester Pfade sind selbst kürzeste Pfade
a−b−c −d
a−b, b−c, c −d, a−b−c, b−c −d
Übung: Kürzeste-Wege-Baum
Alle kürzeste Pfade von
s
aus zusammen bilden einen Baum, falls es
keine negativen Kreise gibt.
2 3 5
7
2
a
b
c
2
9
s
10 5 1
8
0
f
d
e
4
0
7
6
6
KIT Institut für Theoretische Informatik
19
Allgemeines Korrektheitskriterium
t1
Sei
tk
t2
z }| { z }| { z
}|
{
R = h· · · relax(e1 ) · · · relax(e2 ) · · · relax(ek ) · · ·i
eine Folge von Relaxationsoperationen und
p = he1 , e2 , . . . , ek i = hs, v1 , v2 , . . . , vk i
Dann gilt anschlieÿend:
ein kürzester Weg.
d[vk ] = µ(vk )
Beweisskizze: (Eigentlich Induktion über
d[s] = µ(s)
k)
bei Initialisierung
d[v1 ] = µ(v1 )
nach Zeitpunkt
t1
d[v2 ] = µ(v2 )
nach Zeitpunkt
t2
nach Zeitpunkt
tk
···
d[vk ] = µ(vk )
KIT Institut für Theoretische Informatik
20
Algorithmen brutal Bellman-Ford-Algorithmus für
beliebige Kantengewichte
Wir relaxieren alle Kanten (in irgendeiner Reihenfolge)
Alle kürzeste Pfade in
⇒
G
haben höchstens
n−1
n−1
mal.
Kanten.
Jeder kürzeste Pfad ist eine Teilfolge dieser Relaxationen!
v2
v=vk
v3
s=v1
3. Runde
1. Runde
(k−1). Runde
2. Runde
KIT Institut für Theoretische Informatik
21
Negative Kreise nden
Nach Ausführung von Bellman-Ford:
∀
negativen Kreise C:
∃(u, v ) ∈ C :
d[u] + c(e) < d[v ]
Beweis: Übung
v
und alle von
v
erreichbaren Knoten
x
haben
µ(x) = −∞
KIT Institut für Theoretische Informatik
22
Beispiel
KIT Institut für Theoretische Informatik
23
Herunterladen