Tiefensuche (Depth

Werbung
Tiefensuche
(Depth-First Search)
Robert Hilbrich
[email protected]
1
Gliederung
1. Einführung
2. Tiefensuche, der Algorithmus
2.1 Modellierung der Arbeitsumgebung
2.2 Programmablauf
3. Korrektheit
3.1 Partielle Korrektheit
3.2 Totale Korrektheit
4. Einordnung der Tiefensuche
2
1. Einführung
Adventure: „Indiana Jones and the Fate of Atlantis“
(Fiktive)
Spielsituation:
• Indy gerät in ein Labyrinth
• sucht Ausgang (z.B. Sophia)
• Verfügbare Gegenstände:
• Peitsche
• Revolver
• (beliebig lange) rote Schnur
Wie geht Indy möglichst
systematisch vor?
3
1. Einführung
„Indiana Jones And The Fate of Atlantis“
systematische Vorgehensweise:
• roten Faden spannen à
bereits „gesehene“ Wege
markieren
• Wenn „Sackgasse“ à
zurück zur letzten
„ungesehenen“ Gabelung
è Vermeidung „doppelter“
Wege
4
1. Einführung
Heutige Bedeutung in der Informatik
abstrakt:
• bekanntes Suchverfahren für Graphenprobleme
z.B.:
• Ist der Graph verbunden?
• Wenn nicht, was sind die Zusammenhangskomponenten?
• Existiert ein Kreisschluss im Graphen?
konkret:
• Routenplaner
• Roboter Steuerungslogik
• Spiele – Logik
• Prolog
5
2. Tiefensuche, der Algorithmus
6
2.1 Modellierung der Arbeitsumgebung
Tiefensuche arbeitet mit Graphen
•
•
Sei ein (ungerichteter) Graph G mit V Knoten und E
Kanten gegeben
alle Knoten seien eindeutig nummeriert (0,1,2,...)
Modellierung von G:
1. Knoteninformationen
2. Kanteninformationen
7
2.1 Modellierung der Arbeitsumgebung
1. Feld der Länge V (=maxV) für die Knoten
VAR val: array[0..maxV-1]of Integer;
•
•
Index = Knotennummer in G
Eintrag = Markierung des Knoten, durch:
•
i-te Knoten noch nicht „besucht“:
val[i] = 0
•
j-te Knoten schon „besucht“:
val[j] > 0
8
2.1 Modellierung der Arbeitsumgebung
2. Adjazenzliste zur Speicherung der Kanten
•
•
•
Array der Länge v von einfach verketteten Listen
Index des Array = Knotennummer
Listen Elemente = direkte Nachbarn im Graphen
Array Listen
0
1
2
1
0
2
2
0
1
3
2
Graph
1
2
3
0
3
9
2.2 Programmablauf
Tiefensuche – der Algorithmus
PROGRAM tiefensuche;
VAR
id, k
val
: INTEGER;
: array [1..V-1] of INTEGER;
PROCEDURE visit(k : INTEGER);
VAR
t
: Zeiger;
BEGIN
id
:= id+1;
val[k] := id;
t
:= adj[k];
WHILE t != NULL DO BEGIN
IF val[t^.v] = 0 THEN visit(t^.v);
t := t^.next;
END;
END;
BEGIN
{ HAUPTPROGRAMM }
id := 0;
FOR k := 0 TO (V-1) DO val[k] := 0;
FOR k := 0 TO (V-1) DO IF val[k] = 0 THEN visit(k);
END;
10
2.2 Programmablauf
Tiefensuche – der Algorithmus
PROGRAM tiefensuche;
VAR
id, k : INTEGER;
val
: array [0..V-1] of INTEGER;
PROCEDURE visit(k : INTEGER);
VAR
t
: Zeiger;
BEGIN
id
:= id+1;
val[k] := id;
t
:= adj[k];
WHILE t != NULL DO BEGIN
IF val[t^.v] = 0 THEN visit(t^.v);
t := t^.next;
END;
END;
BEGIN
id :=
FOR k
FOR k
IF
END;
0;
:= 0 TO (V-1) DO val[k] := 0;
:= 0 TO (V-1) DO
val[k] = 0 THEN visit(k);
id : „entdeckte“ Knoten
k
: aktueller Knoten
visit:
sucht rekursiv alle Knoten
einer
Zusammenhangskomponente
t:
Zeiger auf Nachbarknoten
von k
val[k]:
Eintrag im Knotenfeld
(Markierung)
adj[k]:
Adjazenzliste (Nachfolger)
11
2.2 Programmablauf
Beispiel: Graph G und zugehörige Adjazenzliste
0
3
2
4
6
7
1
5
0
2
3
1
5
2
0
3
0
4
4
3
6
5
1
8
6
4
7
4
8
5
7
8
12
2.2 Programmablauf
Initialisierung
Graph G, Adjazenzliste und val[0..maxV-1] Feld
FOR k := 0 TO V-1 DO val[k] := 0;
Index
0
0
1
3
2
2
3
4
4
6
7
5
6
1 5
7
8
8 Graph
2
5
0
0
3
1
4
4
5
3
4
6
8
Index
0
1
2
3
4
5
7
6
7
8
Eintrag
0
0
0
0
0
0
0
0
0 val[k]
Adjazenzliste
13
2.2 Programmablauf
Start im Hauptprogramm
FOR k := 0 TO V-1 DO IF val[k] = 0 THEN visit(k);
0
3
2
4
6
1
7
5
8
0
1
2
3
4
5
6
7
8
2
5
0
0
3
1
4
4
5
3
4
6
8
7
0
1
2
3
4
5
6
7
8
0
0
0
0
0
0
0
0
0
14
2.2 Programmablauf
visit(0) à visit(2)
0
3
2
4
6
1
7
5
8
0
1
2
3
4
5
6
7
8
2
5
0
0
3
1
4
4
5
3
4
6
8
7
0
1
2
3
4
5
6
7
8
1
0
0
0
0
0
0
0
0
15
2.2 Programmablauf
visit(2) à check(0)
0
3
2
4
6
1
7
5
8
0
1
2
3
4
5
6
7
8
2
5
0
0
3
1
4
4
5
3
4
6
8
7
0
1
2
3
4
5
6
7
8
1
0
2
0
0
0
0
0
0
16
2.2 Programmablauf
visit(0) à visit(3)
0
3
2
4
6
1
7
5
8
0
1
2
3
4
5
6
7
8
2
5
0
0
3
1
4
4
5
3
4
6
8
7
0
1
2
3
4
5
6
7
8
1
0
2
0
0
0
0
0
0
17
2.2 Programmablauf
visit(3) à check(0)
0
3
2
4
6
1
7
5
8
0
1
2
3
4
5
6
7
8
2
5
0
0
3
1
4
4
5
3
4
6
8
7
0
1
2
3
4
5
6
7
8
1
0
2
3
0
0
0
0
0
18
2.2 Programmablauf
visit(3) à visit(4)
0
3
2
4
6
1
7
5
8
0
1
2
3
4
5
6
7
8
2
5
0
0
3
1
4
4
5
3
4
6
8
7
0
1
2
3
4
5
6
7
8
1
0
2
3
0
0
0
0
0
19
2.2 Programmablauf
visit(4) à check(3)
0
3
2
4
6
1
7
5
8
0
1
2
3
4
5
6
7
8
2
5
0
0
3
1
4
4
5
3
4
6
8
7
0
1
2
3
4
5
6
7
8
1
0
2
3
4
0
0
0
0
20
2.2 Programmablauf
visit(4) à visit(6)
0
3
2
4
6
1
7
5
8
0
1
2
3
4
5
6
7
8
2
5
0
0
3
1
4
4
5
3
4
6
8
7
0
1
2
3
4
5
6
7
8
1
0
2
3
4
0
0
0
0
21
2.2 Programmablauf
visit(6) à check(4)
0
3
2
4
6
1
7
5
8
0
1
2
3
4
5
6
7
8
2
5
0
0
3
1
4
4
5
3
4
6
8
7
0
1
2
3
4
5
6
7
8
1
0
2
3
4
0
5
0
0
22
2.2 Programmablauf
visit(4) à visit(7)
0
3
2
4
6
1
7
5
8
0
1
2
3
4
5
6
7
8
2
5
0
0
3
1
4
4
5
3
4
6
8
7
0
1
2
3
4
5
6
7
8
1
0
2
3
4
0
5
0
0
23
2.2 Programmablauf
visit(7) à check(4)
0
3
2
4
6
1
7
5
8
0
1
2
3
4
5
6
7
8
2
5
0
0
3
1
4
4
5
3
4
6
8
7
0
1
2
3
4
5
6
7
8
1
0
2
3
4
0
5
6
0
24
2.2 Programmablauf
Hauptprogramm à visit(1)
0
3
2
4
6
1
7
5
8
0
1
2
3
4
5
6
7
8
2
5
0
0
3
1
4
4
5
3
4
6
8
7
0
1
2
3
4
5
6
7
8
1
0
2
3
4
0
5
6
0
25
2.2 Programmablauf
visit(1) à visit(5)
0
3
2
4
6
1
7
5
8
0
1
2
3
4
5
6
7
8
2
5
0
0
3
1
4
4
5
3
4
6
8
7
0
1
2
3
4
5
6
7
8
1
7
2
3
4
0
5
6
0
26
2.2 Programmablauf
visit(5) à check(1)
0
3
2
4
6
1
7
5
8
0
1
2
3
4
5
6
7
8
2
5
0
0
3
1
4
4
5
3
4
6
8
7
0
1
2
3
4
5
6
7
8
1
7
2
3
4
8
5
6
0
27
2.2 Programmablauf
visit(5) à visit(8)
0
3
2
4
6
1
7
5
8
0
1
2
3
4
5
6
7
8
2
5
0
0
3
1
4
4
5
3
4
6
8
7
0
1
2
3
4
5
6
7
8
1
7
2
3
4
8
5
6
0
28
2.2 Programmablauf
visit(8) à check(5)
0
3
2
4
6
1
7
5
8
0
1
2
3
4
5
6
7
8
2
5
0
0
3
1
4
4
5
3
4
6
8
7
0
1
2
3
4
5
6
7
8
1
7
2
3
4
8
5
6
9
29
2.2 Programmablauf
Ende der FOR – Schleife, da k = V
FOR k := 0 TO (V-1) DO
IF val[k] = 0 THEN visit(k);
0
3
2
4
6
1
7
5
8
0
1
2
3
4
5
6
7
8
2
5
0
0
3
1
4
4
5
3
4
6
8
7
0
1
2
3
4
5
6
7
8
1
7
2
3
4
8
5
6
9
30
2.2 Programmablauf
Zusammenfassung
• Tiefensuche durchsucht Graphen
• Stack (Rekursion)
• „Backtracking“
• TS stößt immer zuerst in die maximale Tiefe vor
31
3. Korrektheit
32
3.1 Partielle Korrektheit
Partielle Korrektheit mit Hoare Kalkül
• sehr umfangreich (2 A4 Seiten)
• langwierig
• sich wiederholend à monoton
à Beschränkung auf Interessantes
• Anfangs- und Endbedingungen
• Schleifeninvarianten
• Rekursion
33
3.1 Partielle Korrektheit
Hoare Kalkül und Nassi-Schneidermann Diagramme
{P}
{I}
Anweisung
B
{Q}
{ I und B}
Anweisung 1
Anweisung 2
{I}
{ I und nicht (B) }
34
3.1 Partielle Korrektheit
Anfangs- und Endbedingungen
• V = Anzahl aller Knoten im Graphen
• V1 = Anzahl aller markierten Knoten im Graphen
• V2 = Anzahl aller nicht markierten Knoten in der
aktuellen Zusammenhangskomponente (ZK)
• V3 = Anzahl aller nicht markierten Knoten, die
nicht in der aktuellen ZK sind
• k = aktueller Knoten
{ P } V=V1+V2+V3 und V>0
Hauptprogramm
{ Q } V=V1 und V2=0 und V3=0 und k=V
35
3.1 Partielle Korrektheit
Anfangs- und Endbedingungen
• val[k] = 0 : unbesichtigter Knoten
• t^.v
: Nachbarknoten von k in Adjazenzliste
• (t^.next).v : NachbarNachbarknoten von k in Adjazenzliste
P: val[k] = 0
PROCEDURE visit(k)
Q: nicht(val[k] = 0) und nicht(val[t^.v] = 0) und
nicht(val[(t^.next)^.v] = 0) und nicht ...
36
3.1 Partielle Korrektheit
Invarianten im Hauptprogramm
(FOR Schleifen durch WHILE ersetzt)
FOR k := 0 TO (V-1) DO
IF val[k] = 0 THEN visit(k);
{ I }: V = V1 + V2 + V3 und V-k >= 0
Wiederhole, solange wie k <= V
{ I } V = V1 + V2 + V3
und { B } k <= V
Anweisung(en)
{ I } V = V1 + V2 + V3 und V - k >= 0
{ I } V = V1 + V2 + V3 und V-k >= 0
und nicht (k <= V)
37
3.1 Partielle Korrektheit
Invarianten in VISIT
WHILE t != NULL DO BEGIN
IF val[t^.v] = 0 THEN visit(t^.v);
t := t^.next;
END;
{ I } t = NULL oder t^.next = NULL oder
(t^.next)^.next = NULL oder ...
Wiederhole solange wie nicht (t = NULL)
{ I und B} (t = NULL oder t^.next = NULL oder
(t^.next)^.next = NULL oder ...) und nicht (t = NULL)
Anweisung(en)
{ I } t = NULL oder t^.next = NULL oder (t^.next)^.next =
NULL oder ...
{ I und nicht B} (t = NULL oder t^.next = NULL oder
(t^.next)^.next = NULL oder ...) und t = NULL
38
3.1 Partielle Korrektheit
Rekursion in VISIT
IF val[t^.v] = 0 THEN visit(t^.v);
• Nach Hoare gilt ... (Beweis: über Induktion, à K. Schmidt, ThI 1)
val[t^.v] = 0
visit(t^.v)
nicht(val[t^.v] = 0) und
nicht(val[(t^.next)^.v] = 0) und nicht ...
39
3.2 Totale Korrektheit
Totale Korrektheit =
Terminierung der WHILE Schleifen
Hauptprogramm:
Für die Terminierungsfunktion f(V,k) gilt:
f(V,k) = V – k + 1 , denn:
0 = f(V,k) à k = V + 1 à k > V
40
3.2 Totale Korrektheit
Totale Korrektheit =
Terminierung der WHILE Schleifen
Prozedur VISIT
Zusätzliche Funktionen nötig, da Terminierungsfunktion
f(t) nach N abbildet.
LE sei ein Listenelement
nachfolger(LE) := Anzahl der Nachfolger + 1
f(t) = nachfolger(t)
f(t) = 0
, falls t != NULL
, falls t = NULL
41
4. Einordnung der Tiefensuche
42
4. Einordnung der Tiefensuche
Tiefensuche =
ein typischer Vertreter von Suchalgorithmen
weitere Vertreter :
• Breitensuche
• Allgemeine Kostensuche
• Tiefenbeschränkte Suche
• bidirektionale Suche
• „Gierige“ Suche
• „Hill – Climbing“ Suche
• [...]
Informationen:
http://wwwbrauer.in.tum.de/seminare/web/WS0001/vortrag01.html
43
4. Einordnung der Tiefensuche
FAZIT
• moderater Speicherverbrauch
• Keine Tiefensuche bei großen (infiniten) Tiefen
• „Tiefenbeschränkte Suche“ als Alternative
44
Quellen
• http://www.informatik.uni-stuttgart.de/ifi/bs/lehre/ei1/1999/htm/graph3.htm
• Gerald Futschek; Programmentwicklung und Verifikation;
Springer-Verlag Wien New-York; 1989;
• Robert Sedgewick; Algorithms in Java; Addison Wesley; 2002
• http://www.informatik.uni-bremen.de/~visser/lectures/ki-1_WS9900/slides/kap_3_suche.pdf
• http://wwwbrauer.in.tum.de/seminare/web/WS0001/vortrag01.html
• http://www.informatik.uni-stuttgart.de/ifi/bs/lehre/ei1/1999/htm/graph3.htm
45
Abschluss
„Indiana Jones – Der Entdecker der Tiefensuche?“
• Indys Vorgehen entspricht dem Ablauf des
Algorithmus der Tiefensuche
• Dennoch, Indiana Jones ist nicht der Entdecker ...
„Die Tiefensuche ist schon aus dem Altertum und aus der griechischen
Sage bekannt unter dem Namen Labyrinth-Suche.
Dieser bezieht sich auf die Erzählung von dem griechischen Helden
Theseus, der nach Kreta reiste, um dort ein Untier namens Minotauros zu
erlegen, das dort in einem unterirdischen Höhlensystem, genannt
Labyrinth, sein Unwesen trieb. [...]
jedenfalls fand Theseus den Minotauros mittels Tiefensuche, und als
Markierungshilfsmittel verwendete er das Wollknäuel aus dem Strickzeug
der Königstochter Ariadne, [...]“
46
Herunterladen