Folien

Werbung
Erinnerung VL 15.06.2016
I Graphtraversierung
I
BFS (Breitensuche): in Schichten um Startknoten
löst einfache Form des Kürzeste-Wege-Problems
I
DFS (Tiefensuche): erst absteigen, dann Alternativen ansehen
generisch formuliert, viele Instanziierungen möglich
I Heute: mehr zu DFS, kürzeste Wege
KIT Institut für Theoretische Informatik
1
Erinnerung: Tiefensuchschema
unmark all nodes;
init
s ∈ V do
s is not marked
mark s
root(s)
DFS(s, s)
foreach
if
Procedure DFS(u, v
then
: NodeId)
//
//
//
make s a root and grow
a new DFS tree rooted at s
Explore v coming from u
foreach (v , w ) ∈ E do
if w is marked then traverseNonTreeEdge(v , w )
else
traverseTreeEdge(v , w )
mark w
DFS(v , w )
backtrack(u, v )
// return from v along the incoming edge
KIT Institut für Theoretische Informatik
2
Wiederholung: Kantenklassizierung
I Baumkanten: Elemente des Waldes, der bei der Suche gebaut wird
I Vorwärtskanten: verlaufen parallel zu Wegen aus Baumkanten
I Rückwärtskanten: verlaufen antiparallel zu Wegen aus Baumkanten
I Querkanten: alle übrigen
forward
s
tree
backward
cross
KIT Institut für Theoretische Informatik
3
DFS-Nummerierung
dfsPos=1
init:
root(s):
traverseTreeEdge(v , w ):
: 1..n
dfsNum[s]:= dfsPos++
dfsNum[w ]:= dfsPos++
u≺v :⇔ dfsNum[u] < dfsNum[v ] .
Beobachtung:
Knoten auf dem Rekursionsstapel sind bzgl.
1
tree
backward s
cross
forward
2
b
3
e
≺
sortiert
4
g
d
c
7
6
5
f
KIT Institut für Theoretische Informatik
4
Fertigstellungszeit
init:
nishingTime=1
backtrack(u, v ):
nishTime[v ]:= nishingTime++
7
tree
backward s
cross
forward
5
b
: 1..n
4
e
2
g
d
c
6
3
1
f
KIT Institut für Theoretische Informatik
5
Kantenklassizierung bei DFS
nishTime[w ]
(v , w )
<
dfsNum[w ]
nishTime[v ]
marked
tree
yes
yes
no
forward
yes
yes
yes
backward
no
no
yes
cross
no
yes
yes
type
dfsNum[v ]
<
w
is
forward
s
tree
backward
cross
KIT Institut für Theoretische Informatik
6
Topologische Sortierung
Denition 1
Eine lineare Anordnung
t
der Knoten eines DAGs
G = (V , E ),
in der alle Kanten von kleineren zu gröÿeren Knoten verlaufen,
heiÿt topologische Sortierung, d. h.
∀(u, v ) ∈ E : t(u) < t(v ).
Beispiel:
topologisch sortierter Kleidergraph, Quelle: Wikipedia
Kleidergraph, Quelle: Wikipedia
KIT Institut für Theoretische Informatik
7
Topologisches Sortieren mittels DFS
Theorem 2
G ist kreisfrei (DAG) ⇔ DFS ndet keine Rückwärtskante.
In diesem Fall liefert
t(v ):= n − nishTime[v ]
eine topologische Sortierung.
KIT Institut für Theoretische Informatik
8
Topologisches Sortieren mittels DFS
Theorem 2
G ist kreisfrei (DAG) ⇔ DFS ndet keine Rückwärtskante.
In diesem Fall liefert
t(v ):= n − nishTime[v ]
eine topologische Sortierung.
Beweis ⇒: Annahme:
∃
Rückwärtskante.
Zusammen mit Baumkanten ergibt sich ein Kreis.
Widerspruch.
forward
s
tree
backward
cross
KIT Institut für Theoretische Informatik
8
Topologisches Sortieren mittels DFS
Satz:
G
⇔ DFS ndet keine
t(v ):= n − nishTime[v ]
∀(u, v ) ∈ E : t(u) < t(v ).
kreisfrei (DAG)
In diesem Fall liefert
Sortierung, d. h.
Rückwärtskante.
eine topologische
Beweis ⇐:
Keine Rückwärtskante
Kantenklassizierung
z}|{
⇒
⇒G
∀(v , w ) ∈ E : nishTime[v ] > nishTime[w ]
ist kreisfrei und
nishTime deniert umgekehrte topologische Sortierung.
KIT Institut für Theoretische Informatik
9
Starke Zusammenhangskomponenten
∗
u↔v
falls
∃
Pfad
Beobachtung:
∗
↔
∗
↔ mit
hu, . . . , v i und ∃
Betrachte die Relation
Pfad
hv , . . . , ui.
ist Äquivalenzrelation
Die Äquivalenzklassen von
∗
↔
Übung
bezeichnet man als starke
Zusammenhangskomponenten.
DFS-basierter Linearzeitalgorithmus
−→
Algorithmen II
KIT Institut für Theoretische Informatik
10
Mehr DFS-basierte Linearzeitalgorithmen
I 2-zusammenhängende Komponenten: bei Entfernen eines Knotens
aus einer Komponente bleibt diese zusammenhängend
(ungerichtet)
I 3-zusammenhängende Komponenten
I Planaritätstest (lässt sich der Graph kreuzungsfrei zeichnen?)
I Einbettung planarer Graphen
KIT Institut für Theoretische Informatik
11
BFS ←→ DFS
pro BFS:
I nichtrekursiv
I keine Vorwärtskanten
I kürzeste Wege, Umgebung
pro DFS:
I keine explizite Datenstruktur
forward
s
tree
backward
cross
(Rekursionsstapel) für ToDos,
daher mglw. einfacher
I Grundlage vieler Algorithmen
KIT Institut für Theoretische Informatik
12
Kap. 10: Kürzeste Wege
Eingabe:
I Graph
G = (V , E )
mit
I
Kostenfunktion/Kantengewicht
c :E →R
sowie
I Startknoten
Ausgabe: für alle
I Länge
I
µ(v )
3.0 km
s.
v ∈ V:
des kürzesten Pfades von
µ(v ) := min {c(p) : p ist Pfad von s
k
mit c(he1 , . . . , ek i) := ∑i=1 c(ei ).
s
nach
nach
v,
v}
KIT Institut für Theoretische Informatik
13
Kap. 10: Kürzeste Wege
Eingabe:
I Graph
G = (V , E )
mit
I
Kostenfunktion/Kantengewicht
c :E →R
sowie
I Startknoten
Ausgabe: für alle
I Länge
I
µ(v )
3.0 km
s.
v ∈ V:
des kürzesten Pfades von
µ(v ) := min {c(p) : p ist Pfad von s
k
mit c(he1 , . . . , ek i) := ∑i=1 c(ei ).
s
nach
nach
v,
v}
Oft wollen wir auch geeignete Repräsentation der kürzesten Pfade.
KIT Institut für Theoretische Informatik
13
Anwendungen
I Routenplanung
I
Straÿennetze
I
Spiele
I
Kommunikationsnetze
I Unterprogramm
I
Flüsse in Netzwerken
I
...
I Tippfehlerkorrektur
3.0 km
I Disk Scheduling
I ...
KIT Institut für Theoretische Informatik
14
Grundlagen
Gibt es immer einen kürzesten Pfad?
Es kann negative Kreise geben!
s p
u C
q v
s p
(2)
uC
q v ...
weitere Grundlagen just in time
KIT Institut für Theoretische Informatik
15
Azyklische Graphen
später
KIT Institut für Theoretische Informatik
16
Kantengewichte ≥ 0
Alle Gewichte gleich: Breitensuche (BFS)!
b
s
0
e
g
c
d
f
1
2
tree
backward
cross
forward
3
KIT Institut für Theoretische Informatik
17
Dijkstras Algorithmus
Nun: Beliebige nichtnegative Kantengewichte
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
18
Korrektheit der Bindfäden
M
0
Distance to M
Betrachte beliebigen Knoten
mit Hängetiefe
∃
R
v
d[v ].
L
Pfad mit Hängetiefe:
Q
kürzerer Pfad:
falls es einen solchen Pfad
gäbe, wäre einer seiner Fäden
zerrissen!
11
13
15
O
verfolge strae Fäden
¬∃
5
H
G
N
F
K P
E
C
17
17
18
19
20
S
V
J
W
KIT Institut für Theoretische Informatik
19
Edsger Wybe Dijkstra
19302002
I 1972 ACM Turing Award
I THE: das erste Mulitasking-OS
I Semaphor
I Selbst-stabilisierende Systeme
I GOTO Statement Considered Harmful
Bildquelle: Wikipedia
KIT Institut für Theoretische Informatik
20
Allgemeine Denitionen
Knotenarrays:
d[v ] =
aktuelle (vorläuge)
Distanz von
Invariante:
I parent[v ]
=
s nach v
d[v ] ≥ µ(v )
Vorgänger von
v
auf dem (vorläugen) kürzesten
Pfad von
s
nach
v
Kante Kante
I
parent parent
s
Wie bei BFS benutzen wir zwei
d[v]
Initialisierung:
d[s] = 0, parent[s] = s
d[v ] = ∞, parent[v ] = ⊥
d[v ]
Kante
dieser Pfad bezeugt
parent
Invariante:
v
KIT Institut für Theoretische Informatik
21
Kante (u, v ) relaxieren
d[u] + c(u, v ) < d[v ]
d[v ] = ∞),
Falls
(vielleicht
setze
I
d[v ] := d[u] + c(u, v )
und
I parent[v ]
:= u
Invarianten bleiben erhalten!
Beobachtung:
d[v ]
kann sich mehrmals
ändern!
KIT Institut für Theoretische Informatik
22
Dijkstras Algorithmus: Pseudocode
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
Behauptung: Am Ende deniert
d
die optimalen Entfernungen
und parent die zugehörigen Wege
KIT Institut für Theoretische Informatik
23
Beispiel
2 3
2
b
c
a
2
9
s
10 5 1
8
0
e
f
4 d
7
10 0
2 3 5
7
2
a
b
c
2
9
s
10 5 1
8
0
e
f
4 d
6 0 6 7
2 3 5
2
a
b
c
2
9
s
10 5 1
8
0
e
f
4 d
7
10 0
7
2 3 5
2
a
c
b
2
9
s
10 5 1
8
0
f
e
4 d
6 0 6 7
2 3 5
7
2
a
c
b
2
9
s
10 5 1
8
0
d
e
f
4
10 0 6 7
2 3 5
7
2
a
b
c
2
9
s
10 5 1
8
0
f
d
e
4
6 0 6 7
KIT Institut für Theoretische Informatik
24
Korrektheit
Wir zeigen:
Annahme: alle Kosten nicht-negativ!
∀v ∈ V :
I
v
erreichbar
I
v
gescannt
=⇒ v
wird irgendwann gescannt
=⇒ µ(v ) = d[v ]
KIT Institut für Theoretische Informatik
25
v erreichbar =⇒ v wird irgendwann gescannt
Annahme:
v
ist erreichbar, aber wird nicht gescannt
gescannt
ungescannt
z
}|
{
z}|{
s = v1 −→ v2 −→ · · · −→ vi−1 −→ vi −→ · · · −→
{z
|
ein kürzester s v Pfad
=⇒ vi−1 wird gescannt
=⇒ Kante vi−1 −→ vi wird relaxiert
=⇒ d[vi ] < ∞
Widerspruch nur Knoten x mit d[x] = ∞
ungescannt
z }| {
vk = v
werden nie gescannt
}
?
KIT Institut für Theoretische Informatik
26
v erreichbar =⇒ v wird irgendwann gescannt
Annahme:
v
ist erreichbar, aber wird nicht gescannt
gescannt
ungescannt
z
}|
{
z}|{
s = v1 −→ v2 −→ · · · −→ vi−1 −→ vi −→ · · · −→
{z
|
ein kürzester s v Pfad
=⇒ vi−1 wird gescannt
=⇒ Kante vi−1 −→ vi wird relaxiert
=⇒ d[vi ] < ∞
Widerspruch nur Knoten x mit d[x] = ∞
Ups: Spezialfall
ungescannt
z }| {
vk = v
}
werden nie gescannt
i = 1?
Kann auch nicht sein.
v1 = s
wird nach Initialisierung gescannt.
KIT Institut für Theoretische Informatik
26
v gescannt =⇒ µ(v ) = d[v ]
Annahme:
OBdA:
t :=
v
v
gescannt und
µ(v ) < d[v ]
ist der erste gescannte Knoten mit
Scan-Zeit von
µ(v ) < d[v ].
v
Scan-Zeit ≥ t
Scan-Zeit = t
Scan-Zeit < t
z }| {
z}|{
}|
{
z
s = v1 −→ v2 −→ · · · −→ vi−1 −→ vi −→ · · · −→
vk = v
|
{z
}
ein kürzester s v Pfad
Also gilt zur Zeit
t:
µ(vi−1 ) = d[vi−1 ]
vi−1 → vi wurde relaxiert
z}|{
=⇒ d[vi ] ≤ d[vi−1 ] + c(vi−1 , vi ) = µ(vi ) ≤ µ(v )< d[v ]
=⇒ vi wird vor v gescannt. Widerspruch!
Wieder: Spezialfall
i =1
unmöglich.
KIT Institut für Theoretische Informatik
27
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
28
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
29
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
30
: 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
31
Beispiel
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
2 3 5
2
a
b
c
2
9
5
s
10
8
1
0
e
f
4 d
7
10 0
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
Operation
insert(s)
deleteMin
2
relax s → a
10
relax s → d
deleteMin
3
relax a → b
deleteMin
2
relax b → c
1
relax b → e
deleteMin
9
relax e → b
8
relax e → c
0
relax e → d
deleteMin
4
relax d → s
5
relax d → b
deleteMin
(s, 0)
(a, 2)
(b, 5)
(e, 6)
(d, 6)
(c, 7)
Queue
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
32
Herunterladen