Benutzer-Werkzeuge

Webseiten-Werkzeuge


rekursion:tiefensuche:start

Unterschiede

Hier werden die Unterschiede zwischen zwei Versionen angezeigt.

Link zu dieser Vergleichsansicht

Beide Seiten der vorigen RevisionVorhergehende Überarbeitung
Nächste Überarbeitung
Vorhergehende Überarbeitung
rekursion:tiefensuche:start [2024/09/08 16:00] Martin Pabstrekursion:tiefensuche:start [2024/09/18 09:23] (aktuell) – [Wiederholung: Graphen, Adjazenzmatrix] Martin Pabst
Zeile 6: Zeile 6:
 Sehen Sie sich zunächst das folgende Video an, in dem der Algorithmus der Tiefensuche erklärt wird: Sehen Sie sich zunächst das folgende Video an, in dem der Algorithmus der Tiefensuche erklärt wird:
 {{ youtube>PMMc4VsIacU?large }} {{ youtube>PMMc4VsIacU?large }}
 +Im Video verwendete Fachwörter:
 +  * vertex (auch: node) -> Knoten
 +  * edge -> Kante
 +  * DFS: Depth first search -> Tiefensuche
 +  * graph traversal -> Traversierung eines Graphen (d.h. Beschreitung all seiner Knoten)
 </WRAP> </WRAP>
  
Zeile 15: Zeile 20:
  
 \\  \\ 
-Wir wollen eine Methode ''istVerbundenRekursiv(int startknoten, int zielknoten)'' schreiben, die genau dann ''true'' zurückliefert, wenn es einen Pfad vom Startknoten zum Zielknoten gibt. Wir gehen nach folgender Strategie vor:+ 
 + 
 +<WRAP center round info 80%> 
 +**Informelle Beschreibung des Algorithmus:** 
 +Wir entwickeln eine Methode ''istVerbundenRekursiv(int startknoten, int zielknoten)'', die genau dann ''true'' zurückliefert, wenn es einen Pfad vom Startknoten zum Zielknoten gibt. Sie geht dazu folgendermaßen vor:
   * 1.) Überprüfe, ob ''startknoten == zielknoten''. Falls "ja", gib ''true'' zurück.   * 1.) Überprüfe, ob ''startknoten == zielknoten''. Falls "ja", gib ''true'' zurück.
   * 2.) Überprüfe für jeden von ''startknoten'' aus erreichbaren Knoten ''i'', ob ''istVerbundenRekursiv(i, zielknoten) == true'' ist. Falls "ja", gib ''true'' zurück.   * 2.) Überprüfe für jeden von ''startknoten'' aus erreichbaren Knoten ''i'', ob ''istVerbundenRekursiv(i, zielknoten) == true'' ist. Falls "ja", gib ''true'' zurück.
-Dieses Vorgehen kann bei zyklischen Graphen zu einer **unendlichen Methodenaufrufkette** führen. Daher muss der Algorithmus **speichern, welche Knoten er schon besucht hat** und diese bei 2.) ausnehmen. Dies geschieht mittels eines Arrays ''boolean[] schonBesucht'', das für jeden Knoten einen booleschen Wert speichert, der angibt, ob der Knoten schon besucht wurde. Dieses Array wird anfangs in der Methode ''istVerbunden'' instanziert und mit ''false''-Werten befüllt. Diese übergibt die Refernz auf dieses Array an die Methode ''istVerbundenRekursiv''. Bei 1.) wird ''schonBesucht[startknoten] = true'' gesetzt und bei 2.) wird eine Referenz auf das Array ''schonBesucht'' bei jedem weiteren Aufruf von ''istVerbundenRekursiv'' weitergereicht. \\ \\ Die fertigen Methoden ''istVerbunden'' und ''istVerbundenRekursiv'' sind im obigen Programm schon eingebaut. Der Graph, der im Hauptprogramm aufgebaut wird, ist rechts dargestellt.  
  
-<WRAP center round info 80%>+**Problem:** \\  
 +Dieses Vorgehen kann bei zyklischen Graphen zu einer **unendlichen Methodenaufrufkette** führen.  
 + 
 +**Lösung:** \\ 
 +Der Algorithmus muss **speichern, welche Knoten er schon besucht hat** und diese bei Schritt 2.) auslassen. Dies geschieht mittels eines Arrays ''boolean[] schonBesucht'', das für jeden Knoten einen booleschen Wert speichert, der angibt, ob der Knoten schon besucht wurde. Dieses Array wird zu Beginn des Algorithmus (im Programm unten in der Methode ''istVerbunden'') instanziert und mit ''false''-Werten befüllt. \\  
 +In Schritt 1.) wird ''schonBesucht[startknoten] = true'' gesetzt und bei 2.) wird eine Referenz auf das Array ''schonBesucht'' bei jedem weiteren Aufruf von ''istVerbundenRekursiv'' weitergereicht. \\ \\  
 Die beschriebene Methode nennt man **Tiefensuche** (engl. depth-first search, DFS). "Bei der Tiefensuche wird zunächst jeder Pfad vollständig in die Tiefe beschritten, bevor abzweigende Pfade beschritten werden." (siehe [[https://de.wikipedia.org/wiki/Tiefensuche|den entsprechenden Artikel in Wikipedia, der auch eine schöne Animation dazu zeigt)]]. \\ \\  Die beschriebene Methode nennt man **Tiefensuche** (engl. depth-first search, DFS). "Bei der Tiefensuche wird zunächst jeder Pfad vollständig in die Tiefe beschritten, bevor abzweigende Pfade beschritten werden." (siehe [[https://de.wikipedia.org/wiki/Tiefensuche|den entsprechenden Artikel in Wikipedia, der auch eine schöne Animation dazu zeigt)]]. \\ \\ 
 Ein zweites Suchverfahren wäre die **Breitensuche** (engl. breadth-first search, BFS). Bei dieser werden "zunächst alle Knoten beschritten, die vom Ausgangsknoten direkt erreichbar sind. Erst danach werden Folgeknoten beschritten." (siehe [[https://de.wikipedia.org/wiki/Breitensuche|den entsprechenden Artikel in Wikipedia, und die sehr anschauliche Animation dort.)]] \\ \\  Ein zweites Suchverfahren wäre die **Breitensuche** (engl. breadth-first search, BFS). Bei dieser werden "zunächst alle Knoten beschritten, die vom Ausgangsknoten direkt erreichbar sind. Erst danach werden Folgeknoten beschritten." (siehe [[https://de.wikipedia.org/wiki/Breitensuche|den entsprechenden Artikel in Wikipedia, und die sehr anschauliche Animation dort.)]] \\ \\ 
Zeile 30: Zeile 44:
 <WRAP center round tip 50%> <WRAP center round tip 50%>
 {{ :rekursion:tiefensuche:pasted:20240908-175613.png?200|}} {{ :rekursion:tiefensuche:pasted:20240908-175613.png?200|}}
-Den im Testprogramm unten generierten Graphen siehst Du in graphischer Darstellung im Bild rechts. So kannst Du das Programm schrittweise ausführen und gleichzeitig den Programmverlauf am Graphen mitverfolgen.+Den im Testprogramm unten generierten Graphen sehen Sie in graphischer Darstellung im Bild rechts. So können Sie das Programm schrittweise ausführen und gleichzeitig den Programmverlauf am Graphen mitverfolgen.
 </WRAP> </WRAP>
  
Zeile 96: Zeile 110:
  
 <WRAP center round todo 60%> <WRAP center round todo 60%>
 +
 +===== Aufgabe 1 =====
 +
 **Aufgabe (nicht leicht...):** \\ \\  **Aufgabe (nicht leicht...):** \\ \\ 
-Erweitere das Programm so, dass die Methoden ''istVerbunden'' in dem Fall, dass sie einen Pfad gefunden hat, diesen in der Form 7->0->1->2->3->4 ausgibt. \\ \\ +Erweitern Sie das Programm so, dass die Methode ''istVerbunden'' in dem Fall, dass sie einen Pfad gefunden hat, diesen in der Form 7->0->1->2->3->4 ausgibt. \\ \\ 
 [[.istverbundenaufgabe:loesung|Lösung]] [[.istverbundenaufgabe:loesung|Lösung]]
 </WRAP> </WRAP>
rekursion/tiefensuche/start.1725811229.txt.gz · Zuletzt geändert: 2024/09/08 16:00 von Martin Pabst

Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki