Graphen und Suche: Breitensuche und Tiefensuche
Landkarten, soziale Netzwerke, Straßennetze, Abhängigkeiten zwischen Software-Paketen: All das sind Dinge, die miteinander verbunden sind. Die Informatik beschreibt sie alle mit demselben Modell, dem Graphen. Er besteht aus Punkten und Verbindungen zwischen ihnen und lässt alles Unwichtige weg, etwa die Länge der Straße oder die Farbe der Haltestelle.
Die erste Frage an einen Graphen lautet fast immer: Von einem Startpunkt aus, was kann ich erreichen und auf welchem Weg? Dafür gibt es zwei grundlegende Strategien. Die eine erkundet zuerst die Nachbarschaft in immer größeren Kreisen, die andere folgt einem Weg so weit wie möglich und kehrt erst dann um. Beide kannst du im Werkzeug Graphalgorithmen Schritt für Schritt verfolgen.
Graph
Ein Graph besteht aus einer endlichen Menge von Knoten und einer Menge von Kanten. In einem ungerichteten Graphen ist eine Kante eine Verbindung zwischen zwei Knoten ohne Richtung. In einem gerichteten Graphen hat jede Kante eine Richtung von nach .
Zwei Knoten, die durch eine Kante verbunden sind, heißen benachbart. Ein Weg ist eine Folge von Knoten, in der aufeinanderfolgende Knoten benachbart sind. Seine Länge ist die Zahl der Kanten. Ein Graph heißt zusammenhängend, wenn es von jedem Knoten einen Weg zu jedem anderen gibt.
Zur Darstellung im Computer speichert man für jeden Knoten die Liste seiner Nachbarn (Adjazenzliste) oder eine -Tabelle mit Einträgen für vorhandene Kanten (Adjazenzmatrix). Die Liste braucht Platz , die Matrix . Für Graphen mit wenigen Kanten ist die Liste besser.
Breitensuche (BFS)
Bei der Breitensuche startest du an einem Knoten und besuchst zuerst alle seine Nachbarn, dann deren Nachbarn und so weiter. Du erkundest den Graphen also Schicht für Schicht, wie Wellen um einen ins Wasser geworfenen Stein.
Technisch benutzt man eine Warteschlange (Queue: wer zuerst kommt, wird zuerst bearbeitet). Du legst hinein und markierst ihn. Solange die Schlange nicht leer ist, nimmst du den vordersten Knoten heraus, und jeden unmarkierten Nachbarn markierst du und stellst ihn hinten an.
Wichtige Eigenschaft: Die Breitensuche findet in einem Graphen ohne Gewichte zu jedem erreichbaren Knoten einen kürzesten Weg (gemessen in Kanten), denn Knoten mit kleinerem Abstand werden vor Knoten mit größerem Abstand bearbeitet. Die Laufzeit ist .
Tiefensuche (DFS)
Bei der Tiefensuche folgst du von aus einem Nachbarn, von dort einem weiteren Nachbarn und so weiter, so tief wie möglich. Erst wenn es nicht weitergeht (alle Nachbarn sind besucht), gehst du einen Schritt zurück und probierst die nächste Möglichkeit. Das ist wie das Erkunden eines Labyrinths mit einem Faden.
Technisch benutzt man einen Stapel (Stack: zuletzt hinein, zuerst heraus) oder die Rekursion, die einen Stapel implizit mitbringt. Die Laufzeit ist ebenfalls . Die Tiefensuche findet nicht unbedingt kürzeste Wege, ist aber die Grundlage für Zykluserkennung, die Zerlegung in Zusammenhangskomponenten und die topologische Sortierung.
BFS und DFS auf einem kleinen Graphen
BFS und DFS auf einem kleinen Graphen
Der Graph hat die Knoten und die Kanten , , , , , . Nachbarn werden in alphabetischer Reihenfolge besucht. Start ist .
BFS: Schicht : . Schicht : . Schicht : (erreicht über ). Schicht : . Schicht : . Die Besuchsreihenfolge lautet , und der kürzeste Weg von nach hat vier Kanten: .
DFS: Von geht es zu , von zu , von zuerst zu (alphabetisch vor ). hat keine unbesuchten Nachbarn mehr, also zurück zu und weiter zu und . Die Besuchsreihenfolge lautet . Beide Verfahren besuchen alle Knoten, aber in unterschiedlicher Reihenfolge.
Zusammenfassung
Ein Graph beschreibt Objekte (Knoten) und ihre Verbindungen (Kanten); er kann gerichtet oder ungerichtet sein.
Adjazenzliste: Platz ; Adjazenzmatrix: Platz .
Breitensuche mit Warteschlange erkundet Schicht für Schicht und findet kürzeste Wege nach Kantenzahl.
Tiefensuche mit Stapel oder Rekursion geht so tief wie möglich und kehrt dann um.
Beide Verfahren benötigen Zeit, wenn besuchte Knoten markiert werden.
Übungen
Wie viele Kanten hat der vollständige ungerichtete Graph auf Knoten (jeder Knoten ist mit jedem anderen verbunden)?
Welche Datenstruktur benutzt die Breitensuche zur Verwaltung der noch zu besuchenden Knoten?
Wie viele Kanten hat im Beispielgraphen der kürzeste Weg von nach (laut Breitensuche)?
Führe auf dem Graphen mit den Kanten , , , , eine Breitensuche und eine Tiefensuche ab Knoten durch (kleinere Nachbarn zuerst) und gib jeweils die Besuchsreihenfolge an.