zu Graphenrepräsentation, Breitensuche

Transcription

zu Graphenrepräsentation, Breitensuche
Customization (Zuschneiden)
Anpassen der (Graph)Datenstruktur an die Anwendung.
I
Ziel: schnell, kompakt.
I
benutze Entwurfsprinzip: make the common case fast
I
Listen vermeiden
Mögliches Problem: Software-Engineering-Alptraum
Möglicher Ausweg: Trennung von Algorithmus und Repräsentation
317
Beispiel: DAG-Erkennung
Vgl. Folie 73ff. (dort aber Test auf Ausgangsgrad)!
Function isDAG(G = (V , E ))
// Adjazenzarray!
dropped:= 0
compute array inDegree of indegrees of all nodes
// Zeit O(m)!
droppable={v 2 V : inDegree[v ] = 0} : Stack
while droppable 6= 0/ do
invariant G is a DAG iff the input graph is a DAG
v := droppable.pop
dropped++
foreach edge (v , w ) 2 E do
inDegree[w ]
if inDegree[w ] = 0 then droppable.push(w )
return |V | = dropped
Laufzeit: O(m + n) (auch ohne dynamische Graphdatenstruktur!)
318
Adjazenz-Matrix
A 2 {0, 1}n⇥n with A(i, j) = [(i, j) 2 E ]
+ platzeffizient für sehr dichte Graphen
platzineffizient sonst.
Übung: was bedeutet “sehr dicht” hier?
+ einfache Kantenanfragen
langsame Navigation
++ verbindet lineare Algebra und
Graphentheorie
Beispiel: C = Ak .
Cij =# k-Kanten-Pfade von i nach j
Wichtige Beschleunigungstechniken:
2
1
0
0
B 0
B
@ 0
0
4
3
1
0
1
0
1
1
0
0
I
O(log k) Matrixmult. für Potenzberechnung
I
Matrixmultiplikation in subkubischer Zeit, z. B., Strassens
Algorithmus
1
0
1 C
C
1 A
0
319
Pfade zählen mittels LA
Adjanzenzmatrix:
A 2 {0, 1}n⇥n mit A(i, j) = [(i, j) 2 E ]
Sei C := Ak .
Behauptung: Cij =# k-Kanten-Pfade von i
nach j.
Beweis: IA (k = 1) C = A1 = A stimmt nach
Definition von A.
Schluss k
k + 1: Cij = (Ak A)ij = Â Aki` A`j
2
1
4
`
Aki` =#k-Kanten-Pfade von i nach ` (nach IV).
Aki` A`j =#k + 1-Kanten-Pfade von i nach j
mit (`, j) als letzter Kante.
Jede mögliche letzte Kante wird genau einmal
gezählt.
Übung: zähle Pfade der Länge  k
3
0
0
B 0
B
@ 0
0
1
0
1
0
1
1
0
0
1
0
1 C
C
1 A
0
320
Beispiel, wo Graphentheorie bei LA hilft
Problemstellung: löse Bx = c
Sei G = (1..n, E = {{i, j} : Bij 6= 0})
Nehmen wir an, G habe zwei Zusammenhangskomponenten
) tausche Zeilen und Spalten derart, dass
✓
◆✓
◆ ✓
◆
B1 0
x1
c1
=
0 B2
x2
c2
zu lösen bleibt.
Übung: Was passiert, wenn (1..n, E = {(i, j) : Bij 6= 0}) ein DAG ist?
321
Implizite Repräsentation
Kompakte Repräsentation möglicherweise sehr dichter Graphen
Implementiere Algorithmen direkt mittels dieser Repräsentation
Beispiel: Intervall-Graphen
Knoten: Intervalle [a, b] ✓ R
Kanten: zwischen überlappenden Intervallen
322
Zusammenhangstest für Intervallgraphen
V = {[a1 , b1 ], . . . , [an , bn ]}
E = {{[ai , bi ], [aj , bj ]} : [ai , bi ] \ [aj , bj ] 6= 0}
/
Idee: durchlaufe Intervalle von links nach rechts.
Die Anzahl überlappender Intervalle darf nie auf null sinken.
Annahme: Startpunkte in Sortierung vor Endpunkten!
Function isConnected(L : SortedListOfIntervalEndPoints) : {0, 1}
remove first element of L; overlap := 1
foreach p 2 L do
if overlap= 0 return false
if p is a start point then overlap++
else overlap
// end point
return true
O(n log n) Algorithmus für bis zu O n2 Kanten!
Übung: Zusammenhangskomponenten finden
323
Beispiel
Function isConnected(L : SortedListOfIntervalEndPoints) : {0, 1}
remove first element of L; overlap := 1
foreach p 2 L do
if overlap= 0 return false
if p is a start point then overlap++
else overlap
return true
// end point
324
Graphrepräsentation: Zusammenfassung
I
Welche Operationen werden gebraucht?
I
Wie oft?
I
Adjazenzarrays gut für statische Graphen
I
Pointer
I
Matrizen eher konzeptionell interessant
flexibler, aber auch teurer
325
Kap. 9: Graphtraversierung
Ausgangspunkt oder Baustein fast jedes nichttrivialen Graphenalgorithmus
326
Graphtraversierung als Kantenklassifizierung
forward
s
tree
backward
cross
327
Breitensuche
Baue Baum von Startknoten s,
der alle von s erreichbaren Knoten
mit möglichst kurzen Pfaden erreicht.
Berechne Abstände:
b
s
0
e
g
c
d
f
1
2
tree
backward
cross
forward
3
328
Breitensuche
I
Einfachste Form des Kürzeste-Wege-Problems
I
Umgebung eines Knotens definieren
(ggf. begrenzte Suchtiefe)
I
Einfache, effiziente Graphtraversierung
(auch wenn Reihenfolge egal)
b
s
0
e
g
c
d
f
1
2
tree
backward
cross
forward
3
329
Breitensuche
Algorithmenidee: Baum Schicht für Schicht aufbauen
b
s
0
e
g
c
d
f
1
2
tree
backward
cross
forward
3
330
Function bfs(s) :
Q:= hsi
// aktuelle Schicht
while Q 6= hi do
exploriere Knoten in Q
merke dir Knoten der nächsten Schicht in Q 0
Q:= Q 0
b
s
0
e
g
c
d
f
1
2
tree
backward
cross
forward
3
331