Kapitel 6: Graphen

Werbung
Grundlagen Datenstrukturen Transitive Hülle Traversierung Kürzeste Wege Spannender Baum Max. Fluss Zuordnungen
6. Graphen
• viele praktische (Optimierungs-)Probleme sind als
graphentheoretische Probleme formulierbar
• z.B. in Produktionsplanung, Personaleinsatzplanung, . . .
6.1 Grundlagen
• gerichteter, ungerichteter und gewichteter Graph
158
Grundlagen Datenstrukturen Transitive Hülle Traversierung Kürzeste Wege Spannender Baum Max. Fluss Zuordnungen
Gerichteter Graph
Definition: gerichteter Graph G = (V , E) mit:
V = {v0 , . . . , vn−1 }
Knotenmenge
E ⊂V ×V
Kantenmenge (im folgenden: m =| E |)
• Graphen werden meist graphisch dargestellt
Beispiel:
G1 = ({v0 , v1 , v2 , v3 }, {(v0 , v2 ), (v1 , v2 ), (v2 , v1 ), (v2 , v3 )})
v0
v1
v2
v3
159
Grundlagen Datenstrukturen Transitive Hülle Traversierung Kürzeste Wege Spannender Baum Max. Fluss Zuordnungen
Ungerichteter Graph
Definition: ungerichteter Graph G = (V , E) mit:
V = {v0 , . . . , vn−1 }
Knotenmenge
E ⊂ {{v , v 0 } | v , v 0 ∈ V }
Kantenmenge
Beispiel:
G2 = ({v0 , v1 , v2 , v3 }, {{v0 , v2 }, {v1 , v2 }, {v2 , v3 }})
v0
v1
v2
v3
• im folgenden werden gerichtete Graphen betrachtet,
sofern nicht explizit anders hervorgehoben
160
Grundlagen Datenstrukturen Transitive Hülle Traversierung Kürzeste Wege Spannender Baum Max. Fluss Zuordnungen
Gewichteter Graph
Definition: gewichteter Graph G = (V , E, β) mit:
Knotenmenge V
Kantenmenge E
β : E−→IR
(Kanten-)Gewichtsfunktion
Beispiel:
G3 = ({v0 , v1 , v2 , v3 }, {(v0 , v2 ), (v1 , v2 ), (v2 , v1 ), (v2 , v3 )}, β)
mit β(v0 , v2 ) = 2, β(v1 , v2 ) = 5, β(v2 , v1 ) = 3, β(v2 , v3 ) = 2
v0
2
v2
v1
5
3
2
v3
161
Grundlagen Datenstrukturen Transitive Hülle Traversierung Kürzeste Wege Spannender Baum Max. Fluss Zuordnungen
6.2 Datenstrukturen für Graphen
6.2.1 Adjazenzmatrix
sei G = (V , E) ein Graph
Definition: Adjazenzmatrix AG ist n × n-Matrix mit

 1, falls (vi , vj ) ∈ E und 0 ≤ i, j < n (bzw. {vi , vj } ∈ E)
ai,j =

0, sonst
Beispiel:
v0

v1
AG1
G1 :
v2
v3

0
0
1
0

 0
= 
 0

0
0
1
1
0
0
0

0 

1 

0
• Platzbedarf: O(n2 )
162
Grundlagen Datenstrukturen Transitive Hülle Traversierung Kürzeste Wege Spannender Baum Max. Fluss Zuordnungen
6.2.2 Adjazenzlisten
• Array (oder sonstige Kollektion) von Knoten
• für jeden Knoten: Liste mit Verweisen auf Nachfolgeknoten
Beispiel:
0
v0
v2
2
3
-
-
G1 :
1
v1
v3
2
-
2
1
-
3
• Kantengewichte leicht ergänzbar
• Platzbedarf: O(n + m)
163
Grundlagen Datenstrukturen Transitive Hülle Traversierung Kürzeste Wege Spannender Baum Max. Fluss Zuordnungen
6.2.3 Distanzmatrix
sei G = (V , E, β) ein gewichteter Graph
Definition: Distanzmatrix DG ist n × n-Matrix mit

 β(vi , vj ), falls (vi , vj ) ∈ E und 0 ≤ i, j < n (bzw. {vi , vj } ∈ E)
di,j =
 ∞,
sonst
Beispiel:
v0
2
G3 :

v1
5
v2
DG3
3
2
v3
∞


 ∞ ∞ 5 ∞

= 
 ∞ 3 ∞ 2

∞ ∞ ∞ ∞






∞ ∞
2
• Platzbedarf: O(n2 )
164
Grundlagen Datenstrukturen Transitive Hülle Traversierung Kürzeste Wege Spannender Baum Max. Fluss Zuordnungen
6.3 Transitive Hülle
• gegeben: G = (V , E)
• gesucht: (reflexive,) transitive Hülle G∗ = (V , E ∗ ) mit:
• (v , v ) ∈ E ∗
0
∀v ∈ V
∗
• (v , v ) ∈ E , (v 0 , v 00 ) ∈ E ⇒ (v , v 00 ) ∈ E ∗
∀v , v 0 , v 00 ∈ V
• sonst keine Kanten in E ∗
Beispiel:
G1∗ =
G1 =
(V , E):
v0
v1
v0
v1
v2
v3
v2
v3
(V , E ∗ ):
165
Grundlagen Datenstrukturen Transitive Hülle Traversierung Kürzeste Wege Spannender Baum Max. Fluss Zuordnungen
Transitive Hülle (Warshall-Algorithmus)
• gegeben: Adjazenzmatrix AG von G = (V , E)
public static void huelle(byte[][] A){
int n = A.length;
for(int i=0; i<n; i++)
A[i][i] = 1;
for(int j=0; j<n; j++)
for(int i=0; i<n; i++)
// Schleifenreihenfolge
// wichtig!
if (A[i][j] == 1)
for(int k=0; k<n; k++)
if (A[j][k] == 1)
A[i][k] = 1;}
• Iteration j berücksichtigt alle Verbindungen mit Zwischenstationen ≤ j
rth
• Aufwand: tW
(n, m) ∈ O(n2 + | E ∗ | ·n))
166
Grundlagen Datenstrukturen Transitive Hülle Traversierung Kürzeste Wege Spannender Baum Max. Fluss Zuordnungen
6.4 Traversierung von Graphen
6.4.1 Tiefensuche
• an jedem Knoten:
• zuerst die Nachfolger rekursiv betrachten
• dann die “Geschwister”
Beispiel:
G4:
v0
v1
v4
v2
v3
v5
• Durchlaufreihenfolge: v0 , v2 , v1 , v4 , v3 , v5
dfs (n, m) ∈ O(n + m) (bei Adjazenzlisten)
• Aufwand: tW
167
Grundlagen Datenstrukturen Transitive Hülle Traversierung Kürzeste Wege Spannender Baum Max. Fluss Zuordnungen
6.4.2 Breitensuche
• alle Knoten mit Abstand i vom Ausgangsknoten
werden vor denen mit Abstand i + 1 besucht (i = 0, 1, 2, . . .)
• hierzu: Knotenqueue (FIFO)
Beispiel:
G4:
v0
v1
v4
v2
v3
v5
• Durchlaufreihenfolge: v0 , v2 , v1 , v3 , v4 , v5
bfs (n, m) ∈ O(n + m) (bei Adjazenzlisten)
• Aufwand: tW
168
Grundlagen Datenstrukturen Transitive Hülle Traversierung Kürzeste Wege Spannender Baum Max. Fluss Zuordnungen
6.5 Kürzeste Wege
6.5.1 Kürzeste Wege von einem Ausgangsknoten
• sei G = (V , E, β) mit β : E−→IR+
Algorithmus von Dijkstra (grober Pseudocode)
drei Knotenmengen: F (fertig), R (Rand), U (unerreicht)
anfangs:
F = {v0 }; R = Nachbarn(v0 ); U = V − F − R
bis F == V
(*) bestimme v ∈ R mit d(v0 , v ) ≤ d(v0 , v 0 ) ∀v 0 ∈ R
F = F ∪ {v }
R = R ∪ (Nachbarn(v ) − F ) − {v }
U =U −R
169
Grundlagen Datenstrukturen Transitive Hülle Traversierung Kürzeste Wege Spannender Baum Max. Fluss Zuordnungen
Aufwand des Algorithmus von Dijkstra
• abhängig von der Implementierung der Knotenauswahl (*):
1) durchlaufe alle Knoten: → Aufwand O(n2 ) (Original)
2) mit Knoten-Heap: → Aufwand O(m · log n)
3) mit Knoten-Fibonacci-Heap (s. Ottmann/Widmayer):
Aufwand O(m + n · log n)
170
Grundlagen Datenstrukturen Transitive Hülle Traversierung Kürzeste Wege Spannender Baum Max. Fluss Zuordnungen
Beispiel: Algorithmus von Dijkstra
v1
5
2
3
2
v2
0
v0
6
v2
0
v0
6
v1
3
v2
2
3
1
3
v2
0
v0
v1
5
2
2
6
3
v2
2
1
v4
2
v3
2
5
3
4
5
1
v4
2
v3
3
6
4
5
1
v4
2
v3
7
4
3
2
v4
v1
5
2
5
2
v3
2
5
2
v4
6
v0
0
1
2
v1
3
2
6
v3
2
5
2
2
6
v0
0
3
4
6
171
Grundlagen Datenstrukturen Transitive Hülle Traversierung Kürzeste Wege Spannender Baum Max. Fluss Zuordnungen
6.5.2 Alle Paare kürzester Wege
Ansatz 1: n-mal Dijkstra-Algorithmus
• Aufwand: O(n3 ) bzw. O(n · m · log n) (mit Heap)
Ansatz 2: Floyd-Algorithmus
• Variante des Warshall-Algorithmus basierend auf Distanzmatrix
• . . . A[i][k] = min(A[i][k], A[i][j]+A[j][k]) . . .
• Aufwand: O(n2 + | E ∗ | ·n)
172
Grundlagen Datenstrukturen Transitive Hülle Traversierung Kürzeste Wege Spannender Baum Max. Fluss Zuordnungen
Ansatz 3: (+,min)-Multiplikationen
geg.: Distanzmatrix D
M = D;
for(int i=0; i <= log2 n; i++)
M = M ⊕ M;
wobei ⊕: (+,min)-Matrixmultiplikation, d.h. min statt +, + statt ·
• Aufwand: O(n3 · log n)
• verbesserbar auf: O(n2.81 · log n) mit Strassen-Verfahren
173
Grundlagen Datenstrukturen Transitive Hülle Traversierung Kürzeste Wege Spannender Baum Max. Fluss Zuordnungen
6.6 Minimaler Spannender Baum
• gegeben: ungerichteter, gewichteter Graph G = (V , E, β)
• gesucht: Baum B = (V , E 0 , β 0 ) mit E 0 ⊂ E, β 0 = β |E 0 und
P
β(e) minimal
e∈E 0
Algorithmus von Kruskal (Pseudocode)
E0 = ∅
while B noch kein Baum do
wähle e ∈ E − E 0 mit kleinstem β(e)
und so dass B = (V , E 0 ∪ {e}) “kreisfrei”
E 0 = E 0 ∪ {e}
• Aufwand: O(m · log n) mit “union-find-Struktur”
(s. z.B. Ottmann/Widmayer)
174
Grundlagen Datenstrukturen Transitive Hülle Traversierung Kürzeste Wege Spannender Baum Max. Fluss Zuordnungen
Beispiel: Algorithmus von Kruskal
6
v0
v1
2
v4
2
3
2
6
v0
v3
v1
2
1
3
3
v2
2
6
v0
1
v4
2
v3
v1
3
1
2
2
2
v4
2
3
v2
v1
2
2
v2
6
v0
1
2
v3
3
2
v4
2
3
v2
2
v3
3
175
Grundlagen Datenstrukturen Transitive Hülle Traversierung Kürzeste Wege Spannender Baum Max. Fluss Zuordnungen
Algorithmus von Jarník/Prim/Dijkstra
• analog zu Dijkstra-Algorithmus (s.o)
• jedoch wird für jeden Randknoten der Abstand zum fertigen Baum
vermerkt (nicht zum Anfangsknoten)
Beispiel:
6
v0
v1
6
2
v4
2
3
v2
2
6
v0
3
v3
v1
v4
2
3
v2
2
2
6
v0
1
6
v0
1
v1
2
1
2
2
3
2
v3
v1
2
v2
2
v4
2
3
3
2
v3
3
3
1
2
2
v4
2
3
v2
v1
2
2
2
6
v0
1
2
v3
3
1
2
v4
2
3
v2
2
v3
3
• Aufwand: O(m + n log n) (mit Fibonacci-Heap)
176
Grundlagen Datenstrukturen Transitive Hülle Traversierung Kürzeste Wege Spannender Baum Max. Fluss Zuordnungen
6.7 Maximaler Fluss
• gegeben: gewichteter Graph G = (V , E, β) mit
β : E−→IR+
Kantenkapazität
q∈V
Quelle
s∈V
Senke
• gesucht: maximaler Fluss f : E−→IR+ von q nach s
d.h.
max (
P
f :E−→IR+ (q,v )∈E
f (q, v ) −
(v 0 ,q)∈E
* f (e) ≤ β(e) ∀e ∈ E
P
P
*
f (v 0 , v )−
(v 0 ,v )∈E
f (v 0 , q)) mit:
P
Kapazitätsrestriktion
00
f (v , v ) = 0 ∀v ∈ V −{q, s} Flusserhaltung
(v ,v 00 )∈E
177
Grundlagen Datenstrukturen Transitive Hülle Traversierung Kürzeste Wege Spannender Baum Max. Fluss Zuordnungen
Beispiel: Fluss
3/ 2
v0
4/ 4
v1
1/ 0 3/ 2
q
4/ 3
v2
3/ 3
s
1/ 1
3/ 2
1/ 1
v3
5/ 4
Definition:
• ein zunehmender Weg w von q nach s mit Kapazität k ist eine
• Kantenfolge ( v00 , v10 ), (v10 , v20 ), . . . , (vr0−1 , vr0 ) mit
|{z}
|{z}
=s
=q
0
0
0
• f (vi0 , vi+1
) + k ≤ β(vi0 , vi+1
), falls (vi0 , vi+1
)∈E
•
0
f (vi+1
, vi0 )
− k ≥ 0,
(für i = 0, . . . r − 1)
falls
0
(vi+1
, vi0 )
oder
∈E
178
Grundlagen Datenstrukturen Transitive Hülle Traversierung Kürzeste Wege Spannender Baum Max. Fluss Zuordnungen
Beispiel: Flusserhöhung
4/ 4
3/ 2
v0
1/ 0 3/ 2
q
4/ 3
v2
v1
s
1/ 1
3/ 2
1/ 1
v3
4/ 4
3/ 3
5/ 4
3/ 1
v0
1/ 0 3/ 3
q
4/ 4
v2
v1
3/ 3
s
1/ 1
3/ 3
1/ 1
v3
5/ 5
• Fluss f 0 nach Addition des zunehmenden Weges w: (für i = 0, . . . r − 1)
0
0
f 0 (vi0 , vi+1
) := f (vi0 , vi+1
) + k,
0
falls (vi0 , vi+1
)∈E
0
0
und f (vi0 , vi+1
) + k ≤ β(vi0 , vi+1
)
0
0
f 0 (vi+1
, vi0 ) := f (vi+1
, vi0 ) − k ,
sonst
179
Grundlagen Datenstrukturen Transitive Hülle Traversierung Kürzeste Wege Spannender Baum Max. Fluss Zuordnungen
Algorithmus von Ford/Fulkerson
für alle e ∈ E: f (e) = 0;
while ∃ zunehmenden Weg w von q nach s do
sei k die (max.) Kapazität von w
erhöhe f entlang w um k
• zur Implementierung: speichere f (e) für jede Kante e
• bei naiver Wahl von w ist weder die Termination noch die Korrektheit
garantiert
Aufwand im schlechtesten Fall:
• abhängig vom Vorgehen bei der Bestimmung des zunehmenden Weges
1) wenn w mit maximaler Kapazität: O(m · log βmax )
2) wenn w mit minimaler Kantenanzahl: O(n · m2 )
(Algorithmus von Edmonds/Karp (Breitensuche))
180
Grundlagen Datenstrukturen Transitive Hülle Traversierung Kürzeste Wege Spannender Baum Max. Fluss Zuordnungen
Andere Maximal-Fluss-Algorithmen
• Algorithmus von Dinic: O(n2 · m) verbessert Alg. v. Edmonds/Karp;
alle kürzesten Wege werden gleichzeitig berücksichtigt
• Algorithmus von Karsanow/Tarjan: O(n3 )
• Algorithmus von Sleator/Tarjan: O(n · m · log n)
• Details siehe Ottmann/Widmayer
Bemerkungen:
• maximaler Fluss entspricht “minimalem Schnitt”
• ein Fluss f ist maximal, wenn es keinen zunehmenden Weg gibt
181
Grundlagen Datenstrukturen Transitive Hülle Traversierung Kürzeste Wege Spannender Baum Max. Fluss Zuordnungen
5.8 Zuordnungen
Definition: (Zuordnung)
• sei G = (V , E) ein Graph; E 0 ⊂ E heißt Zuordnung (Matching), wenn
∀(v , v 0 ) ∈ E 0 6 ∃v 00 ∈ V − {v , v 0 }
{(v 00 , v ), (v 00 , v 0 ), (v , v 00 ), (v 0 , v 00 )} ∩ E 0 6= ∅
182
Grundlagen Datenstrukturen Transitive Hülle Traversierung Kürzeste Wege Spannender Baum Max. Fluss Zuordnungen
Bipartite Graphen
Definition: (bipartiter Graph)
• sei G = (V , E) ein Graph mit V = V1 ∪ V2 und V1 ∩ V2 = ∅
• G heißt bipartit, wenn E ⊂ V1 × V2 ∪ V2 ∩ V1
Bestimmung einer maximalen Zuordnung
• die Bestimmung einer (bzgl. | E 0 |) maximalen Zuordnung in einem
bipartiten Graphen lässt sich auf das Maximal-Fluss-Problem
zurückführen
• hierzu werden Knoten q und s ergänzt und q mit allen Knoten von V1
und s mit allen Knoten von V2 verbunden
• das Gewicht jeder Kante ist 1
183
Grundlagen Datenstrukturen Transitive Hülle Traversierung Kürzeste Wege Spannender Baum Max. Fluss Zuordnungen
Beispiel: Bestimmung einer maximalen Zuordnung
1
Adam
1
Anna
1
1
1
Bernd
1
Christian
q
1
Birgit
1
1
s
Chantal
1
1
1
1
Dieter
1
Doris
1
zunehmende Wege:
1) q→A1 →A2 →s
2) q→B1 →C2 →s
3) q→D1 →D2 →s
4) q→C1 →C2 ← B1 →A2 ← A1 →B2 →q
184
Herunterladen