Lektion 3.1

Graphen und Suche: Breitensuche und Tiefensuche

35 min Lesezeit

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.

Definition

Graph

Ein Graph G=(V,E)G = (V, E) besteht aus einer endlichen Menge VV von Knoten und einer Menge EE von Kanten. In einem ungerichteten Graphen ist eine Kante {u,v}\{u, v\} eine Verbindung zwischen zwei Knoten ohne Richtung. In einem gerichteten Graphen hat jede Kante (u,v)(u, v) eine Richtung von uu nach vv.

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 ∣V∣×∣V∣|V| \times |V|-Tabelle mit Einträgen 11 für vorhandene Kanten (Adjazenzmatrix). Die Liste braucht Platz O(∣V∣+∣E∣)O(|V| + |E|), die Matrix O(∣V∣2)O(|V|^2). Für Graphen mit wenigen Kanten ist die Liste besser.

G=(V,E),E⊆{{u,v}:u,v∈V, u≠v}G = (V, E), \qquad E \subseteq \bigl\{\{u,v\} : u, v \in V,\ u \neq v\bigr\}
Definition

Breitensuche (BFS)

Bei der Breitensuche startest du an einem Knoten ss 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 ss 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 O(∣V∣+∣E∣)O(|V| + |E|).

Abstand(s,v)=Schicht, in der v entdeckt wird\text{Abstand}(s, v) = \text{Schicht, in der } v \text{ entdeckt wird}
Definition

Tiefensuche (DFS)

Bei der Tiefensuche folgst du von ss 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 O(∣V∣+∣E∣)O(|V| + |E|). Die Tiefensuche findet nicht unbedingt kürzeste Wege, ist aber die Grundlage für Zykluserkennung, die Zerlegung in Zusammenhangskomponenten und die topologische Sortierung.

BFS: Warteschlange (FIFO)DFS: Stapel (LIFO)\text{BFS: Warteschlange (FIFO)} \qquad \text{DFS: Stapel (LIFO)}
Beispiel

BFS und DFS auf einem kleinen Graphen

Der Graph hat die Knoten A,B,C,D,E,FA, B, C, D, E, F und die Kanten A ⁣− ⁣BA\!-\!B, A ⁣− ⁣CA\!-\!C, B ⁣− ⁣DB\!-\!D, C ⁣− ⁣DC\!-\!D, D ⁣− ⁣ED\!-\!E, E ⁣− ⁣FE\!-\!F. Nachbarn werden in alphabetischer Reihenfolge besucht. Start ist AA.

BFS: Schicht 00: AA. Schicht 11: B,CB, C. Schicht 22: DD (erreicht über BB). Schicht 33: EE. Schicht 44: FF. Die Besuchsreihenfolge lautet A,B,C,D,E,FA, B, C, D, E, F, und der kürzeste Weg von AA nach FF hat vier Kanten: A,B,D,E,FA, B, D, E, F.

DFS: A→B→D→C→(zuru¨ck zu D)→E→F\text{DFS: } A \to B \to D \to C \to (\text{zurück zu } D) \to E \to F

DFS: Von AA geht es zu BB, von BB zu DD, von DD zuerst zu CC (alphabetisch vor EE). CC hat keine unbesuchten Nachbarn mehr, also zurück zu DD und weiter zu EE und FF. Die Besuchsreihenfolge lautet A,B,D,C,E,FA, B, D, C, E, F. Beide Verfahren besuchen alle Knoten, aber in unterschiedlicher Reihenfolge.

Zusammenfassung

  • Ein Graph G=(V,E)G = (V, E) beschreibt Objekte (Knoten) und ihre Verbindungen (Kanten); er kann gerichtet oder ungerichtet sein.

  • Adjazenzliste: Platz O(∣V∣+∣E∣)O(|V|+|E|); Adjazenzmatrix: Platz O(∣V∣2)O(|V|^2).

  • 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 O(∣V∣+∣E∣)O(|V| + |E|) Zeit, wenn besuchte Knoten markiert werden.

Übungen

Aufgabe 1Numerisch

Wie viele Kanten hat der vollständige ungerichtete Graph auf 66 Knoten (jeder Knoten ist mit jedem anderen verbunden)?

Aufgabe 2Multiple Choice

Welche Datenstruktur benutzt die Breitensuche zur Verwaltung der noch zu besuchenden Knoten?

Aufgabe 3Numerisch

Wie viele Kanten hat im Beispielgraphen der kürzeste Weg von AA nach FF (laut Breitensuche)?

Aufgabe 4Freitext

Führe auf dem Graphen mit den Kanten 1 ⁣− ⁣21\!-\!2, 1 ⁣− ⁣31\!-\!3, 2 ⁣− ⁣42\!-\!4, 3 ⁣− ⁣43\!-\!4, 4 ⁣− ⁣54\!-\!5 eine Breitensuche und eine Tiefensuche ab Knoten 11 durch (kleinere Nachbarn zuerst) und gib jeweils die Besuchsreihenfolge an.