Vorlesung Informatik 2Algorithmen und Datenstrukturen(22 - Graphen)Prof. Th. Ottmann
Vorlesung Informatik 2Algorithmen und Datenstrukturen(22 - Graphen)
Prof. Th. Ottmann
Motivation
Pregel Wie komme ich am besten von Freiburg nach Ulm?
Was ist die kürzeste Rundreise durch eine gegebene Menge vonStädten?
Welche Menge an Wasser kann die Kanalisation von Freiburg maximalverkraften?
Gibt es einen Rundweg über die Brücken von Königsberg (Kaliningrad),derart dass jede Brücke nur einmal überquert wird und man zumAusgangspunkt zurückgelangt?
Diese und viele andere Probleme lassen sich als Graphenproblemedefinieren.
V x V E Í E v v Î ´) , ( ¥ < V Definition: Ein gerichteter Graph G = (V,E) (englisch: digraph) besteht auseiner Menge V = {1, 2, . . . , |V |} von Knoten (englisch: vertices) und einerMenge von Pfeilen oder Kanten (englisch: edges, arcs). EinPaar heißt Pfeil oder Kante von v nach v´.
Darstellung:
Knoten werden durch Punkte dargestellt und
Kanten bzw. Pfeile werden durch Verbindungslinien mit Pfeilspitze aufden Endknoten dargestellt.
Einschränkung: Endliche Graphen, d.h.
Adjazenzmatrizen
î í ì Î Ï = ; falls ; falls E j i E j i a ij ) , ( 1 ) , ( 0 Adjazenzmatrizen dienen der Speicherung von Graphen.
Ein Graph G = (V,E) wird in einer Boole’schen |V | x |V |-MatrixAG = (aij), mit 1 i |V |, 1 j |V | gespeichert, wobei
class graph{ graph(int n){ this.numberOfNodes = n; this.a = new boolean[n][n]; } private int numberOfNodes; private boolean[][] a;}
Bei der Speicherung eines Graphen mit Knotenmenge V in einerAdjazenzmatrix ergibt sich ein Speicherbedarf von Θ(|V |2).
Dieser Speicherbedarf ist nicht abhängig von der Anzahl der Kantenim Graphen.
Demnach sind Adjazenzmatrizen ungünstig, wenn der Graphvergleichsweise wenige Kanten enthält.
Wegen der erforderlichen Initialisierung der Matrix oder derBerücksichtigung aller Einträge der Matrix benötigen die meistenAlgorithmen Ω(|V |2) Rechenschritte.
Adjazenzlisten
E j i Î ) , ( Bei Adjazenzlisten wird für jeden Knoten eine lineare, verketteteListe der von diesem Knoten ausgehenden Kanten gespeichert.
Die Knoten werden als lineares Feld von |V | Anfangszeigern auf jeeine solche Liste verwaltet.
Die i-te Liste enthält ein Listenelement mit Eintrag j für jedenEndknoten eines Pfeils .
Adjazenzlisten unterstützen viele Operationen, z.B. das Verfolgen vonPfeilen in Graphen, sehr gut.
Andere Operationen dagegen werden nur schlecht unterstützt,insbesondere das Hinzufügen und Entfernen von Knoten.
Implementierung von Adjazenzlisten
class graphAL{ graphAL(int n){ this.numberOfNodes = n; this.edgeTo = new edge[n]; } private int numberOfNodes; private edge[] edgeTo;}
class edge { edge(int node, edge next){ this.node = node; this.next = next; } int node; edge next;}
Ein Beispiel
3 7 2 6 4 6 5 8 5 1 1 2 3 4 5 6 7 8 9
Doppelt verkettete Kantenliste
Die bei Adjazenzlisten fehlende Dynamik kann erreicht werden, indemman die Knoten in einer doppelt verketteten Liste speichert, anstattsie in einem Feld fester Größe zu verwalten.
Jedes Listenelement dieser Liste enthält drei Verweise, zwei davonauf benachbarte Listenelemente und einen auf eine Kantenliste, wiebei Adjazenzlisten.
Jede Kantenliste ist doppelt verkettet; statt einer Knotennummerbesitzt jedes Kantenlistenelement einen Verweis auf ein Element derKnotenliste.
Doppelt verkettete Kantenliste am Beispiel
1 2 3 4 5 6 7 8 9
Durchlaufen von Graphen
Für manche Probleme ist es wichtig Graphen vollständig zutraversieren, d.h. alle Knoten eines Graphen zu betrachten.
Fasst man die Web-Seiten im Internet als Knoten und die Links aufdiesen Seiten als Kanten auf, so muss man beim Suchen nach einembestimmten Schlüsselwort alle Knoten dieses Web-Seiten-Grapheninspizieren.
Das Betrachten oder Inspizieren eines Knotens in einem Graphen nenntman auch oft Besuchen des Knotens.
Manchmal ist es wichtig die Knoten nach einer gewissen Systematikzu besuchen.
Wir werden im Folgenden die Tiefensuche und die Breitensuche alszwei Spezialfälle eines allgemeinen Knotenbesuchsalgorithmuskennen lernen.
Ein allgemeines Schema für das Traversieren
Im Gegensatz zu Bäumen kann es bei Graphen Zyklen geben.
Deswegen kann es beim Traversieren passieren, dass wir bei einemschon einmal besuchten Knoten ankommen.
Aus diesem Grund müssen wir uns die bereits besuchten Knoten ineiner Tabelle merken, um Endlosschleifen zu vermeiden.
Da jeder Knoten mehrere Nachfolger haben kann, müssen wir darüberhinaus eine Datenstruktur verwenden, in der wie die noch zubesuchenden Knoten ablegen.
Allgemeiner Knotenbesuchsalgorithmus für einen Graphen G = (V,E)
Konkrete Traversierungsverfahren
Die Reihenfolge, in der die Knoten ausgegeben werden, hängtoffensichtlich von der Datenstruktur für den Rand ab, d. h. der Art, wie dieKnoten darin abgelegt werden.
Verwendet man für die Knotenliste einen Stack, so ergibt sich einTiefendurchlauf durch den Graphen.
Verwendet man hingegen eine Queue, so entspricht das Verhalten einemBreitendurchlauf.
8 9 1 2 3 6 7 5 4 V v Î Definition: Das Single-Source-Shortest-Path-Problem besteht darin, füreinen Graph G = (V,E) und einen Knoten die kürzesten Pfade vonv zu allen anderen Knoten in G zu bestimmen.
Beispiel:
Graph g Kürzeste Pfade ausgehend von Knoten 1
1 2 1 3 1 7 1 7 5 1 7 5 4 1 7 5 4 6
Lösung des Single-Source-Shortest-Path-Problems
Der Knoten v ist von sich selbst genau 0 Schritte weit entfernt.
Die Nachbarn von v sind genau 1 Schritt entfernt.
Die Knoten der Entfernung j sind alle Knoten, die von den j -1Schritt entfernten in genau einem Schritt erreicht werden können.
Also können wir dieses Problem durch einen Breitendurchlauf lösen.
Anstelle der Besucht-Markierungen verwenden wir jedoch ein Felddistance, um den Abstand der einzelnen Knoten abzulegen.
Dabei ist |V | - 1 die Maximaldistanz eines Knoten von v.
Damit ist die Komplexität bei Verwendung von AdjazenzlistenO(|V | + |E|).
Comments