www.wikidata.de-de.nina.az
Tiefensuche englisch depth first search DFS ist in der Informatik ein Verfahren zum Suchen von Knoten in einem Graphen Sie zahlt zu den uninformierten Suchalgorithmen Im Gegensatz zur Breitensuche wird bei der Tiefensuche zunachst ein Pfad vollstandig in die Tiefe beschritten bevor abzweigende Pfade beschritten werden 1 Dabei sollen alle erreichbaren Knoten des Graphen besucht werden Fur Graphen mit potenziell wenigen langen Pfaden bietet sich die beschrankte Tiefensuche an bei der jeder Pfad nur bis zu einer bestimmten Tiefe beschritten wird Animation der Tiefensuche in einem BaumEine Verbesserung der Tiefensuche ist die iterative Tiefensuche Inhaltsverzeichnis 1 Arbeitsweise 2 Algorithmen 2 1 Erzeugen des Tiefensuchwaldes 3 Programmierung 4 Eigenschaften 4 1 Speicherplatz 4 2 Laufzeit 4 3 Vollstandigkeit 4 4 Optimalitat 5 Anwendungen 6 Literatur 7 Weblinks 8 EinzelnachweiseArbeitsweise BearbeitenSiehe auch Binarbaum Tiefensuche Die Tiefensuche ist ein uninformierter Suchalgorithmus welche durch Expansion des jeweils ersten auftretenden Nachfolgeknotens im Graphen nach und nach vom Startknoten aus weiter in die Tiefe sucht In welcher Reihenfolge die Nachfolger eines Knotens dabei bestimmt werden hangt von der Reprasentation der Nachfolger ab Bei der Reprasentation uber eine Adjazenzliste mittels einer verketteten Liste werden beispielsweise die Knoten in der Reihenfolge ihres Eintrags in dieser Liste durchlaufen Im oben angegebenen Bild wird implizit davon ausgegangen dass die Nachfolger von links nach rechts ausgewahlt werden Fur ungerichtete Graphen sieht das Verfahren wie folgt aus Zuerst wird ein Startknoten u displaystyle left u right nbsp ausgewahlt Von diesem Knoten aus wird nun die erste Kante u v displaystyle left u v right nbsp betrachtet und getestet ob der gegenuberliegende Knoten v displaystyle left v right nbsp schon entdeckt wurde bzw das gesuchte Element ist Ist dies noch nicht der Fall so wird rekursiv fur diesen Knoten die Tiefensuche aufgerufen wodurch wieder der erste Nachfolger dieses Knotens expandiert wird Diese Art der Suche wird solange fortgesetzt bis das gesuchte Element entweder gefunden wurde oder die Suche bei einer Senke im Graphen angekommen ist und somit keine weiteren Nachfolgeknoten mehr untersuchen kann An dieser Stelle kehrt der Algorithmus nun zum zuletzt expandierten Knoten u displaystyle left u right nbsp zuruck und untersucht den nachsten Nachfolger des Knotens Sollte es hier keine weiteren Nachfolger mehr geben geht der Algorithmus wieder Schritt fur Schritt zum jeweiligen Vorganger zuruck und versucht es dort erneut Ein Beispiel fur die Anwendung der Tiefensuche auf einen Baum zeigt die Animation nbsp Die vier Typen von Kanten die vom Startknoten 1 des gezeigten gerichteten Graphen definiert werden Die schwarzen Kanten zeigen den Baum den die Tiefensuche durchlauft Die Kanten des Graphen die vom Algorithmus zum Durchlaufen des Graphen benutzt werden werden als Baumkanten bezeichnet Diejenigen Kanten die nicht benutzt werden und von einem Knoten zu einem anderen Knoten im selben Teilbaum fuhren der bei der Tiefensuche spater besucht wird heissen Vorwartskanten Diejenigen Kanten die nicht benutzt werden und von einem Knoten zu einem anderen Knoten im selben Teilbaum fuhren der bei der Tiefensuche bereits vorher besucht wurde heissen Ruckwartskanten Diejenigen Kanten die quer von einem Teilbaum zu einem anderen Teilbaum verlaufen heissen Querkanten Innerhalb des Tiefensuchbaums wurde der Pfad zwischen zwei uber eine Querkante verbundenen Knoten zunachst ein Auf und dann ein Absteigen im Baum erfordern Vorwartskanten Ruckwartskanten Querkanten und Baumkanten ergeben insgesamt die Kantenmenge des Graphen nbsp Eine graphentheoretische Landkarte von Deutschland Osterreich und der Schweiz mit den Verbindungen zwischen einigen Stadten Dieses Beispiel ist ein ungerichteter Graph mit 10 Knoten nbsp Der Baum welcher entsteht wenn man Tiefensuche auf die Landkarte anwendet und in Hannover startet Dieser Baum hat die Hohe 6 Daher hat die Tiefensuche in diesem Fall die maximale Rekursionstiefe 6 Der Index der Rekursionstiefe der rekursiven Methode oder Prozedur fur die Tiefensuche entspricht dem Knotenabstand des aktuell durchlaufenen Knotens vom Startknoten im in der rechten Abbildung gezeigten Baum Dieser Index musste um zum Beispiel auf der Konsole ausgegeben zu werden in einer Variablen gespeichert werden Diese rekursive Methode oder Prozedur wird so oft aufgerufen wie die Anzahl der Knoten des Graphen ist Die Rekursion bricht ab wenn der aktuell durchlaufene Knoten nur Nachbarknoten hat die schon vorher durchlaufen wurden Im Beispiel mit den Stadten siehe oben gibt es folgende rekursive Aufrufe Hannover Startknoten Rekursionstiefe 0 Frankfurt Nachbarknoten von Hannover Rekursionstiefe 1 Zurich Nachbarknoten von Frankfurt Rekursionstiefe 2 Munchen Nachbarknoten von Zurich Rekursionstiefe 3 Stuttgart Nachbarknoten von Munchen Rekursionstiefe 4 Hamburg Nachbarknoten von Stuttgart Rekursionstiefe 5 Mannheim Nachbarknoten von Hamburg Rekursionstiefe 6 Dresden Nachbarknoten von Stuttgart Rekursionstiefe 5 Wien Nachbarknoten von Munchen Rekursionstiefe 4 Berlin Nachbarknoten von Wien Rekursionstiefe 5 Der Knotenabstand bezieht sich immer auf den Startknoten Im links dargestellten ungerichteten Graphen ist es Hannover Bei gerichteten Graphen ist der Knotenabstand zwischen zwei verschiedenen Knoten nicht unbedingt symmetrisch Der Baum den die Tiefensuche durchlauft ist ein Spannbaum des Graphen und hangt vom Startknoten ab Es ist ausserdem wichtig ob es sich um einen gerichteten Graphen oder ungerichteten Graphen handelt Der Knotenabstand und die Rekursionstiefe ist nur fur zusammenhangende Graphen definiert und hangt vom Startknoten ab Fur nicht zusammenhangende Graphen ist der Knotenabstand und die Rekursionstiefe nur innerhalb jeder Zusammenhangskomponente definiert Hinweis Der in der Abbildung links oben mit den Stadten gezeigte Graph ist ein ungerichteter Graph Die Reihenfolge der durchlaufenen Knoten kann sich andern wenn stattdessen ein anderer Startknoten oder ein gerichteter Graph genommen wird der nicht symmetrisch ist Algorithmen BearbeitenBestimme den Knoten an dem die Suche beginnen soll Expandiere den Knoten und speichere der Reihenfolge nach den kleinsten grossten optional noch nicht erschlossenen Nachfolger in einem Stack Rufe rekursiv fur jeden der Knoten in dem Stack DFS auf Falls das gesuchte Element gefunden wurde brich die Suche ab und liefere ein Ergebnis Falls es keine nicht erschlossenen Nachfolger mehr gibt losche den obersten Knoten aus dem Stack und rufe fur den jetzt oberen Knoten im Stack DFS aufDFS node goal if node goal return node else stack expand node while stack is not empty node pop stack DFS node goal Erzeugen des Tiefensuchwaldes Bearbeiten Der folgende rekursive Algorithmus in Pseudocode erzeugt den Tiefensuchwald eines Graphen G mittels Setzen von Discovery und Finishing Times und Farben der Knoten In Anlehnung an Cormen et al werden zunachst alle Knoten weiss gefarbt Anschliessend startet die Tiefensuche per Definition beim alphabetisch kleinsten Knoten und farbt diesen grau Danach wird wie oben beschrieben rekursiv dessen weisser Nachbar betrachtet und grau gefarbt Existiert kein weisser Nachbar mehr kommt es zum Backtracking wahrend dessen alle durchwanderten Knoten schwarz gefarbt werden 2 DFS G for each v of G Alle Knoten weiss farben Vorganger auf nil setzen col v w pi v nil time 0 for each u of G Fur alle weissen Knoten DFS visit aufrufen if col u w DFS visit u DFS visit u 1 col u g Aktuellen Knoten grau farben 2 time Zeitzahler erhohen 3 d u time Entdeckzeit des aktuellen Knotens setzen 4 for each v of Adj u Fur alle weissen Nachbarn des aktuellen Knotens 5 6 if col v w 7 8 pi v u Vorganger auf aktuellen Knoten setzen 9 DFS visit v DFS visit aufrufen 10 11 if col v g 12 13 Zyklus entdeckt 14 15 16 col u s Aktuellen Knoten schwarz farben 17 time 18 f u time Finishing Time des aktuellen Knotens setzen Den Zeitstempel siehe Zeilen 2 17 18 kann man weiterhin fur eine topologische Sortierung verwenden Nachdem ein Knoten schwarz gefarbt wurde wird er einer Liste absteigend nach den Werten f u fur die Zeitstempel hinzugefugt und man erhalt eine topologische Reihenfolge Wird ein Zyklus siehe Zeile 9 entdeckt ist dies nicht mehr moglich Programmierung BearbeitenDas folgende Beispiel in der Programmiersprache C zeigt die Implementierung der Tiefensuche fur einen gerichteten Graphen Der gerichtete Graph wird als Klasse DirectedGraph deklariert Die Methode DepthFirstSearch die die Knoten durchlauft und in einer Liste speichert verwendet einfache Rekursion Bei der Ausfuhrung des Programms wird die Methode Main verwendet die die Liste der markierten Knoten auf der Konsole ausgibt 3 using System using System Collections Generic Deklariert die Klasse fur die Knoten des Graphen class Node public int index public string value public List lt Node gt adjacentNodes new List lt Node gt Liste der Nachbarknoten Deklariert die Klasse fur den gerichteten Graphen class DirectedGraph Diese Methode verbindet die Knoten startNode und targetNode miteinander public void ConnectNodes Node startNode Node targetNode startNode adjacentNodes Add targetNode class Program Diese Methode gibt die Liste der Knoten in der Form A B C als Text zuruck public static string ToString List lt Node gt traversedNodes string text for int i 0 i lt traversedNodes Count i for Schleife die die Knoten durchlauft text traversedNodes i value text text Substring 0 text Length 2 return text Diese Methode durchlauft die Knoten des gerichteten Graphen mit einer Tiefensuche public static void DepthFirstSearch Node startNode List lt Node gt traversedNodes traversedNodes Add startNode Fugt den aktuellen Knoten der Menge der markierten Knoten hinzu foreach Node node in startNode adjacentNodes foreach Schleife die alle benachbarten Knoten des Knotens durchlauft if traversedNodes Contains node Wenn der Knoten noch nicht markiert wurde DepthFirstSearch node traversedNodes Rekursiver Aufruf der Methode mit dem Nachbarknoten als Startknoten Hauptmethode die das Programm ausfuhrt public static void Main String args Deklariert und initialisiert 4 Knoten Node node1 new Node index 0 value A Node node2 new Node index 1 value B Node node3 new Node index 2 value C Node node4 new Node index 3 value D Erzeugt einen gerichteten Graphen DirectedGraph directedGraph new DirectedGraph Verbindet Knoten des Graphen miteinander directedGraph ConnectNodes node1 node2 directedGraph ConnectNodes node1 node3 directedGraph ConnectNodes node2 node3 directedGraph ConnectNodes node3 node1 directedGraph ConnectNodes node3 node4 directedGraph ConnectNodes node4 node4 List lt Node gt traversedNodes new List lt Node gt Liste der Knoten fur die Tiefensuche DepthFirstSearch node3 traversedNodes Aufruf der Methode Console WriteLine ToString traversedNodes Ausgabe auf der Konsole Console ReadLine Hinweise Fur die Nachbarknoten wurde eine Liste als Datentyp verwendet damit die Reihenfolge der durchlaufenen Knoten eindeutig ist und die Knoten in allen Ebenen von links nach rechts durchlaufen werden Fur den Datentyp Menge zum Beispiel muss das nicht der der Fall sein Statt dem HashSet Menge visitedNodes kann auch eine Liste oder ein Array vom Typ bool Boolesche Variable verwendet werden wie im Einzelnachweis gezeigt 3 Eigenschaften BearbeitenIm Folgenden werden Speicherbedarf und Laufzeit des Algorithmus in Landau Notation angegeben Wir gehen ausserdem von einem gerichteten Graphen aus Speicherplatz Bearbeiten Der Speicherbedarf des Algorithmus wird ohne den Speicherplatz fur den Graphen wie er ubergeben wird angegeben denn dieser kann in verschiedenen Formen mit unterschiedlichem Speicherbedarf vorliegen z B als verkettete Liste als Adjazenzmatrix oder als Inzidenzmatrix Fur die oben beschriebene Prozedur DFS G werden zunachst alle Knoten weiss gefarbt und die Referenzen fur deren Vorganger entfernt Diese Informationen benotigt also fur jeden Knoten konstanten Speicherplatz also O 1 displaystyle mathcal O 1 nbsp Insgesamt ergibt sich ein linearer Speicherbedarf von O V displaystyle mathcal O vert V vert nbsp abhangig von der Anzahl der Knoten V displaystyle vert V vert nbsp englisch vertices Der Speicherbedarf der Variable time ist mit konstantem O 1 displaystyle mathcal O 1 nbsp gegenuber O V displaystyle mathcal O vert V vert nbsp vernachlassigbar Anschliessend wird fur jeden Knoten u die Prozedur DFS visit u aufgerufen Da es sich hierbei nur um Kontrollstrukturen handelt tragen sie nicht zum Speicherbedarf bei Die Prozedur DFS visit u arbeitet auf der bereits aufgebauten Speicherstruktur in der alle Knoten abgelegt sind und erweitert diese pro Knoten noch um die Entdeckzeit und die Finishing Time jeweils konstant O 1 displaystyle mathcal O 1 nbsp Das andert nichts am bisherigen linearen Speicherbedarf O V displaystyle mathcal O vert V vert nbsp Da sonst in DFS visit u keine weiteren Variablen mehr eingefuhrt werden hat die Tiefensuche einen Speicherbedarf von O V displaystyle mathcal O vert V vert nbsp Laufzeit Bearbeiten Falls der Graph als Adjazenzliste gespeichert wurde mussen im Worst Case alle moglichen Pfade zu allen moglichen Knoten betrachtet werden Damit betragt die Laufzeit von Tiefensuche O V E displaystyle mathcal O vert V vert vert E vert nbsp wobei V displaystyle vert V vert nbsp fur die Anzahl der Knoten und E displaystyle vert E vert nbsp fur die Anzahl der Kanten im Graph stehen 4 Vollstandigkeit Bearbeiten Falls ein Graph unendlich gross ist oder kein Test auf Zyklen durchgefuhrt wird so ist die Tiefensuche nicht vollstandig Es kann also sein dass ein Ergebnis obwohl es existiert nicht gefunden wird Optimalitat Bearbeiten Tiefensuche ist insbesondere bei monoton steigenden Pfadkosten nicht optimal da eventuell ein Ergebnis gefunden wird zu welchem ein sehr viel langerer Pfad fuhrt als zu einem alternativen Ergebnis Dafur wird ein solches Ergebnis im Allgemeinen deutlich schneller gefunden als bei der in diesem Fall optimalen aber sehr viel speicheraufwendigeren Breitensuche Als Kombination von Tiefen und Breitensuche gibt es die iterative Tiefensuche Anwendungen Bearbeiten source source source source source Algorithmus der Tiefensuche verwendet um einen Irrgarten zu erzeugen Die Tiefensuche ist indirekt an vielen komplexeren Algorithmen fur Graphen beteiligt Beispiele Das Auffinden aller starken Zusammenhangskomponenten eines Graphen Das Ermitteln von 2 zusammenhangenden Komponenten Das Ermitteln von 3 zusammenhangenden Komponenten Das Ermitteln der Brucken eines Graphen Einen Graphen testen ob er ein planarer Graph ist 5 6 Bei einem Baum der Abhangigkeiten darstellt ergeben die sortierten finish Zeiten siehe Pseudocode oben eine invers topologische Sortierung Mit der Tiefensuche kann man Graphen in Laufzeit O V E displaystyle mathcal O vert V vert vert E vert nbsp auf Kreise testen und im Falle von Kreisen die dazugehorige Kantenfolge ausgeben 7 Ein kreisfreier Graph kann mit der Tiefensuche in Laufzeit O V E displaystyle mathcal O vert V vert vert E vert nbsp topologisch sortiert werden 7 Das Losen von Ratseln mit nur einer Losung z B Irrgarten Die Tiefensuche kann angepasst werden um alle Losungen fur einen Irrgarten zu finden indem nur Knoten auf dem aktuellen Pfad in die besuchte Menge aufgenommen werden Fur das Erzeugen eines Irrgartens kann eine zufallige Tiefensuche verwendet werden Literatur BearbeitenStuart Russell Peter Norvig Artificial Intelligence A Modern Approach 2 Auflage Prentice Hall 2002 Sven Oliver Krumke Hartmut Noltemeier Graphentheoretische Konzepte und Algorithmen 3 Auflage Springer Vieweg 2012 ISBN 978 3 8348 1849 2Weblinks Bearbeiten nbsp Commons Tiefensuche Sammlung von Bildern Videos und Audiodateien nbsp Wikibooks Tiefensuche Implementierungen in der Algorithmensammlung Anschauliche Erklarung der Tiefensuche am Beispiel eines LabyrinthsEinzelnachweise Bearbeiten Volker Turau Algorithmische Graphentheorie 3 Auflage Oldenbourg Wissenschaftsverlag Munchen 2009 ISBN 978 3 486 59057 9 S 94 98 Thomas H Cormen Charles Leiserson Ronald L Rivest Clifford Stein Algorithmen Eine Einfuhrung 3 Auflage Oldenbourg Wissenschaftsverlag Munchen 2010 ISBN 978 3 486 59002 9 S 613 622 a b GeeksforGeeks Depth First Search or DFS for a Graph Thomas Ottmann Peter Widmayer Algorithmen und Datenstrukturen 5 Auflage Spektrum Akademischer Verlag Heidelberg 2012 ISBN 978 3 8274 2803 5 S 589 668 John Hopcroft Robert E Tarjan Efficient planarity testing In Journal of the Association for Computing Machinery 21 Jahrgang Nr 4 1974 S 549 568 doi 10 1145 321850 321852 H de Fraysseix P Ossona de Mendez P Rosenstiehl Tremaux Trees and Planarity In International Journal of Foundations of Computer Science 17 Jahrgang Nr 5 2006 S 1017 1030 doi 10 1142 S0129054106004248 arxiv math 0610935 a b Sven Oliver Krumke Hartmut Noltemeier Graphentheoretische Konzepte und Algorithmen 3 Auflage Springer Vieweg Wiesbaden 2012 ISBN 978 3 8348 1849 2 S 152 157 Abgerufen von https de wikipedia org w index php title Tiefensuche amp oldid 229359414