Algorithmen und Datenstrukturen (für ET/IT)

Werbung
Algorithmen und Datenstrukturen (für ET/IT)
Sommersemester 2016
Dr. Tobias Lasser
Computer Aided Medical Procedures
Technische Universität München
Wdh: Traversierung von Binärbäumen
Sei G = (V , E ) Binärbaum.
In welcher Reihenfolge durchläuft man G ?
• Wurzel zuerst
• danach linker oder rechter Kind-Knoten l bzw. r ?
• falls l: danach Kind-Knoten von l oder zuerst r ?
• falls r : danach Kind-Knoten von r oder zuerst l?
w
l
r
! falls zuerst in die Tiefe: Depth-first search (DFS)
! falls zuerst in die Breite: Breadth-first search (BFS)
2
Wdh: Implementierung DFS Traversierung
Datenstruktur:
Knoten:
• Algorithmus preorder:
preorder(knoten):
if (knoten == null) return;
besuche(knoten);
preorder(knoten.links);
preorder(knoten.rechts);
links
Wert
rechts
• Algorithmus postorder:
postorder(knoten):
if (knoten == null) return;
postorder(knoten.links);
postorder(knoten.rechts);
besuche(knoten);
• Algorithmus inorder:
inorder(knoten):
if (knoten == null) return;
inorder(knoten.links);
besuche(knoten);
inorder(knoten.rechts);
• rekursive Algorithmen
• auf Call-Stack basiert
3
Wdh: Implementierung DFS Traversierung ohne Rekursion
• Datenstruktur:
Knoten:
links
Wert
rechts
besucht
• Hilfsmittel: Stack von Knoten “knotenStack”
postorderIterativ(wurzelKnoten):
knotenStack.push(wurzelKnoten);
while ( !knotenStack.isEmpty() ) {
knoten = knotenStack.top();
if ( (knoten.links != null) && (!knoten.links.besucht) )
knotenStack.push(knoten.links);
else if ( (knoten.rechts != null) && (!knoten.rechts.besucht) )
knotenStack.push(knoten.rechts);
else {
besuche(knoten);
knoten.besucht = true;
knotenStack.pop();
}
}
4
Wdh: Implementierung BFS Traversierung
• Datenstruktur:
Knoten:
links
Wert
rechts
• Hilfsmittel: Queue von Knoten “knotenQueue”
breitensuche(wurzelKnoten):
knotenQueue = leer;
knotenQueue.enqueue(wurzelKnoten);
while ( !knotenQueue.isEmpty() ) {
knoten = knotenQueue.dequeue();
besuche(knoten);
if (knoten.links != null)
knotenQueue.enqueue(knoten.links);
if (knoten.rechts != null)
knotenQueue.enqueue(knoten.rechts);
}
5
Wdh: Anwendung: Quadtree I
• 4-närer Baum heißt Quadtree
Quadtree
Bild
0
1
1
2
3
5
6
7
8
5
7
9
10
11
2
4
9
10
11 12
4
8
12
6
Wdh: Anwendung: Quadtree II
• Codierung des Baumes mit Binärzi↵ern
Quadtree
Bild
0
1
1
1
2
3
4
0
0
1
0
5
5
6
7
8
0
1
0
0
10
11
12
0
0
0
0
9
10
11 12
7
9
2
4
8
1001010000 0 00
7
Programm heute
7 Fortgeschrittene Datenstrukturen
8 Such-Algorithmen
9 Graph-Algorithmen
Tiefensuche
Breitensuche
8
Bild-Repräsentation mit Pixeln
• Bild als zwei-dimensionales Feld
• einzelnes Element: Pixel (picture element)
• hier: jedes Pixel hat einen Grauwert zugewiesen
• z.B. von 0 bis 255
9
Segmentierung von Bildern
• Segmentierung: Zusammenfassung von inhaltlich
zusammenhängenden Regionen gemäß eines Kriteriums
• Beispiel: Segmentierung von Knochen oder Organen
10
Binäre Bilder
• Binäres Bild: jedes Pixel hat entweder Wert 0 oder 1
0
0
0
0
0
0
0
0
0
0
0
0
1
0
0
0
0
0
0
0
0
1
1
1
0
0
0
1
0
0
1
1
1
1
1
0
1
1
1
0
0
1
1
1
0
0
0
1
0
0
0
0
1
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
• Segmentierungs-Problem: identifiziere die beiden “Sterne”
! Algorithmus?
11
Problem: Segmentierung von “Sternen”
0
0
0
0
0
0
0
0
0
0
0
0
1
0
0
0
0
0
0
0
0
1
1
1
0
0
0
1
0
0
1
1
1
1
1
0
1
1
1
0
0
1
1
1
0
0
0
1
0
0
0
0
1
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
• Gegeben: binäres Bild mit 0,1 Werten
• Gesucht: Regionen im Bild mit nur 1 Werten
• Ansatz:
• fange an bei Pixel mit Wert 1
• wiederhole: inspiziere unbesuchte Nachbar-Pixel auf Wert 1
• beende falls kein weiterer Nachbar mit Wert 1 existiert
12
Nachbarschaft von Pixeln
N
N
P
N
N
4-Nachbarschaft
N
N
N
N
P
N
N
N
N
8-Nachbarschaft
• 4-Nachbarschaft von Pixel P: alle direkten Nachbar-Pixel, die
Kante mit P gemeinsam haben
• auch genannt: Von-Neumann-Nachbarschaft
• 8-Nachbarschaft von Pixel P: alle direkten Nachbar-Pixel, die
Kante oder Ecke mit P gemeinsam haben
• auch genannt: Moore-Nachbarschaft
13
“Stern” als Graph
1
5
2
3
4
6
7
8
10
11
12
9
13
Segmentierungs-Ansatz von linkem “Stern”:
1
starte mit Pixel 1
2
besuche Nachbarn (Schema: oben, unten, links, rechts)
14
Segmentierungs-Durchlauf als Baum
1
1
5
3
2
3
4
6
7
8
10
11
12
7
11
9
13
10
12
6
8
13
2
5
4
9
Ansatz auch genannt: Tiefensuche bzw. Depth-First Search (DFS)
15
Tiefensuche (DFS)
Sei G = (V , E ) Graph (gerichtet oder ungerichtet).
• Graph repräsentiert mit Adjazenzliste adj
• jeder Knoten hat Farb-Markierung farbe:
• weiss = noch nicht besucht
• grau = besucht, gerade in Bearbeitung
• schwarz = besucht, fertig bearbeitet
• jeder Knoten hat Vorgänger in Besuch-Reihenfolge pred
• (optional) zusätzliche Knoten-Markierungen d und f
• Zeitmarke, wann Knoten entdeckt: d (discovered)
• Zeitmarke, wann Knoten fertig bearbeitet: f (finalized)
16
Algorithmus DFS
Input: Graph G = (V , E )
Output: Vorgänger-Liste pred,
Markierungen d, f
DFS(G ):
for each (Knoten v 2 V ) {
farbe[v ] = weiss;
pred[v ] = null;
}
zeit = 0;
for each (Knoten v 2 V ) {
if (farbe[v ] == weiss)
DFSvisit(v );
}
DFSvisit(v ):
farbe[v ] = grau; // v war weiss
zeit = zeit + 1;
d[v ] = zeit;
for each (Knoten u 2 adj[v ]) {
if (farbe[u] == weiss) {
pred[u] = v;
DFSvisit(u);
}
}
farbe[v ] = schwarz; // v ist fertig
zeit = zeit + 1;
f[v ] = zeit;
17
DFS: Beispiel-Ablauf 1
u
v
w
x
y
z
• Knoten u, v, w, x, y, z
• farbe direkt im Knoten markiert
• d/f im Knoten notiert
• pred markiert durch rote Kanten
18
DFS: Beispiel-Ablauf 2
u
v
w
u
1/_
v
1/_
w
u
2/_
v
1/_
w
2/_
3/_
x
y
u
v
1/_
z
x
w
u
2/_
y
v
1/_
z
x
w
u
2/_
y
v
1/_
B
4/_
3/_
x
y
u
v
1/_
x
w
u
2/_
v
1/_
4/5
z
x
w
u
2/7
3/6
y
x
3/6
y
x
w
2/7
B
4/5
z
z
v
F
4/5
z
3/_
y
1/_
B
4/5
x
3/_
y
B
w
2/_
B
4/_
z
z
3/6
y
z
19
DFS: Beispiel-Ablauf 3
u
v
1/_
F
F
z
v
1/8
4/5
u
z
v
1/8
F
F
3/6
y
z
10/
11
B
10/
_
9/_
C
B
4/5
x
w
2/7
3/6
y
z
10/
_
B
w
9/
12
2/7
C
B
4/5
x
z
v
1/8
C
4/5
y
u
9/_
F
3/6
z
v
1/8
C
B
3/6
y
u
9/_
9/_
B
x
w
2/7
x
w
2/7
B
v
4/5
y
z
w
2/7
4/5
y
F
3/6
x
F
1/8
C
B
v
1/8
3/6
u
9/_
u
B
x
w
2/7
w
2/7
4/5
y
u
v
1/8
3/6
x
F
u
B
4/5
x
w
2/7
3/6
y
z
10/
11
B
20
Spannwald mit DFS
Sei G = (V , E ) Graph.
• Spannbaum: Teilgraph G 0 = (V , E 0 ), der ein Baum ist und
alle Knoten von G enthält.
• existiert nur für zusammenhängende Graphen
• Spannwald: Teilgraph G 0 = (V , E 0 ), dessen
Zusammenhangskomponenten jeweils Spannbäume der
Zusammenhangskomponenten von G sind
21
Spannwald mit DFS
Sei G = (V , E ) Graph.
• Spannbaum: Teilgraph G 0 = (V , E 0 ), der ein Baum ist und
alle Knoten von G enthält.
• existiert nur für zusammenhängende Graphen
• Spannwald: Teilgraph G 0 = (V , E 0 ), dessen
Zusammenhangskomponenten jeweils Spannbäume der
Zusammenhangskomponenten von G sind
• DFS erzeugt Spannwald
• Knoten sind V , Kanten E 0 ergeben sich aus pred
• im Beispiel-Ablauf: Knoten V sind schwarz, Kanten E 0 sind rot
• DFS erlaubt Markierung spezieller Kanten:
• Rückkanten im Spannwald (markiert mit B)
• Vorwärtskanten im Spannwald (markiert mit F)
• Cross-Kanten im Spannnwald (markiert mit C)
21
Komplexität von DFS
• DFS erste Schleife wird |V | mal durchlaufen: ⇥(|V |)
• DFSvisit wird für jeden Knoten genau einmal aufgerufen
(zweite Schleife in DFS, rekursiver Aufruf in DFSvisit)
• innere Schleife in DFSvisit wird |adj(v )| mal aufgerufen
X
v 2V
|adj(v )| = ⇥(|E |)
• Gesamtlaufzeit: ⇥(|V | + |E |)
• Implementierung gleicher Komplexität auch nicht-rekursiv
möglich (mit Stack)
22
Anwendungen von DFS
• Test auf Zusammenhang von Graphen
• rufe DFSvisit nur für einen Knoten auf (statt für alle)
• falls nicht alle Knoten dadurch besucht: nicht
zusammenhängend!
• Test auf Zyklenfreiheit in Graphen
• Zyklus entdeckt falls Rückkante B gefunden
• Rückkante B: in DFSvisit Schleife ist Zielknoten bereits grau
23
Beispiel DFS 1
2/_
1/_
1/_
2/_
1/_
2/_
3/_
2/_
1/_
1/_
4/5
3/_
4/_
3/_
2/_
1/_
4/5
3/6
24
Beispiel DFS 2
2/_
4/5
1/_
3/6
2/_
F
1/_
4/5
3/6
8/_
2/7
F
1/_
4/5
3/6
2/7
1/_
9/_
10/
_
8/_
2/7
4/5
3/6
9/_
8/_
1/_
F
F
4/5
3/6
2/7
1/_
F
4/5
3/6
25
Beispiel DFS 3
9/_
9/_
10/
_
8/_
2/7
1/_
4/5
3/6
1/_
10/
_
F
2/7
1/_
C
4/5
B
10/
11
F
2/7
1/_
9/
12
1/_
3/6
8/_
3/6
C
4/5
3/6
9/
12
B
2/7
4/5
9/_
B
8/_
10/
_
F
2/7
9/_
8/_
B
8/_
F
10/
11
F
3/6
B
8/
13
C
4/5
2/7
1/_
10/
11
F
C
4/5
3/6
26
Beispiel DFS 4
9/
12
9/
12
B
8/
13
10/
11
F
2/7
1/_
2/7
15/
_
B
1/
14
4/5
2/7
10/
11
F
16/
17
C
3/6
F
16/
_
C
2/7
1/
14
15/
_
B
8/
13
4/5
4/5
3/6
9/
12
15/
_
B
10/
11
1/
14
9/
12
8/
13
15/
_
B
2/7
3/6
4/5
3/6
8/
13
C
C
9/
12
10/
11
F
2/7
10/
11
F
1/
14
9/
12
1/
14
4/5
3/6
8/
13
B
8/
13
C
10/
11
F
16/
17
C
3/6
4/5
18/
_
27
Beispiel DFS 5
9/
12
15/
_
B
8/
13
10/
11
F
2/7
1/
14
16/
17
C
2/7
1/
14
15/
_
B
C
3/6
16/
17
C
16/
17
8/
13
18/
19
1/
14
4/5
C
18/
_
15/
20
B
2/7
C
4/5
3/6
9/
12
10/
11
F
10/
11
F
2/7
3/6
8/
13
15/
_
B
8/
13
4/5
18/
_
9/
12
1/
14
9/
12
10/
11
F
16/
17
C
3/6
4/5
C
18/
19
28
Programm heute
7 Fortgeschrittene Datenstrukturen
8 Such-Algorithmen
9 Graph-Algorithmen
Tiefensuche
Breitensuche
29
Breitensuche im “Stern”-Beispiel
• Segmentierung von “Sternen”
0
0
0
0
0
0
0
0
0
0
0
0
1
0
0
0
0
0
0
0
0
1
1
1
0
0
0
1
0
0
1
1
1
1
1
0
1
1
1
0
0
1
1
1
0
0
0
1
0
0
0
0
1
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
• neuer Ansatz:
• anstatt direkt nächsten Nachbar ansteuern, erst alle aktuellen
Nachbarn abarbeiten
! Breitensuche
30
Breitensuche im “Stern”-Beispiel: Ablauf
1
5
2
3
4
6
7
8
10
11
12
9
13
1
starte mit Pixel 1
2
besuche alle Nachbarn von aktuellem Pixel (Schema: oben,
unten, links, rechts)
3
arbeite die Nachbarn der Nachbarn in selber Reihenfolge ab
31
Breitensuche im “Stern”-Beispiel: als Baum
1
1
5
3
2
3
4
6
7
8
10
11
12
7
9
11
13
10
12
2
6
8
5
9
4
13
Ansatz: Breitensuche bzw. Breadth-First Search (BFS)
32
Breitensuche (BFS)
Sei G = (V , E ) zusammenhängender Graph (gerichtet oder
ungerichtet).
• Startknoten s 2 V
• Graph repräsentiert mit Adjazenzliste adj
• jeder Knoten hat Farb-Markierung farbe:
• weiss = noch nicht besucht
• grau = besucht, gerade in Bearbeitung
• schwarz = besucht, fertig bearbeitet
• jeder Knoten hat Vorgänger in Besuch-Reihenfolge pred
• (optional) zusätzliche Knoten-Markierung d
• Distanz (in Anzahl von Kanten) von Startknoten s
• Hilfsmittel: Queue Q
33
Algorithmus BFS
Input: Graph G = (V , E ), Startknoten s 2 V
Output: Vorgänger-Liste pred, Markierung d
BFS(G , s):
for each (Knoten v 2 V ) { // Initialisierung
farbe[v ] = weiss; pred[v ] = null; d[v ] = 1;
}
farbe[s] = grau; d[s] = 0;
Q = initialize(); Q.enqueue(s);
while ( !Q.isEmpty() ) {
u = Q.dequeue();
for each (v 2 adj[u]) { // besuche alle Nachbarn
if (farbe[v ] == weiss) {
farbe[v ] = grau; d[v ] = d[u] + 1; pred[v ] = u;
Q.enqueue(v );
}
}
farbe[u] = schwarz; // u ist erledigt
}
34
BFS: Beispiel-Ablauf 1
r
s
t
u
v
w
x
y
• Knoten r, s, t, u, v, w, x, y
• farbe direkt im Knoten markiert
• d im Knoten notiert
• pred markiert durch rote Kanten
• Startknoten s
35
BFS: Beispiel-Ablauf 2
r
s
∞
t
0
u
∞
r
∞
Q:
∞
v
∞
w
r
s
1
∞
x
∞
∞
v
u
2
∞
v
1
w
r
s
1
2
x
v
1
w
2
v
y
v
2
x
v
Q:
v
u
y
∞
t
u
0
2
3
2
1
2
3
x
t
y
1
w
Q:
∞
u
∞
r
u
x
s
w
∞
2
1
w
r
3
x
t
0
Q:
y
x
u
2
x
t
v
Q:
2
r
∞
2
∞
∞
x
s
1
y
t
0
u
∞
1
w
r
∞
Q:
t
0
s
y
t
0
s
1
y
36
BFS: Beispiel-Ablauf 3
r
s
1
t
0
u
2
r
3
Q:
2
v
1
w
r
s
1
2
x
2
2
1
w
r
3
2
x
s
1
t
0
u
y
3
y
u
2
3
y
Q:
3
y
u
2
Q:
3
2
x
t
0
y
v
u
2
1
w
u
3
Q:
v
v
y
t
0
s
1
2
v
1
w
2
x
3
y
37
BFS Eigenschaften
Sei G = (V , E ) Graph.
• BFS erzeugt Spannbaum G 0 = (V , E 0 )
• Knoten sind V , Kanten E 0 ergeben sich aus pred
• im Beispiel-Ablauf: Knoten V sind schwarz, Kanten E 0 sind rot
• ausgehend von Startknoten s wird nur
Zusammenhangskomponente von Graph durchsucht!
• falls G nicht zusammenhängend, wird kein Spannwald
berechnet!
• falls Stack statt Queue in BFS: DFS-artiger Algorithmus
• Unterschied: nur in Zusammenhangskomponente
38
Komplexität von BFS
• BFS erste Schleife (for) wird |V | mal durchlaufen: ⇥(|V |)
• zweite geschachtelte Schleife (while und for) wird im
schlechtesten Fall je einmal für jeden Knoten in Adjazenzliste
aufgerufen
X
|adj(v )| = ⇥(|E |)
v 2V
• Gesamtlaufzeit: ⇥(|V | + |E |)
39
Anwendungen von BFS
• Besuche alle Knoten in Zusammenhangskomponente von
Graph
• ausgehend von Startknoten s
• Berechne Länge der kürzesten Pfade (d.h. Anzahl von
Kanten)
• ausgehend von Startknoten s
• kürzeste Pfade selbst erfordern Modifikation des Algorithmus
40
Zusammenfassung
7 Fortgeschrittene Datenstrukturen
8 Such-Algorithmen
9 Graph-Algorithmen
Tiefensuche
Breitensuche
41
Herunterladen