Algorithmik 1 Prof. Dr. Michael Philippsen Handy aus! M. Philippsen Friedrich-Alexander-Universität Erlangen-Nürnberg Informatik 2 • Programmiersysteme Martensstraße 3 • 91058 Erlangen Graph-Grundlagen Darstellung von Graphen im Rechner Euler-Pfad Graph-Traversierung Topologische Sortierung Kürzeste Pfade Minimaler Spannbaum Transitive Hülle Matching Kapitel 17 - Graphalgorithmen 17.1 17.2 17.3 17.4 17.5 17.6 17.7 17.8 17.9 Algorithmik 1, WS 2003/04, Folie 17-3 Friedrich-Alexander-Universität Erlangen-Nürnberg 17.1 Graph-Grundlagen v2 v4 v5 Übliche graphische Darstellung: v1 v3 M. Philippsen v6 v7 Ein ungerichteter Graph ist ein Graph G=(V,E) für den gilt: für alle vi,vj V: (vi,vj) E (vj,vi) E. E ist symmetrisch. In der graphischen Darstellung gehört zu jedem Pfeil ein Pfeil in die Gegenrichtung. Statt Pfeilen zeichnet man daher spitzenlose Linien. In der Mengenschreibweise schreibt man [vi,vj] für beide Paare. Beispiel: V={v1,v2,v3,v4,v5,v6,v7} E={[v1,v2], [v2,v3], [v2,v6], [v2,v7], [v5,v3], [v5,v7], [v6,v5], [v7,v6], [v7,v7]} Algorithmik 1, WS 2003/04, Wiederholungsfolie Friedrich-Alexander-Universität Erlangen-Nürnberg Organisatorisches Klausuranmeldung M. Philippsen I&K-Studenten müssen sich zu den Klausuren Mathematik I, Einführung in I&K, Algorithmik I und Digitaltechnik anmelden. Nachfrist: MITTWOCH 28.1. also MORGEN! Lehramt: bis 13.2., natürlich gerne auch früher! Algorithmik 1, WS 2003/04, Folie 17-2 Friedrich-Alexander-Universität Erlangen-Nürnberg 17.1 Graph-Grundlagen reflexive Kante, Schlinge Ein gerichteter Graph ist ein Paar G=(V,E), wobei V eine endliche Menge von Knoten („vertex“) und E eine zweistellige Relation auf V ist, d.h. E V V. Die Elemente von E werden (gerichtete) Kante („edge“) genannt. Knoten M. Philippsen (gerichtete) Kante Übliche graphische Darstellung: Beispiel: v2 V={v1,v2,v3,v4,v5,v6,v7} v7 v1 E={(v1,v2), (v2,v3), (v2,v6), (v2,v7), v6 (v5,v3), (v5,v7), v4 v (v6,v5), 3 v5 (v7,v6), (v7,v7)} Algorithmik 1, WS 2003/04, Wiederholungsfolie Friedrich-Alexander-Universität Erlangen-Nürnberg 17.1 Graph-Grundlagen Ein Pfad (Weg, Kantenzug) von x nach y ist eine endliche Folge von Knoten x=a0, a1, …, ap=y wobei (ai, ai+1) E. p ist Anzahl der Kanten im Pfad und heißt Länge des Pfades Der Pfad verbindet x und y, y ist von x aus erreichbar. Beachte: In unserer Graph-Definition kann es keine "parallelen Kanten (mit gleicher Richtung)" zwischen zwei Knoten geben. Sonst „Multigraph“ M. Philippsen In einem einfachen Pfad kommt jeder Knoten höchstens einmal vor. Algorithmik 1, WS 2003/04, Wiederholungsfolie Friedrich-Alexander-Universität Erlangen-Nürnberg 17.1 Graph-Grundlagen v5 X M. Philippsen zwei (einfache) Pfade von v1 nach v5 vier (einfache) Pfade von v1 nach v5 Pfade im ungerichteten Graph: v1 v1 Pfade im gerichteten Graph: v5 „nicht gegen die Pfeilrichtung“ Algorithmik 1, WS 2003/04, Wiederholungsfolie Friedrich-Alexander-Universität Erlangen-Nürnberg 17.1 Graph-Grundlagen Jeder Knoten ist von jedem anderen Knoten aus erreichbar. X gerichteter Beispielgraph: X X M. Philippsen Diese Knoten sind nicht von jedem anderen Knoten aus erreichbar. X Ein Graph G=(V,E) heißt (stark) zusammenhängend (oder stark verbunden), wenn es für alle x,y V einen Pfad von x nach y gibt. ungerichteter Beispielgraph: X Graph ist nur ohne diesen Knoten zusammenhängend Algorithmik 1, WS 2003/04, Wiederholungsfolie Friedrich-Alexander-Universität Erlangen-Nürnberg 17.1 Graph-Grundlagen … Weglassen von Kanten kann Bäume erzeugen: Ein stark zusammenhängender ungerichteter Graph heißt Baum, wenn es keine Schlingen gibt und wenn es zwischen je zwei verschiedenen Knoten genau einen einfachen Pfad gibt. Ein Knoten, zu dem nur eine Kante führt, heißt Blatt. M. Philippsen Später folgt: Definition vom Bäumen in gerichteten Graphen. Algorithmik 1, WS 2003/04, Wiederholungsfolie Friedrich-Alexander-Universität Erlangen-Nürnberg 17.1 Graph-Grundlagen v5 v7 v6 M. Philippsen Zyklen: • v5, v7, v6, v5 ist minimal • v5, v7, v7, v7, v6, v5 ist nicht minimal • v7, v7 ist minimal • Gibt es mehr minimale Zyklen? Ein Pfad der Länge p 1 von x nach x heißt Zyklus (von x nach x). Ein Zyklus von x nach x heißt minimaler Zyklus (von x nach x), wenn außer x kein anderer Knoten mehr als einmal vorkommt. Algorithmik 1, WS 2003/04, Wiederholungsfolie Friedrich-Alexander-Universität Erlangen-Nürnberg 17.1 Graph-Grundlagen M. Philippsen Der gerichtete Graph ist daher schwach zusammenhängend. gerichteter Beispielgraph (nicht stark zusammenhängend) Ein gerichteter Graph heißt schwach zusammenhängend, wenn der zugehörige ungerichtete Graph (der durch Hinzunahme aller Rückwärtskanten entsteht) zusammenhängend ist. Im gerichteten Graph gibt es keinen Pfad zu diesem Knoten zugehöriger ungerichteter Graph ist zusammenhängend: Algorithmik 1, WS 2003/04, Folie 17-10 Friedrich-Alexander-Universität Erlangen-Nürnberg 17.1 Graph-Grundlagen Ein Graph G'=(V',E') ist ein Teilgraph (Untergraph) eines Graphen G=(V,E) genau dann, wenn V' V und E' E. Ein Teilgraph muss diese Kante nicht enthalten, wohl aber ein induzierter Teilgraph. Ein Graph G'=(V',E') ist ein induzierter Teilgraph eines Graphen G = (V,E) gdw V' V und E' = { (u,v) ∈ E | u,v ∈ V' } M. Philippsen Wähle einige Knoten aus G aus; es „überleben“ in E' alle Kanten, die diese ausgewählte Knoten verbinden Algorithmik 1, WS 2003/04, Wiederholungsfolie Friedrich-Alexander-Universität Erlangen-Nürnberg 17.1 Graph-Grundlagen M. Philippsen … Sind G ein Graph und R ein zyklenfreier Teilgraph von G, der alle Knoten von G enthält, und sind G und R beide zusammenhängend, dann heißt R Spannbaum (aufspannender Baum) von G. Einige Spannbäume: Algorithmik 1, WS 2003/04, Folie 17-13 Friedrich-Alexander-Universität Erlangen-Nürnberg 17.1 Graph-Grundlagen Eine Zusammenhangskomponente Z eines Graphen ist ein zusammenhängender Teilgraph von G, der in keinem anderen zusammenhängenden Teilgraph von G enthalten ist. Z ist also ein maximaler zusammenhängender Teilgraph von G. Folgender Graph hat zwei Zusammenhangskomponenten: M. Philippsen Jeder Graph kann in eindeutiger Weise in die Menge seiner Zusammenhangskomponenten partitioniert werden. Algorithmik 1, WS 2003/04, Folie 17-15 Friedrich-Alexander-Universität Erlangen-Nürnberg 17.1 Graph-Grundlagen 4 3 3 0/1 2/0 1/3 Eingangs-/Ausgangsgrad 3/2 2/1 M. Philippsen Knoten mit Grad 0/* heißen Quelle, Knoten mit Grad */0 heißen Senke. 1/2 gerichteter Beispielgraph: Die Anzahl der direkten Vorgänger eines Knotens heißt Eingangsgrad des Knotens. Die Anzahl der direkten Nachfolger eines Knotens heißt Ausgangsgrad des Knotens. Bei ungerichteten Graphen spricht man vom Grad des Knoten. 0 3 ungerichteter Beispielgraph: 1 2 Grad Algorithmik 1, WS 2003/04, Wiederholungsfolie Friedrich-Alexander-Universität Erlangen-Nürnberg 17.1 Graph-Grundlagen Eine Familie Gi=(Vi,Ei) mit i ∈ {1,…,n} von Teilgraphen heißt Partitionierung eines Graphen G = (V,E) gdw M. Philippsen Partitionierung in 3 Komponenten Jeder Graph Gi wird Komponente von G genannt. 1. jeder Graph Gi zusammenhängend ist und 2. ∀i,j ∈ {1,…,n}, i≠j Vi ∩Vj = ∅ 3. Ui=1...n Vi = V Algorithmik 1, WS 2003/04, Folie 17-14 Friedrich-Alexander-Universität Erlangen-Nürnberg 17.1 Graph-Grundlagen Ist (x,y) E, so heißen x direkter Vorgänger (bei gerichteten Graphen auch: Elternknoten) von y y direkter Nachfolger (bei gerichteten Graphen auch: Kind) von x. Man schreibt x → y Die Kante (x,y) heißt inzident zu x (bzw. zu y). Falls ein Pfad von x nach z führt, so heißen B D A F E M. Philippsen A ist Vorfahr von allen anderen Knoten C und D sind Kinder von B B und E sind Eltern von D F ist Nachkomme von A und von E x Vorgänger (bei gerichteten Graphen auch: Vorfahr) von z z Nachfolger (bei gerichteten Graphen auch: Nachkomme) von x. Man schreibt x →* y C Algorithmik 1, WS 2003/04, Wiederholungsfolie Friedrich-Alexander-Universität Erlangen-Nürnberg 17.1 Graph-Grundlagen Ein stark zusammenhängender ungerichteter Graph heißt Baum, wenn es keine Schlingen gibt und wenn es zwischen je zwei verschiedenen Knoten genau einen einfachen Pfad gibt. Bei gerichteten Graphen sind mehr Begriffe nötig: Wurzel X Wurzelgraph: Wurzel M. Philippsen Gerichteter azyklischer Graph (DAG, „directed acyclic graph“): Gerichteter Graph ohne Zyklen. Ein Knoten v eines DAG heißt Wurzel, falls es keine auf ihn gerichteten Kanten gibt. Hat ein DAG nur eine Wurzel, so heißt er Wurzelgraph. DAG: Wurzel nur zyklenfrei, wenn X entfernt ist. Algorithmik 1, WS 2003/04, Wiederholungsfolie Friedrich-Alexander-Universität Erlangen-Nürnberg 17.1 Graph-Grundlagen Baum: X X Es gibt noch andere Möglichkeiten, um durch Entfernen von Kanten aus dem Graph ein Baum zu machen. Bei gerichteten Graphen ist ein Baum ein Wurzelgraph, in dem zu jedem Knoten genau ein (eindeutiger) Pfad von der Wurzel aus führt. Wurzel Ein DAG mit mehreren Wurzeln, aber eindeutigen Pfaden, heißt Wald. M. Philippsen 17.1 Graph-Grundlagen Aus dieser Baum-Definition folgt: Es gibt (auch bei gerichteten Graphen) keinen Zyklus. Die Wurzel ist der einzige Knoten ohne direkten Vorgänger. Jeder andere Knoten hat genau einen direkten Vorgänger, er kann aber beliebig viele direkte Nachfolger haben. Abweichend zu ungerichteten Graphen definiert man: M. Philippsen Der Grad eines Knotens ist die Anzahl der Nachfolger eines Knotens. (Es werden als nur die Ausgangskanten berücksichtigt.) Der Grad des Baums ist der maximale Grad seiner Knoten. Ein Knoten mit Grad 0, also ohne Nachfolger, heißt Blatt. Alle anderen Knoten heißen innere Knoten des Baums. Algorithmik 1, WS 2003/04, Wiederholungsfolie Friedrich-Alexander-Universität Erlangen-Nürnberg 17.1 Graph-Grundlagen Algorithmik 1, WS 2003/04, Wiederholungsfolie Friedrich-Alexander-Universität Erlangen-Nürnberg 17.1 Graph-Grundlagen Weitere Baum-Begriffe (2) Binärbaum = Baum mit Grad 2 Algorithmik 1, WS 2003/04, Wiederholungsfolie Friedrich-Alexander-Universität Erlangen-Nürnberg 17.1 Graph-Grundlagen Beispiele: * 3 Ausdrucksbaum „Kantorowitsch-Baum“ 5 * (7-3) 5 7 Algorithmik 1, WS 2003/04, Wiederholungsfolie Friedrich-Alexander-Universität Erlangen-Nürnberg Elisabeth Victoria Loius Andrew Alice ist Kind von Olga Georg I Mary Georg VI George V Cecilia Claude Abstammungsbaum Elisabeth II Philip M. Philippsen Charles M. Philippsen Bei binären Suchbäum andere Höhen-Definition: Blätter haben die Höhe 0, Höhe eines Knotens = Länge des längsten Pfades zu einem Blatt. Die Wurzel hat die Höhe 0. Die Höhe aller direkten Nachfolger eines Knotens v ist um 1 größer als die Höhe von v. Die Länge des Pfades von der Wurzel zu einem Knoten k bestimmt die Höhe von k im Baum. Triviale Bäume: leerer Graph; kantenloser Graph mit nur einem Knoten. Unterbäume sind wieder Bäume. Der Unterbaum eines Knotens v im Baum sind v und alle nachfolgenden Knoten plus die verbindenden Kanten. Weitere Baum-Begriffe (1) M. Philippsen 0:1 M. Philippsen 1:1 Unterbaum dieses Knotens: 2:0 2:1 2:0 innerer Knoten 3:1 Blatt Jeder Knoten hat maximal 2 Nachfolger. Man spricht vom rechten/linken Kind (Nachfolger, Sohn). Wenn bei der graphischen Darstellung von Bäumen klar ist, welcher Knoten die Wurzel ist (und welche Bedeutung die Kante zwischen Elternknoten und Kinderknoten hat), kann man auf die Pfeilspitzen verzichten. Algorithmik 1, WS 2003/04, Wiederholungsfolie Friedrich-Alexander-Universität Erlangen-Nürnberg 1:2 17.1 Graph-Grundlagen 4:0 Am Beispiel: 0:1 Wurzel Blatt n:m = Höhe:Grad Grad des Baums: 2 Algorithmik 1, WS 2003/04, Wiederholungsfolie Friedrich-Alexander-Universität Erlangen-Nürnberg 17.1 Graph-Grundlagen J D F E G 2 4 1 0 0 0 0 1 0 0 1 1 0 1 A B C 3 N Ü R N B E R G H J D E F 300 M. Philippsen M. Philippsen boolean-Werte: true (1) bedeutet, dass es eine Kante von 2 nach 4 gibt. M. Philippsen G Andere Darstellungsformen von Bäumen Einrückungsdarstellung H C Kontour-Darstellung B A Listendarstellung A(B(HJ)C( DE( G)F )) Algorithmik 1, WS 2003/04, Wiederholungsfolie Friedrich-Alexander-Universität Erlangen-Nürnberg 1 17.2 Darstellung von Graphen im Rechner Graphische Darstellung: 0 0 1 0 1 2 3 4 Mengenschreibweise: G = (V,E) mit x y (x,y) ∈ E V V. V={1,2,3,4} E={(1,2), (1,4), (2,3), (2,4), (3,1), (4,4)} Matrixdarstellung: (Adjazenzmatrix) 1 2 3 4 Algorithmik 1, WS 2003/04, Folie 17-27 Friedrich-Alexander-Universität Erlangen-Nürnberg M Ü N C H E N S T U T T G A R T L E I P Z I G K A R L S R U H E - 100 230 250 150 450 400 300 300 70 400 - - LEIPZIG 300 250 450 230 300 300 150 100 70 NÜRNBERG STUTTGART MÜNCHEN KARLSRUHE 17.2 Darstellung von Graphen im Rechner Adjazenzmatrix Entfernungstabelle ist die bekannteste Form der Adjazenzmatrix Algorithmik 1, WS 2003/04, Folie 17-29 Friedrich-Alexander-Universität Erlangen-Nürnberg 17.1 Graph-Grundlagen Ein Graph G=(V,E) wird zu einem bewerteten/gewichteten Graphen, >0 ergänzt, indem man eine Gewichtsfunktion gw:E bzw. gw:E die jeder Kante e E ein positives Gewicht gw(e) zuordnet. c(w) = i=0 p-1 gw(ai,ai+1) Die (bewertete) Länge c(w) eines Pfades w definiert man in gewichteten Graphen als die Summe der Gewichte seiner Kanten: für w = (x=a0, a1, …, ap=y) ist true}, true}, false}, true} M. Philippsen Statt von (bewerteter) Länge spricht man auch von Kosten („cost“) des Pfades w. Algorithmik 1, WS 2003/04, Folie 17-26 Friedrich-Alexander-Universität Erlangen-Nürnberg 3 } boolean [][] kanten = { {false, true, false, {false, false, true, {true, false, false, {false, false, false, 17.2 Darstellung von Graphen im Rechner 2 Adjazenzmatrix 1 4 2 3 1 4 Knoten(1, Knoten(2, Knoten(3, Knoten(4, 4 4 new new new new 1 2 M. Philippsen 3 M. Philippsen Verbindung(2, new Verbindung(4)); Verbindung(3, new Verbindung(4)); Verbindung(1)); Verbindung(4)); 4 Bei ungerichteten Graphen sind Adjazenzmatrizen symmetrisch, es reicht die Speicherung einer Dreiecksmatrix. Graphen ohne Schlingen haben in der Diagonalen stets „false“. Graphen mit wenigen Kanten führen zu spärlich besetzten Matrizen. Bei bewerteten/gewichteten Graphen speichert man statt booleanWerten die Kantengewichte in der Matrix. Fehlende Kanten durch ein Gewicht nahe ausgedrückt. Algorithmik 1, WS 2003/04, Folie 17-28 Friedrich-Alexander-Universität Erlangen-Nürnberg new new new new 1 2 3 4 17.2 Darstellung von Graphen im Rechner = = = = Adjazenzlisten: knoten[1] knoten[2] knoten[3] knoten[4] Bei gewichteten Graphen hat das Verbindungsobjekt Instanzvariablen für die Speicherung des Gewichts. Algorithmik 1, WS 2003/04, Folie 17-30 Friedrich-Alexander-Universität Erlangen-Nürnberg 17.2 Darstellung von Graphen im Rechner Nachfolger von Knoten 1 sind die Knoten 2 und 4. 10 5 2 6 4 7 8 Kanten 3 9 10 1 Als Reihung: 9 4 4 7 3 4 5 2 Knoten 1 Die Nachfolger von Knoten 1 finden sich in der Reihung ab Position 5 (und bis <7) C B 1 A 2 4 3 M. Philippsen D M. Philippsen Bei gewichteten Graphen hat die Reihung zwei „Zeilen“. Gewichte im Kantenteil der 2. Zeile speichern. Algorithmik 1, WS 2003/04, Folie 17-31 Friedrich-Alexander-Universität Erlangen-Nürnberg 17.3 Euler-Pfad Königsberger Brückenproblem: Gibt es einen geschlossenen Pfad, der über alle 7 Brücken führt? Zeichenproblem: Kann das Häuschen mit einem Strich gezeichnet werden? Algorithmik 1, WS 2003/04, Folie 17-33 Friedrich-Alexander-Universität Erlangen-Nürnberg 17.4 Graph-Traversierung Bisher war die Bearbeitung der Eingabe immer einfach: man ist sequentiell vorgegangen und hat ein Eingabe-Element nach dem anderen betrachtet. Aber bei Graphen? Traversierung von Graphen, die jeden Knoten einmal betrachten, ist eine Aufgabe für sich, die in vielen GraphAlgorithmen bewältigt werden muss. Gegeben: Graph G Gesucht: Besuch jedes Knotens Lösungswege: M. Philippsen Tiefensuche Breitensuche Bei Bäumen können spezielle Verfahren angewendet werden, weil keine Zyklen vorliegen. Algorithmik 1, WS 2003/04, Folie 17-35 Friedrich-Alexander-Universität Erlangen-Nürnberg Graphik: + geeignet für einige mathematische Operationen - teure Suche nach Knoten und Kanten + sehr leicht lesbar für Menschen - extrem kompliziert für maschinelle Bearbeitung 17.2 Darstellung von Graphen im Rechner Mengen: + sehr kompakte Darstellung (wenig Speicher), O(|V|+|E|) - kostspielige Suche nach Kanten, O(|E|) Adjazenzmatrix:+ sehr schnell feststellbar, ob eine Kante existiert, O(1) + manche Graphenoperationen lassen sich als Matrizenoperationen darstellen - Speicherverschwendung bei dünnen Graphen, O(n²) Adjazenzliste: + noch kompakter als Liste - aufwändige Änderungen (Einfügen/Löschen) M. Philippsen Reihung: Algorithmik 1, WS 2003/04, Folie 17-32 Friedrich-Alexander-Universität Erlangen-Nürnberg 17.3 Euler-Pfad Pfad, der alle Kanten umfasst und jede genau einmal durchläuft. Eulerscher Pfad: A D als Multigraph, da parallele Kanten C B A D Eulerscher Pfad, bei dem Start- und Endknoten identisch sind. Eulerscher Zyklus: C B M. Philippsen Die Frage, ob ein Eulerscher Zyklus existiert, ist leicht zu beantworten. Idee: Wenn man in einen Knoten kommt, muss man auf anderem Weg wieder herauskommen. Euler zeigte: Es existiert ein Euler-Zyklus gdw. der Grad jedes Knotens durch 2 teilbar ist und der Graph zusammenhängend ist. (Beweisrichtung leicht, Beweisrichtung Übung) Algorithmik 1, WS 2003/04, Folie 17-34 Friedrich-Alexander-Universität Erlangen-Nürnberg 17.4 Graph-Traversierung Grundidee der Tiefensuche (DFS, „depth-first-search“) 13 2 3 7 11 M. Philippsen mögliche Tiefensuch-Reihenfolgen: 2, 13, 5, 1, 3, 7, 11 2, 13, 3, 5, 1, 7, 11 2, 7, 11, 13, 5, 1, 3 2, 7, 11, 13, 3, 5, 1 Besuche zuerst die Kinder jedes Knotens, Absteigen bis zum Blatt, dann zum nächsten Blatt, … 5 1 Algorithmik 1, WS 2003/04, Folie 17-36 Friedrich-Alexander-Universität Erlangen-Nürnberg 17.4 Graph-Traversierung 17.4 Graph-Traversierung Algorithmik 1, WS 2003/04, Folie 17-38 Friedrich-Alexander-Universität Erlangen-Nürnberg 17.4 Graph-Traversierung Rekursion am Beispiel: 13 2 3 7 11 X DFS(7) X DFS(2) DFS(13) Besuch der Nachfolger von links nach rechts 5 1 while-Schleife über die Kanten, die von 2 abgehen, hier v.l.n.r. Algorithmik 1, WS 2003/04, Folie 17-40 Friedrich-Alexander-Universität Erlangen-Nürnberg } } } } Algorithmik 1, WS 2003/04, Folie 17-42 Friedrich-Alexander-Universität Erlangen-Nürnberg X 2 1 3 M. Philippsen DFS(1) M. Philippsen M. Philippsen 5 4 Die Kinder eines Knotens v kommen oben auf den Keller. Ein Kind k wird als erstes besucht. Dessen Kinder kommen wieder oben auf den Keller … Erst wenn alle Enkel (und deren Nachfolger) besucht wurden, kommen die Geschwister von k an die Reihe … Tiefensuche DFS(11) DFS(3) DFS(5) Die Markierung dient dazu, dass der Algorithmus bei allgemeinen Graphen nicht in Endlosschleifen läuft. Es wird nur die Zusammenhangskomponente besucht, in der sich der Startknoten befindet. Startknoten Grundidee der Tiefensuche (DFS, „depth-first-search“) Speicherung als Adjazenzliste: Reihenfolge nicht festgelegt. Jeder Knoten einer Zusammenhangskomponente wird erreicht: sonst gäbe es einen Knoten ohne Markierung, der über eine Kante mit einem markierten Knoten verbunden ist. Das kann nicht vorkommen. X Tiefensuche am Beispiel Besuch eines Museums mit vielen Gängen, wobei man jeden Gang ablaufen möchte. Verfahren: Man läuft in das Museum hinein. Man betritt einen neuen Gang, sobald er sich öffnet. Wenn sich mehrere Gänge gleichzeitig öffnen, wählt man einen (meist den linken). und hinterlässt an der Kreuzung einen Kieselstein. Wenn man an eine Kreuzung stößt, die bereits einen Kiesel hat, kehrt man um und geht den gleichen Weg zurück bis zur vorhergehenden Kreuzung. Wenn von dieser noch ein unausprobierter Gang abgeht, wird dieser erforscht. Gibt es keinen unausprobierten Gang mehr, kann der Kieselstein entfernt werden und weiter zurück gegangen werden. } M. Philippsen Ariadne benutzte ein Garnknäuel, um Theseus die Rückkehr aus dem Labyrinth zu ermöglichen, in dem er den Minotaurus getötet hat. Algorithmik 1, WS 2003/04, Folie 17-37 Friedrich-Alexander-Universität Erlangen-Nürnberg 17.4 Graph-Traversierung Rekursive DFS-Implementierung } void DFS(Graph G, Node v) { v.mark(); Iterator iter = v.getEdges(); while (iter.hasNext()) { Edge e = (Edge) iter.next(); if (e.target.isUnmarked()) { DFS(G, e.target); } M. Philippsen Erweiterung für nicht zusammenhängenden Graph: wiederhole beginnend bei unmarkiertem Knoten Aufwand O(|V|+|E|): • jede der |E| Kanten wird von beiden Seiten betrachtet • zusätzlich gibt es ggf. isolierte Knoten in V Algorithmik 1, WS 2003/04, Folie 17-39 Friedrich-Alexander-Universität Erlangen-Nürnberg 17.4 Graph-Traversierung DFS(1) DFS(3) DFS(7) 17.4 Graph-Traversierung DFS(2) DFS(13) DFS(5) DFS(7) DFS(3) DFS(7) DFS(7) DFS(11) Iterative DFS-Implementierung mit Keller 2 7 DFS(3) DFS(7) M. Philippsen void DFS(Graph G, Node v) { Keller k = new Keller(); k.push(v); //merke Wurzel für Besuch vor while (!k.isEmpty()) { //besuche oberstes Kellerelement v = k.top(); k.pop(); v.mark(); Iterator iter = v.getEdges(); while (iter.hasNext()) { //lege alle Nachfolger auf Keller Edge e = (Edge) iter.next(); if (e.target.isUnmarked()) { k.push(e.target); Keller zur Implementierung der Rekursion 13 3 11 Besuch der Nachfolger von links nach rechts 5 1 Algorithmik 1, WS 2003/04, Folie 17-41 Friedrich-Alexander-Universität Erlangen-Nürnberg 17.4 Graph-Traversierung M. Philippsen Graph wird besucht, um eine bestimmte Aufgabe zu erledigen. Abhängig von der Aufgabe sind zu konkretisieren: • präKnotenArbeit: was ist beim ersten Betreten eines Knotens zu tun? • inKnotenArbeit: was ist zwischen dem Besuchen der Nachfolger zu tun? • postKnotenArbeit: was ist nach Besuch aller Nachfolger zu tun? • kantenArbeit: was ist beim Abstieg zu tun? (Rekursive) DFS-Implementierung mit Nutzarbeit void DFS(Graph G, Node v) { v.mark(); //präKnotenArbeit(v); Iterator iter = v.getEdges(); while (iter.hasNext()) { Edge e = (Edge) iter.next(); if (e.target.isUnmarked()) { //inKnotenArbeit(v); DFS(G, e.target); //kantenArbeitif(e) } //kantenArbeitimmer(e); } //postKnotenArbeit(v); } Aufgabe: ergänzen Sie Nutzarbeit in iterativer Version Algorithmik 1, WS 2003/04, Folie 17-43 Friedrich-Alexander-Universität Erlangen-Nürnberg 17.4 Graph-Traversierung DFS-Anwendungsbeispiel: Knotenzahl des Unterbaums (1) 3 8 6 1 2 1 } } * 7 M. Philippsen void DFSKnotenZahl(Graph G, Node v) { v.mark(); v.zaehler = 1; //präKnotenArbeit(v) Iterator iter = v.getEdges(); while (iter.hasNext()) { Edge e = (Edge) iter.next(); if (e.target.isUnmarked()) { DFSKnotenZahl(G, e.target); } //kantenArbeitimmer(e): v.zaehler += e.target.zaehler; Gegeben: Baum G Gesucht: Bestimmt für jeden Knoten v die Anzahl der Knoten des Unterbaums, der v als Wurzel hat. 1 1 In Bäumen gibt es keine bereits markierten Nachfolger. Algorithmik 1, WS 2003/04, Folie 17-44 Friedrich-Alexander-Universität Erlangen-Nürnberg 5 * (7-3) 573-* - 17.4 Graph-Traversierung - M. Philippsen //Operatoren zwischen den Operanden //Operatoren hinter den Operanden //siehe „Auswertung mit Keller“ //Operatoren stehen vor Operanden //“polnische Notation“ 5 17.4 Graph-Traversierung Betrachte den Ausdruck 5 * (7-3) Darstellung als Ausdrucksbaum: Infix-Form: Postfix-Form: *5-73 ? ang enh amm Zus Präfix-Form: Algorithmik 1, WS 2003/04, Folie 17-46 Friedrich-Alexander-Universität Erlangen-Nürnberg 3 DFS-Anwendungsbeispiel: Ausdrucksbaum (1) D F 3 1 A.zaehler = 1; A B.zaehler = 1; C A.zaehler += B.zaehler // = 2 C.zaehler = 1; E D.zaehler = 1; G H F.zaehler = 1; D.zaehler += F.zaehler // = 2 G.zaehler = 1; D.zaehler += G.zaehler // = 3 C.zaehler += D.zaehler // = 4 8 E.zaehler = 1; 6 H.zaehler = 1; 2 E.zaehler += H.zaehler // = 2 C.zaehler += E.zaehler // = 6 A.zaehler += C.zaehler // = 8 1 DFS-Anwendungsbeispiel: Knotenzahl des Unterbaums (2) B 1 1 M. Philippsen 17.4 Graph-Traversierung Algorithmik 1, WS 2003/04, Folie 17-45 Friedrich-Alexander-Universität Erlangen-Nürnberg 17.4 Graph-Traversierung 5. 6.:„(“ 2.:„5“ 5 1. Besuche Unterbäume (v.l.n.r.) 2. postKnotenArbeit: Drucke Knotensymbol1. Solange „links-abwärts“ wie möglich. Rechtes Kind wird erst besucht, wenn der linke Unterbaum völlig abgearbeitet ist. * 3. 6.:„7“ 4. 5. 7 erzeugte lineare Liste: 5 7 3 - … Algorithmik 1, WS 2003/04, Folie 17-48 Friedrich-Alexander-Universität Erlangen-Nürnberg 7. - 3 9.:„3“ M. Philippsen 8. 11.:„-“ Tiefensuche durch Ausdrucksbaum, dabei Nachfolger v.l.n.r. Postfix/Postorder-Form DFS-Anwendungsbeispiel: Ausdrucksbaum (3) * 3. 7. 7 3 DFS-Anwendungsbeispiel: Ausdrucksbaum (2) 5 8.:„7“ M. Philippsen Tiefensuche durch Ausdrucksbaum, dabei Nachfolger v.l.n.r. Infix/Inorder-Form (nur Binärbäume) 4.: „*“ 2.:„5“ 1. Besuche linken Unterbaum 2. inKnotenArbeit: Drucke Knotensymbol 1. 3. Besuche rechten Unterbaum Zahlen geben die Reigenfolge an, in „“ steht ausgegebener Text erzeugte lineare Liste: 5 * ( 7 - … Algorithmik 1, WS 2003/04, Folie 17-47 Friedrich-Alexander-Universität Erlangen-Nürnberg 36 39 26 41 39 41 43 94 54 57 65 65 97 78 78 92 99 92 94 99 M. Philippsen 97 17.4 Graph-Traversierung DFS mit inKnotenArbeit 27 36 = drucke Wert 27 57 17.4 Graph-Traversierung 10. 3 26 Algorithmik 1, WS 2003/04, Folie 17-50 Friedrich-Alexander-Universität Erlangen-Nürnberg 17.4 Graph-Traversierung Initialisierung: Knoten "ganz links" im Baum } position = treeSet.root; if (position != null) { while (position.left != null) { position = position.left; } alte position neue position Algorithmik 1, WS 2003/04, Folie 17-54 Friedrich-Alexander-Universität Erlangen-Nürnberg } } M. Philippsen M. Philippsen if (position.right != null) { position = position.right; while (position.left != null) { position = position.left; Dann wird zu diesem rechten Nachfolger gegangen und von dort sofort weiter so weit wie möglich nach links unten. Beim next()-Aufruf wird der Knoten position zurück gegeben. Für den nächsten next()-Aufruf wird position fortgeschaltet. Fall 1: Der aktuelle Knoten position (der keinen linken Nachfolger haben kann) hat einen rechten Nachfolger. Tiefensuche-Iterator für Inorder-Besuch (3) 17.4 Graph-Traversierung Algorithmik 1, WS 2003/04, Folie 17-52 Friedrich-Alexander-Universität Erlangen-Nürnberg An der Stelle position geht es nicht mehr nach links weiter, position hat (wenn überhaupt) einen rechten Nachfolger. position Zustand des Iterators muss im Iterator-Objekt gespeichert werden: Instanzvariable position zeigt jeweils auf dasjenige Element, das beim nächsten next()-Aufruf geliefert werden soll. Tiefensuche-Iterator für Inorder-Besuch (1) 54 Inorder-Besuch eines binären Suchbaums liefert sortierte Liste 4. 5. 6.:„-“ 7. 7 11.:„3“ M. Philippsen 43 DFS-Anwendungsbeispiel: Ausdrucksbaum (4) 5 8.:„7“ 9. Tiefensuche durch Ausdrucksbaum, dabei Nachfolger v.l.n.r. 3.:„5“ Präfix/Präorder-Form 1.:„*“ 1. präKnotenArbeit: Drucke Knotensymbol * 2. Besuche Unterbäume (v.l.n.r.) 2. Solange „links-abwärts“ wie möglich. Rechtes Kind wird erst besucht, wenn der linke Unterbaum völlig abgearbeitet ist. erzeugte lineare Liste: * 5 - 7 3 Algorithmik 1, WS 2003/04, Folie 17-49 Friedrich-Alexander-Universität Erlangen-Nürnberg 17.4 Graph-Traversierung Beim Besuchen von Binärbäumen kann man die Tiefensuche iterativ implementieren, ohne einen expliziten Keller zu benötigen. Idee: Die zwei Nachfolger sind ohnehin im Knoten gespeichert und können v.l.n.r. abgefragt werden. Wenn man die aktuelle Besuchsposition kennt kann man beim Rückkehren von unten erkennen, ob man von links unten oder von rechts unten kommt. Wenn man von links unten kommt, dann muss der rechte Nachfolger (und dessen Nachfahren) noch besucht werden Wenn man von rechts kommt, geht‘s weiter Richtung Wurzel zurück M. Philippsen Auf den folgenden Folien wird ein entsprechender Iterator für einen Binärbaum entwickelt, der bei next() den nächsten Knoten gemäß DFS-Reihenfolge liefert. Algorithmik 1, WS 2003/04, Folie 17-51 Friedrich-Alexander-Universität Erlangen-Nürnberg 17.4 Graph-Traversierung Tiefensuche-Iterator für Inorder-Besuch (2) class TreeSetIterator implements java.util.Iterator { // Zu traversierender Baum private TreeSet treeSet; M. Philippsen private Entry position; // Aktuelle Position public TreeSetIterator(TreeSet treeSet) { this.treeSet = treeSet; //ggf. Baum vorher kopieren // Erste Position ist Knoten "ganz links" position = treeSet.root; if (position != null) { while (position.left != null) { position = position.left; } } } public boolean hasNext() { return position != null; } Algorithmik 1, WS 2003/04, Folie 17-53 Friedrich-Alexander-Universität Erlangen-Nürnberg 17.4 Graph-Traversierung Tiefensuche-Iterator für Inorder-Besuch (4) } M. Philippsen //Schleppzeiger Entry previous = position; position = position.parent; if (position.right == previous) { //Fall 2b } else { //Fall 2a Wie unterscheidet man zwischen den Fällen 2a und 2b? Fall 2: Der aktuelle Knoten position (der keinen linken Nachfolger haben kann) hat auch keinen rechten Nachfolger. Rückweg Richtung Wurzel Fall 2a: von links kommend neue position alte position neue position Fall 2b: von rechts kommend alte position 17.4 Graph-Traversierung //Ergebnis konservieren //Fall 1 M. Philippsen if (position == treeSet.root) position = null; //Wurzel erreicht else { Entry prevPosition = position; // Schleppzeiger position = position.parent; // Aufstieg um eins while ( position.right==prevPosition && position!=treeSet.root){ prevPosition = position; position = position.parent; } if (position.right==prevPosition && position==treeSet.root) //Wurzel erreicht position = null; } } return result; //konserviertes Ergebnis zurückgeben position = position.right; while (position.left != null) position = position.left; } else { //Fall 2 public Object next() { Object result = position.value; if (position.right != null) { } Algorithmik 1, WS 2003/04, Folie 17-56 Friedrich-Alexander-Universität Erlangen-Nürnberg 17.4 Graph-Traversierung Algorithmik 1, WS 2003/04, Folie 17-55 Friedrich-Alexander-Universität Erlangen-Nürnberg 17.4 Graph-Traversierung 1 7 8 2 3 4 6 5 1 7 Tiefensuchbaum, „DFS-tree“) auf, einen Spannbaum. Algorithmik 1, WS 2003/04, Folie 17-58 Friedrich-Alexander-Universität Erlangen-Nürnberg M. Philippsen kantenArbeitif baut aus diesen Kanten den sog. DFS-Baum (oder Durchgezogene Kanten verbinden Knoten mit denjenigen Nachfolgern, die die DFS-Nummerierung als noch unmarkiert vorgefunden hat. Startknoten DFS-Anwendungsbeispiel: DFS-Nummerierung/-Baum (2) 2 6 Beweis: Es sei (v,u) Kante von G, v sei bereits besucht. Nach dem Markieren von v werden die Nachfolger von v besucht. Wäre u als erster Nachfolger besucht worden, dann würde (v,u) zu F gehören. Oder u wird besucht, ehe DFS zum Vorgänger von v zurücklehrt, dann ist u Nachfolger von v in T. 8 Knoten mit DFS-Nummern: DFS-Anwendungsbeispiel: DFS-Nummerierung/-Baum (1) Die Tiefensuche durchläuft die Knoten eines Graphen in einer bestimmten Reihenfolge. Wenn jedem Knoten die Position in dieser Reihenfolge zugeordnet wird, ist das eine DFS-Nummerierung. DFS-Nummern sind für viele Graph-Algorithmen nützlich. Umsetzung mit DFS-Algorithmus: Globale Variable dfs = 0 vor dem Start initialisieren präKnotenArbeit(v): v.dfs = dfs++ DFS-Nummer des Knotens wird auf den Wert der globalen Variable gesetzt; diese wird inkrementiert. M. Philippsen 17.4 Graph-Traversierung Algorithmik 1, WS 2003/04, Folie 17-57 Friedrich-Alexander-Universität Erlangen-Nürnberg 17.4 Graph-Traversierung Tiefensuche in gerichteten Graphen: 3 Es gibt keine Querverbindungen M. Philippsen V Tiefensuche(V) durchläuft alle Knoten Tiefensuche(A) durchläuft nur die Knoten A,B und C Algorithmik 1, WS 2003/04, Folie 17-60 Friedrich-Alexander-Universität Erlangen-Nürnberg M. Philippsen Ebenso wie man bei ungerichteten Graphen davon ausgeht, dass der DFS-Algorithmus so lange läuft, bis alle Zusammenhangskomponenten bearbeitet sind, geht man auch bei gerichteten Graphen davon aus, dass DFS so oft mit noch unbesuchten Knoten wiederholt wird, bis alle Knoten besucht worden sind. B C A Prinzip ist gleich wie bei ungerichteten Graphen. Aber Problem: Welcher Teil des Graphen abgesucht wird, hängt vom Startknoten ab: Wichtige Eigenschaft ungerichteter DFS-Bäume 1 7 4 Seien G=(V,E) ein ungerichteter Graph und T=(V,F) ein DFS-Baum von G, dann gilt für alle Kanten e E entweder e F oder e verbindet zwei Knoten von G, von denen einer Vorfahre des anderen in T ist. 6 5 8 Am Beispiel: 2 3 4 5 Algorithmik 1, WS 2003/04, Folie 17-59 Friedrich-Alexander-Universität Erlangen-Nürnberg 1 7 Einen (gerichteten) Zyklus kann es nur geben, wo es eine Rückwärtskante gibt. Rückwärskante („backward edge“) 17.4 Graph-Traversierung 3 Algorithmik 1, WS 2003/04, Folie 17-62 Friedrich-Alexander-Universität Erlangen-Nürnberg M. Philippsen Auf dem Pfad von der Wurzel nach unten setzt man eine boolesche Variable auf true. Man setzt diese Variable auf false, wenn man alle Nachfolger besucht hat, ohne einen Zyklus zu finden. Eine Rückwärtskante (v,w) erkennt man daran, dass die boolesche Variable von w noch immer gesetzt ist. (Bei Vorwärtskanten und Querkanten ist die Variable bereits wieder auf false gesetzt worden.) Erkennung des Zyklus per DFS-Algorithmus: 5 6 17.4 Graph-Traversierung Baumkante („tree edge“) Vorwärskante („forward edge“) Rückwärskante („backward edge“) 2 Zyklenerkennung (1) Definiert für DFS-Baum im gerichteten Graphen: 1 6 7 Querkante („cross edge“), von rechts nach links M. Philippsen 4 Verschiedene Kantenarten in DFS-Bäumen gerichteter Graphen 3 2 Baumkanten sind Teil des Tiefensuchbaums Nicht Teil des Tiefensuchbaums sind Vorwärtskanten verbinden Knoten mit einem Nachkommen Rückwärtskanten verbinden mit einem Vorfahr Querkanten verbinden „nicht direkt verwandte“ Knoten 4 5 Algorithmik 1, WS 2003/04, Folie 17-61 Friedrich-Alexander-Universität Erlangen-Nürnberg 7 6 17.4 Graph-Traversierung 1 17.4 Graph-Traversierung 2 3 5 XX X 2 1 5 M. Philippsen 3 4 M. Philippsen Seien G=(V,E) ein gerichteter Graph und T=(V,F) ein DFS-Baum von G, dann gilt für alle Kanten e=(v,w) E: wenn v.dfs<w.dfs, dann ist v Vorfahre von w in T. Wichtige Eigenschaft gerichteter DFS-Bäume Erkennung des Zyklus per DFS-Algorithmus: mögliche Breitensuch-Reihenfolgen: 2, 13, 7, 5, 3, 11, 1 2, 7, 13, 11, 3, 5, 1 … Algorithmik 1, WS 2003/04, Folie 17-66 X X 5 ist weder Vorfahre von 4 noch von 2. 7 ist nicht Vorfahre von 5. 1 ist aber Vorfahre von 5. Algorithmik 1, WS 2003/04, Folie 17-64 Friedrich-Alexander-Universität Erlangen-Nürnberg 4 Zyklenerkennung (2) Auf dem Pfad von der Wurzel nach unten setzt man eine boolesche Variable auf true. Man setzt diese Variable auf false, wenn man alle Nachfolger besucht hat, ohne einen Zyklus zu finden. Eine Rückwärtskante (v,w) erkennt man daran, dass die boolesche Variable von w noch immer gesetzt ist. (Bei Vorwärtskanten und Querkanten ist die Variable bereits wieder auf false gesetzt worden.) Konkret: M. Philippsen präKnotenArbeit(v): v.onPath = true; knotenArbeitimmer(e): if (e.target.onPath) { Zurücksetzen foundCycle=true; nachdem letzter break; Nachfolger } if (!iter.hasNext()) { besucht wurde. v.onPath=false; } 17.4 Graph-Traversierung Algorithmik 1, WS 2003/04, Folie 17-63 Friedrich-Alexander-Universität Erlangen-Nürnberg 17.4 Graph-Traversierung Breitensuche am Beispiel: 2 7 M. Philippsen Friedrich-Alexander-Universität Erlangen-Nürnberg Grundidee der Breitensuche (BFS, „breadth-first-search“) 13 3 11 Besuche die Knoten eines Graphen also „ebenenweise“: erst alle Knoten mit Höhe 0, dann alle mit Höhe 1, dann alle mit Höhe 2, … 5 1 Algorithmik 1, WS 2003/04, Folie 17-65 Friedrich-Alexander-Universität Erlangen-Nürnberg Implementierung: ersetze den Keller der iterativen DFSImplementierung durch Schlange (FIFO). 5 6 7 Eingangsgrad 0 1 2 3 7 Algorithmik 1, WS 2003/04, Folie 17-70 Friedrich-Alexander-Universität Erlangen-Nürnberg 17.6 Kürzeste Pfade Suche nach einem geschlossenen Pfad durch gegebene Knoten: Wie besucht ein Handlungsreisender alle seine Kunden mit einer Rundreise? S 400 230 300 300 L Suche nach einem „billigen“ Pfad: KA Wie komme ich am billigsten von Stuttgart nach Leipzig? oder beides: Billigste Rundreise? 70 Algorithmik 1, WS 2003/04, Folie 17-72 Friedrich-Alexander-Universität Erlangen-Nürnberg 2 13 7 753 5 3 11 3 11 1 11 1 1 70 KA N 100 M 150 S 400 230 300 300 L M. Philippsen N M. Philippsen 100 M 150 M. Philippsen Es gibt sicher einen Knoten v mit Eingangsgrad 0. (Sonst gäbe es einen Zyklus). Dieser Knoten bekommt die Nummer 1. Für die übrigen n-1 Knoten wird nach Induktionsvoraussetzung eine topologische Sortierung von 2…n“ berechnet. Hypothese: Es ist klar, wie man Graphen mit <n Knoten topol. sortiert Induktionsanfang: Der einzige Knoten eines Graph mit |V|=1 bekommt die Nummer 1; dies ist die topologische Sortierung Induktionsschritt „n-1 n“: 17.5 Topologische Sortierung Algorithmik 1, WS 2003/04, Folie 17-68 Friedrich-Alexander-Universität Erlangen-Nürnberg 1 13 17.4 Graph-Traversierung 4 11 17.4 Graph-Traversierung } 2 M. Philippsen 5 Breitensuche mit Schlange } M. Philippsen prä/post/in sind nicht wohldefiniert. Daher nur arbeit. Iterative BFS-Implementierung mit Schlange } void DFS(Graph G, Nod v) { Schlange s = new Schlange(); k.enq(v); //merke Wurzel für Besuch vor while (!s.isEmpty()) { //besuche vorderstes Schlangenelement v = s.front(); s.deq(); v.mark(); //Arbeit(v); Iterator iter = v.getEdges(); while (iter.hasNext()) { //lege alle Nachf. in Schlange Edge e = (Edge) iter.next(); if (e.target.isUnmarked()) { k.enq(e.target); } Algorithmik 1, WS 2003/04, Folie 17-67 Friedrich-Alexander-Universität Erlangen-Nürnberg 17.5 Topologische Sortierung Beispiel: Eine Menge von Aufgaben muss erledigt werden. Manche Aufgaben hängen von einer anderen Aufgabe ab und können erst begonnen werden, wenn die erste Aufgabe erledigt ist. In welcher Reihenfolge sollten die Aufgaben hintereinander ausgeführt werden? 3 Gegeben: gerichteter azyklischer Graph G=(V,E) mit n Knoten. Gäbe es einen Zyklus, dann kann keine sequentielle Reihenfolge der Aufgaben gefunden werden, die alle Abhängigkeiten berücksichtigt. Gesucht: Nummerierung der Knoten von 1 bis |V|=n, so dass alle Knoten, die von einem Knoten v mit Nummer k aus erreicht werden können, eine Nummer >k haben. 1 Algorithmik 1, WS 2003/04, Folie 17-69 Friedrich-Alexander-Universität Erlangen-Nürnberg 17.5 Topologische Sortierung Algorithmus zum topologischen Sortieren kantenArbeit(e): e.target.indegree++ 1. Traversiere den Graph und berechne für jeden Knoten eine Instanzvariable indegree, die mit dem Eingangsgrad initialisiert wird: 2. Knoten mit indegree==0 werden in einen beliebigen Behälterdatentyp (Liste, Schlange, Keller, …) gesteckt. 3. Initialisiere einen globalen Zähler topolSort = 0 4. Solange der Behälter nicht leer ist: Entnimm einen Knoten v und setze v.topoNr=topolSort++; Für alle direkten Nachfolger w von v Setze w.indegree -= 1; Wenn w.indegree==0 dann füge w in den Behälter ein M. Philippsen Aufwand O(|V|+|E|): indegree-Berechnung O(|V|+|E|), Behälterzugriff O(1), jeder Kante wird einmal berücksichtigt, wenn indegree des Zielknotens verkleinert wird O(|E|). Algorithmik 1, WS 2003/04, Folie 17-71 Friedrich-Alexander-Universität Erlangen-Nürnberg 17.6 Kürzeste Pfade Bemerkungen 17.6 Kürzeste Pfade Algorithmik 1, WS 2003/04, Folie 17-74 5 11 6 24 W 22 25 c(sp(v,x))=13 c(sp(v,y))=17 c(sp(v,z))=19 3 8 Friedrich-Alexander-Universität Erlangen-Nürnberg y Algorithmik 1, WS 2003/04, Folie 17-76 Friedrich-Alexander-Universität Erlangen-Nürnberg v V2={w,x} V3={w,x,y} Vk z Vk+1 z w w der Knoten mit dem kürzestem Abstand zu v die 2 Knoten … die 3 Knoten … M. Philippsen Wegen der gestrichelten Kante könnte es in Vk+1 einen billigeren Weg zu z geben als vorher in Vk. Sei w der Knoten, mit dem k+1-kleinsten Abstand zu v. M. Philippsen Suche denjenigen Knoten w Vk, der den k+1-kleinsten Abstand zu v hat. Induktionsschritt „k k+1“: Die Menge Vk der k Knoten, die am nächsten an v liegen, ist bekannt. In Vk ist also der Knoten mit dem kürzesten Abstand zu v, mit dem zweitkleinsten Abstand zu v, …, mit dem k-kleinsten Abstand zu v. Induktionsannahme: 3 Betrachte Knoten v und alle seine abgehenden Kanten. Offensichtlich: Wenn (v,w) die kürzeste Kante ist, die von v abgeht, dann ist w der Knoten, der am nächsten an v liegt. V1={w} v x w 2 1 M. Philippsen Widerspruchsbeweis: Angenommen es gäbe einen kürzeren Pfad p“ von vi nach vj. Dann kann in p p‘ durch p“ ersetzt werden, der entstehende Pfad von v0 nach vk wäre kürzer als p. Für jeden kürzesten Pfad p = (v0, v1, ..., vk) von v0 nach vk ist jeder Teilpfad p‘ = (vi, ..., vj), 0≤i<j ≤k, ein kürzester Pfad von vi nach vj. 2 In gerichteten Graphen gilt natürlich nicht, dass der kürzeste Pfad von v nach w der gleiche ist wie der von w nach v. Suche nach dem kürzesten Pfad Gegeben: Gesucht: Ein Graph, zwei Knoten v und w. Der (nach Anzahl der Kanten) kürzeste Pfad von v nach w. v w Verallgemeinerung: Pfadlänge nicht durch Kantenzahl bestimmt, sondern durch Summe der Kantengewichte (die alle positiv sein sollen). Beispiel: Gegeben: Eine Straßenkarte mit Entfernungsangaben zwischen Kreuzungen Finde die kürzeste Route von Erlangen nach Berlin Aufgabe: M. Philippsen 17.6 Kürzeste Pfade Algorithmik 1, WS 2003/04, Folie 17-73 Friedrich-Alexander-Universität Erlangen-Nürnberg 17.6 Kürzeste Pfade Algorithmus von Dijkstra (1) X Y Z Induktionsbeginn: Grundidee für kürzeste Pfade 13 17 Angenommen man kennt die kürzesten Pfade („shortest path“, sp) zu allen direkten Vorgängern eines Knoten w. V 19 Zur Erinnerung: c(w) = Kosten des Pfads w. Dann ist c(sp(v,w)) = min( c(sp(v,x)) + c(x,w), c(sp(v,y)) + c(y,w), c(sp(v,z)) + c(z,w)) = min(24,22,25)=22 M. Philippsen 17.6 Kürzeste Pfade Algorithmik 1, WS 2003/04, Folie 17-75 Friedrich-Alexander-Universität Erlangen-Nürnberg 17.6 Kürzeste Pfade Die Kosten des Pfades von v zu diesem Knoten seien c. Effizienzverbesserung Algorithmus von Dijkstra (3) Induktionsschritt „k k+1“: w Einer dieser Knoten ist der gesuchte k+1-te Knoten Algorithmik 1, WS 2003/04, Folie 17-78 Friedrich-Alexander-Universität Erlangen-Nürnberg Die Kosten des Pfades von v zu diesem Knoten bleiben unverändert! v Algorithmus von Dijkstra (2) Vk Suche denjenigen Knoten w Vk, der den k+1-kleinsten Abstand zu v hat. Der kürzeste Pfad von v nach w kann nur durch Vk laufen, nur die letzte Kante kann einen Knoten u Vk mit w verbinden. (Sonst wären andere Knoten in Vk.) Dann ist (siehe „Grundidee“) der Knoten w mit minimalen Kosten c(sp(v,w)) = minu Vk ( c(sp(v,u)) + c(u,w) ) der gesuchte k+1-te Knoten. v M. Philippsen Problem: Aufwändige Berechnung der Kosten für alle w Vk Algorithmik 1, WS 2003/04, Folie 17-77 Friedrich-Alexander-Universität Erlangen-Nürnberg 17.6 Kürzeste Pfade Algorithmus von Dijkstra auf einen Blick 17.6 Kürzeste Pfade Effizienzverbesserung + ? < 4 D V B 5 12 8 2 1 Algorithmik 1, WS 2003/04, Folie 17-80 Friedrich-Alexander-Universität Erlangen-Nürnberg Minimumsauswahl: Algorithmik 1, WS 2003/04, Folie 17-82 Friedrich-Alexander-Universität Erlangen-Nürnberg M. Philippsen Die Halde ist die ideale Datenstruktur für die Suche nach dem Knoten w mit minimalem Pfad. O(1) für Zugriff auf das Minimum, O(log2|V|) für das Entfernen von w aus der Halde. Insgesamt sind |V| Knoten zu suchen & entfernen: O(|V| log2|V|) M. Philippsen 1. Minimumsauswahl: wähle/besuche einen Knoten w, mit w.sp minimal (1. Iteration: nur v.sp=0, daher wird v gewählt) 2. Aktualisierung: Für alle Kanten (w,z) zu unbesuchten z: Wenn (w.sp + c(w,z) < z.sp) dann setze z.sp := w.sp + c(w,z) (1. Iteration: Kosten der direkten Nachfolger von v werden gesetzt.) Solange nicht besuchte Knoten existieren Markiere alle Knoten als unbesucht. Setze v.sp=0 und w.sp= für alle w v Algorithmus von Dijkstra (4) w z D D C M. Philippsen Gestrichelte Kanten bilden den Spannbaum kürzester Pfade. 3 C M. Philippsen wenn ja: gespeicherten min. Pfad zu z aktualisieren Speichere die Kosten der kürzesten Wege zu Knoten außerhalb von Vk. Diese Kosten können meistens unverändert als Kosten der kürzesten Wege zu Knoten außerhalb von Vk+1 übernommen werden. Nur die Pfade zu w‘ Vk+1, die über den neuen Knoten w (w Vk, aber w Vk+1) führen, könnten sich verbilligen (oben: gestrichelte Kante). v gespeicherter min. Pfad zu z Algorithmik 1, WS 2003/04, Folie 17-79 Friedrich-Alexander-Universität Erlangen-Nürnberg 4 V B 5 12 A 8 2 1 3 C B 12 Wahl 8 minWahl 13 12 11min- D 17.6 Kürzeste Pfade D V B 5 12 A 8 2 1 4 A 5 minWahl 10minWahl 4 17.6 Kürzeste Pfade V B 5 12 A 8 2 1 3 C Aufwand von Dijkstras Algorithmus (1) D V 0 3 C Algorithmus von Dijkstra am Beispiel A 4 V B 5 12 A 8 2 1 3 C bisher gefundene billigste Wege besucht 17.7 Minimaler Spannbaum Algorithmik 1, WS 2003/04, Folie 17-81 Friedrich-Alexander-Universität Erlangen-Nürnberg 17.6 Kürzeste Pfade Beispiel-Problem: Aktualisierung: Algorithmik 1, WS 2003/04, Folie 17-84 oder Was ist besser? Friedrich-Alexander-Universität Erlangen-Nürnberg M. Philippsen Gegeben: Eine Landkarte als Graph G. Gesucht: Es soll ein Wasserleitungsnetz mit minimalen Kosten aufgebaut werden, das alle Ortschaften versorgt. Die Gesamtkosten des Netzes sind proportional zur Summe der Längen aller vorkommenden Leitungen. Ähnliche Probleme gibt es beim Entwurf von Rechnernetzen. Aufwand von Dijkstras Algorithmus (2) Für jeden Knoten w müssen dessen Nachfolger z gefunden und ggf. die Pfade zu z korrigiert werden. Die Halde unterstützt die Suche nach z nicht. Daher ist eine Reihung erforderlich, die für jedes z dessen Position in der Halde angibt. Die Korrektur der Pfadlänge zu z macht eine Umsortierung der Halde erforderlich O(log2|V|) Insgesamt führen |E| Kanten zu solchen Aktualisierungen: O(|E| log2|V|) M. Philippsen Gesamtaufwand: O((|E|+|V|) log2|V|) Mit sog. Fibonacci-Halden geht es noch besser: O(|E|+|V| log2|V|), das sprengt aber den Rahmen der Algorithmik-1. Algorithmik 1, WS 2003/04, Folie 17-83 Friedrich-Alexander-Universität Erlangen-Nürnberg 17.7 Minimaler Spannbaum Erster Ansatz: 17.7 Minimaler Spannbaum C O(|V| (|E| + |V| log|V|)). Algorithmik 1, WS 2003/04, Folie 17-86 Friedrich-Alexander-Universität Erlangen-Nürnberg M. Philippsen Man kann den minimalen Spannbaum finden, indem man den Spannbaum kürzester Pfade für jeden Knoten berechnet und dann den kleinsten dieser Spannbäume auswählt. In jedem Schritt wurde eine Kante so hinzugefügt, dass der entstehende Pfad minimale Länge hatte. Aufwand: O(|E| + |V| log|V|). Der Algorithmus für die Suche nach dem kürzesten Pfad lieferte für einen gegebenen Knoten einen Spannbaum kürzester Pfade. Aufgabe: Gegeben: Ein ungerichteter Graph mit Kantengewichten. Gesucht: Zusammenhängender Teilgraph der alle Knoten enthält, wobei die Summe der Kantengewichte minimal ist. Eigenschaft: Der gesuchte Teilgraph ist azyklisch: Denn gäbe es einen Zyklus, dann könnte man zumindest eine Kante entfernen (also Kosten verringern) und trotzdem alle Knoten erreichen. Also ist der gesuchte Teilgraph ein Baum. Genauer, ein Spannbaum (aufspannender Baum) M. Philippsen 17.7 Minimaler Spannbaum Algorithmik 1, WS 2003/04, Folie 17-85 Friedrich-Alexander-Universität Erlangen-Nürnberg 17.7 Minimaler Spannbaum Algorithmus von Prim (2) Algorithmik 1, WS 2003/04, Folie 17-88 Friedrich-Alexander-Universität Erlangen-Nürnberg A 1 B 12 F C 2 6 4 11 9 H I T w u M. Philippsen (u,w) sei die billigste Kante, die einen Knoten von T mit einem Knoten außerhalb von T verbindet. (u,w) gehört zum minimalen Spannbaum. Andernfalls gäbe es einen Pfad von irgendeinem Knoten aus T zu w mit niedrigeren Kosten. Da jeder Pfad T verlassen muss, hat dieser Pfad mindestens die Kosten der ersten Kante, die T verlässt. Diese sind aber höher als die Kosten der Kante (u,w). zu T gehörig Die Kante mit dem kleinsten Gewicht, die einen zu T benachbarten Knoten verbindet, wird zum minimalen Spannbaum hinzugenommen. Zweiter Ansatz: Algorithmus von Prim (1) T Angenommen man hat einen Teilgraph T von G gefunden, der auch Teilgraph des minimalen Spannbaums ist. Wie kann man T um eine weitere Kante vergrößern? zu T gehörig M. Philippsen Es gibt Knoten, die über eine Kante mit T verbunden sind, die aber noch nicht zu T gehören. Algorithmik 1, WS 2003/04, Folie 17-87 Friedrich-Alexander-Universität Erlangen-Nürnberg 12 17.7 Minimaler Spannbaum B D 17.7 Minimaler Spannbaum 1 F G 19 1317 22 28 Algorithmik 1, WS 2003/04, Folie 17-90 Friedrich-Alexander-Universität Erlangen-Nürnberg M. Philippsen Knoten D kommt hinzu. Zu untersuchende Kanten, sortiert: (EF)-11 (BC)-12 (EH)-17 (DG)-19 Knoten A kommt hinzu. Zu untersuchende Kanten, sortiert: (AD)-2 Wegen Hinzunahme (ED)-6 von D wird diese (EF)-11 Kante gestrichen. (BC)-12 (EH)-17 Algorithmus von Prim am Beispiel (2) A 2 6 4 11 9 I M. Philippsen Zu untersuchende Kanten, sortiert: (BA)-1 Mit Knoten B kommen (ED)-6 neue Kanten hinzu, (EF)-11 einsortieren. (BC)-12 (EH)-17 Starten wir zum Beispiel mit Knoten E E gehört sicher zum Spannbaum Zu untersuchende Kanten, sortiert: (EB)-4 (ED)-6 Minimum (EF)-11 (EH)-17 Algorithmus von Prim am Beispiel (1) D H 19 1317 22 28 G Algorithmik 1, WS 2003/04, Folie 17-89 Friedrich-Alexander-Universität Erlangen-Nürnberg C 1 B 12 F C 2 6 4 11 9 A 17.7 Minimaler Spannbaum 12 dito H I Knoten G kommt hinzu. Zu untersuchende Kanten, sortiert: (HI)-22 (FI)-28 M. Philippsen Knoten I kommt hinzu. Keine Kanten mehr zu untersuchen. Minimaler Spannbaum gefunden. Es ist garantiert, dass kein Zyklus entsteht. Algorithmik 1, WS 2003/04, Folie 17-94 Friedrich-Alexander-Universität Erlangen-Nürnberg M. Philippsen Jetzt kann man die Kanten nacheinander betrachten und sofort entscheiden, ob die Kante zur Lösung gehört oder nicht. einen vorhandenen Baum um einen noch nicht betrachteten Knoten erweitert zwei noch nicht betrachtete Knoten verbindet (zu einem neuen Baum) zwei verschiedene Bäume verbindet Statt einen Teilgraph des Minimalen Spannbaum in jedem Schritt um eine Kante zu erweitern, beginnt man mit einem Wald von einzelnen Knoten und fügt diese nach und nach zum Minimalen Spannbaum zusammen. Beginne mit sortierter Kantenliste in aufsteigender Reihenfolge Kante gehört zur Lösung, wenn sie Dritter Ansatz: Algorithmus von Kruskal (1) 17.7 Minimaler Spannbaum Algorithmik 1, WS 2003/04, Folie 17-92 Friedrich-Alexander-Universität Erlangen-Nürnberg G 19 1317 22 28 D 17.7 Minimaler Spannbaum B F dito Knoten H kommt hinzu. Zu untersuchende Kanten, sortiert: (HG)-13 (DG)-19 (HI)-22 (FI)-28 Algorithmus von Prim am Beispiel (4) 1 I Knoten F kommt hinzu. Zu untersuchende Kanten, sortiert: (FC)-9 Wegen Hinzunahme (BC)-12 von C wird diese (EH)-17 Kante gestrichen. (DG)-19 (FI)-28 M. Philippsen Knoten C kommt hinzu. Zu untersuchende Kanten, sortiert: (EH)-17 (DG)-19 (FI)-28 Algorithmus von Prim am Beispiel (3) A 2 6 4 11 9 H 19 1317 22 28 D G Algorithmik 1, WS 2003/04, Folie 17-91 Friedrich-Alexander-Universität Erlangen-Nürnberg 17.7 Minimaler Spannbaum Beachte die Analogie zu Dijkstras Algorithmus: Minimumauswahl unter den Kanten, die aus T herausführen. T vergrößern. Aktualisierung und gleiche Idee zur Effizienzverbesserung: Statt alle Kanten, die aus dem neuen T herausführen, neu zu untersuchen, aktualisiert man die Kosten der billigsten Kante aus T für alle Nachbarknoten von w. Durch diese Änderung berechnet der selbe Algorithmus den minimalen Spannbaum Natürlich mit dem gleichen Gesamtaufwand: O(|E|+|V| log2|V|) M. Philippsen 17.7 Minimaler Spannbaum Algorithmik 1, WS 2003/04, Folie 17-93 Friedrich-Alexander-Universität Erlangen-Nürnberg 17.7 Minimaler Spannbaum dito Sortierte Kantenliste (hier nur Gewichte): 1 2 4 6 9 11 12 13 17 19 22 28 Andere Sichtweise: 12 entfällt, da Zyklus entstünde M. Philippsen " # $ " & %$ !" Algorithmik 1, WS 2003/04, Folie 17-96 ! Friedrich-Alexander-Universität Erlangen-Nürnberg ! ' (! " ! M. Philippsen Induktion: Zu jedem Zeitpunkt haben wir einen Wald minimal spannender Bäume. Induktionsanfang: Jeder Knoten ist für sich ohne Kanten ein minimal spannender Baum. Induktionsschritt: Vereinige durch Hinzufügen zwei Bäume zu einem, so dass dieser seine Knoten auch minimal aufspannt. Algorithmus von Kruskal am Beispiel 1 2 6 4 11 9 19 1317 22 28 Algorithmik 1, WS 2003/04, Folie 17-95 Friedrich-Alexander-Universität Erlangen-Nürnberg 17.7 Minimaler Spannbaum Aufwand von Kruskals Algorithmus (1) 17.7 Minimaler Spannbaum e H vkx vl1 vl2 vl3 … vly kürzere Liste wird angehängt, O(1) G: Verweis auf Identifikator der Zusammenhangskomponente Anfangs eine Komponente für jeden Knoten. Aufwand des Zyklentests: Beim Einfügen von (vi,vj) wird überprüft, ob vi und vj in derselben Zusammenhangskomponente liegen. Dann Zyklus. Aufwand des Tests: O(1) vk1 vk2 vk3 vkx M. Philippsen Zusammengangskomponente mit x Knoten, nämlich vk1, …, vkx Baumerweiterung: Konkatenation und Zeigerkorrektur x vl1 vl2 vl3 … vly … Vn-1 y Algorithmik 1, WS 2003/04, Folie 17-100 Friedrich-Alexander-Universität Erlangen-Nürnberg M. Philippsen Transitive Hülle von G: Gegeben ein gerichteter Graph G=(V,E). Die transitive Hülle C=(V,F) von G ist ein gerichteter Graph, in dem es genau dann eine Kante (v,w) VxV gibt, wenn es in G einen gerichteten Pfad v *w gibt. 17.8 Transitive Hülle Algorithmik 1, WS 2003/04, Folie 17-98 Friedrich-Alexander-Universität Erlangen-Nürnberg vn … … v5 v4 v3 v2 v1 Jede Kante wird aus der Halde entfernt: O(|E| log2|V|) Aufwand für Baumerweiterung und Test auf Zyklenfreiheit? Daraus dann Beweis für Korrektheit: Induktionsanfang: trivial. Induktionsschritt: G M. Philippsen Nach Induktion gilt, dass der Teilgraph G ein minimaler Spannbaum ist und ebenso Teilgraph H. Nach Verfahren ist e die kürzeste Kante, die G und H verbindet. G∪H∪e ist auch minimal, weil G∪H∪f nicht besser sein kann, und eine „Umordnung“ G oder H „länger“ macht. Würde man G und H mit mehr als einer Kante verbinden, würde ein Zyklus entstehen, außer man entfernt dafür andere (kürzere) Kanten Summe wieder länger. Algorithmik 1, WS 2003/04, Folie 17-97 Friedrich-Alexander-Universität Erlangen-Nürnberg 17.7 Minimaler Spannbaum Aufwand von Kruskals Algorithmus (2) O(|E| log2|V|) x+y vk1 vk2 vk3 … Wenn bei der Baumerweiterung eines Knotens der Zeiger kopiert wird, dann war der Knoten in der kleineren Gruppe. Das kann insgesamt höchstens log2|V| mal der Fall sein, weil dann der Spannbaum erreicht ist. Da jede Kante einmal betrachtet wird, ergibt sich als Gesamtkosten der Baumerweiterung Aufwand für Baumerweiterung? v1 v2 v3 v4 v5 … … Vn-1 vn gestrichelt: y Zeiger werden korrigiert. M. Philippsen Gesamtaufwand O(|E| log2|V|) 17.9 Matching Algorithmik 1, WS 2003/04, Folie 17-99 Friedrich-Alexander-Universität Erlangen-Nürnberg 17.8 Transitive Hülle Bipartiter Graph: Algorithmik 1, WS 2003/04, Folie 17-102 Friedrich-Alexander-Universität Erlangen-Nürnberg M. Philippsen Bäume sind bipartit (ebenenweise aufteilen) Satz von König: Graphen ohne Zyklen mit ungrader Kantenanzahl sind bipartit. (Aufteilung: Graph traversieren und dabei Markierungsbit auf alternierend/jeweils invers zum Vorgänger setzen.) Männer / Frauen im Tanzkurs Arbeiten / Arbeitskräfte Koffer / Schließfächer usw. Praktische Relevanz: Viele Zuordnungsprobleme ordnen Dinge verschiedener Arten einander zu, z.B. Ungerichteter Graph G=(U ∪V,E) mit U∩V = ∅ und nur Kanten [v1, v2] ∈ E mit v1∈U, v2∈V. In diesem Abschnitt betrachten wir nur ungerichtete Graphen. Lösung durch Reduktion auf ein anderes Problem M. Philippsen Die transitive Hülle kann man finden, indem man das Problem auf ein anderes (bekanntes) Problem reduziert. Sei G‘=(V,E‘) ein vollständig verbundener Graph („jeder mit jedem“). Jeder Kante e E‘ hat das Gewicht 0, wenn sie auch Kante in G ist (e E) und 1 sonst. Es gibt also einen von v nach w in G, wenn der kürzeste Pfad zwischen v und w in G‘ die Länge 0 hat. Berechne die Länge aller kürzesten Pfade für jeden Knoten aus G‘; dann kann die Transitive Hülle abgelesen werde. Algorithmik 1, WS 2003/04, Folie 17-101 Friedrich-Alexander-Universität Erlangen-Nürnberg 17.9 Matching Beispiel Maria Heino Uwe Pia Eva Gegeben: Wir befinden uns im Tanzkurs. Jeder Teilnehmer (Knoten) weiß, mit wem er gerne tanzt (Kante). Bestimme mögliche Paarungen. Aufgabe: Klaus Lilo Martin M. Philippsen 17.9 Matching Klaus Heino Maria Lilo Eva Pia Uwe Martin Es ist ja noch ein Herr und eine Dame übrig geblieben! M. Philippsen Drei Paare sind gefunden (gestrichelt), aber nicht jeder Knoten hat einen Partner, und es sind keine weiteren Paarungen möglich. Frage: Wie kriegt man eine optimale Paarbildung zustande? Algorithmik 1, WS 2003/04, Folie 17-104 Friedrich-Alexander-Universität Erlangen-Nürnberg 17.9 Matching Algorithmik 1, WS 2003/04, Folie 17-103 Friedrich-Alexander-Universität Erlangen-Nürnberg 17.9 Matching Definitionen Tutorien … Algorithmik 1, WS 2003/04, Folie 17-106 Friedrich-Alexander-Universität Erlangen-Nürnberg M. Philippsen Zwei Kanten (u,v) und (x,y) heißen unabhängig, wenn u,v,x,y vier verschiedene Knoten sind. Wenn u=x oder u=y oder v=x oder v=y, dann heißen die Kanten benachbart (oder verbunden oder adjazent). Eine Kantenmenge M heißt unabhängig, wenn alle ihre Elemente paarweise unabhängig sind. Solche Kantenmengen heißen auch Matching. Anderes Beispiel … Jeder Algorithmik-Student darf 2 Wünsche für Übungsgruppen angeben. Die Übungsgruppen haben eine begrenzte Zahl an Plätzen. Gibt es eine Lösung, die alle Übungsgruppenwünsche erfüllt? Studenten … M. Philippsen 17.9 Matching Algorithmik 1, WS 2003/04, Folie 17-105 Friedrich-Alexander-Universität Erlangen-Nürnberg 17.9 Matching Bemerkungen Nicht jeder Graph hat ein (fast) perfektes Matching. Algorithmik 1, WS 2003/04, Folie 17-108 Friedrich-Alexander-Universität Erlangen-Nürnberg M. Philippsen Ein Zyklus mit gerader Knotenzahl hat genau 2 perfekte Matchings. Definitionen M. Philippsen ist nicht perfekt Ein Knoten heißt frei bzgl. eines Matchings, wenn er keine Kante des Matchings hat, sonst sagt man, dass er zum Matching gehört. Ein Matching heißt perfekt, wenn es alle Knoten des Graphen überdeckt. Ein Matching heißt größtes Matching wenn es um keine Kante erweitert werden kann. Ein Matching heißt größtmögliches Matching wenn es kein Matching mit mehr Kanten gibt. Ein Matching bei dem nur ein Knoten frei bleibt, heißt fast perfekt. gematcht frei Algorithmik 1, WS 2003/04, Folie 17-107 Friedrich-Alexander-Universität Erlangen-Nürnberg 17.9 Matching Ein gieriger Algorithmus: Gegeben: Graph G Gesucht: Matching M Dieser giereige Algorithmus liefert ein maximales Matching aber kein (fast) perfektes Matching " ! ! ! Verbesserung der Matchingqualität durch Heuristiken: # ) M. Philippsen zuerst Knoten mit geringem Grad bearbeiten („schwer zu verkuppeln“) … 17.9 Matching }A }B Idee klappt bei alternierenden Pfaden: / v v M. Philippsen w w M. Philippsen größtmögliches (auch perfektes) Matching. ersetze hier 2 Kanten des Matchings durch 3 neue Kanten }B }A }B }A Idee: Verbesserung eines größten Matchings Um diesen freien Knoten ins Matching aufzunehmen… …muss diese MatchingKante ersetzt werden. Algorithmik 1, WS 2003/04, Folie 17-110 Friedrich-Alexander-Universität Erlangen-Nürnberg 17.9 Matching Algorithmik 1, WS 2003/04, Folie 17-109 Friedrich-Alexander-Universität Erlangen-Nürnberg 17.9 Matching v . M (fette Linien) ist kein größtmögliches Matching, da Verbessern es einen alternierenden Pfad zwischen Knoten v,w M gibt. ,- / v Beispiel (1) w w Algorithmik 1, WS 2003/04, Folie 17-112 Friedrich-Alexander-Universität Erlangen-Nürnberg + /. # , ! 0 M (fette Linien) ist kein größtmögliches Matching, da Verbessern es einen alternierenden Pfad zwischen Knoten v,w M gibt. Definition Ein Pfad heißt (vergrößernd) alternierender Pfad bzgl. eines Matchings M gdw. w der Pfad der abwechselnd Kanten M und M hat und Anfangs- und Endknoten des Pfades nicht in M liegen. v M. Philippsen Satz von Berge: Ein Matching M in einem Graphen G ist größtmöglich gdw. G keinen alternierenden Pfad bzgl. M enthält. Algorithmik 1, WS 2003/04, Folie 17-111 Friedrich-Alexander-Universität Erlangen-Nürnberg * 0 %' Noch offen: Wie findet man M-alternierende Pfade? Algorithmik 1, WS 2003/04, Folie 17-114 Friedrich-Alexander-Universität Erlangen-Nürnberg M. Philippsen Der Algorithmus fügt in jedem Schritt eine Kante zu M hinzu. Da es nur endlich viele Kanten gibt, terminiert er. Wenn er terminiert, hat er ein größtmögliches Matching gefunden. # 17.9 Matching v 17.9 Matching w Matching-Algorithmus: v M (fette Linien) ist kein größtmögliches Matching, da Verbessern es einen alternierenden Pfad zwischen Knoten v,w M gibt. Beispiel (2) w M. Philippsen In jedem Fall landet man bei einem größtmöglichen Matching. Algorithmik 1, WS 2003/04, Folie 17-113 Friedrich-Alexander-Universität Erlangen-Nürnberg 17.9 Matching Das Finden eines alternierenden Pfades ist in bipartiten Graphen G mit zwei Klassen A und B leicht. Sei ein Matching gegeben: }A }B Definiere G‘ so dass alle Matching-Kanten von A nach B und alle anderen von B nach A gerichtet sind. }A }B M. Philippsen 17.9 Matching Traversiere den Graph (egal ob Tiefen- oder Breitensuche). } } } M. Philippsen M. Philippsen Jeder Pfad wechselt zwischen M´ und G´\M´. Ein alternierender Pfad ist gefunden, sobald man von einem Knoten v M‘ einen Knoten w M‘ erreicht. Vergrößerung der Matchings: Algorithmik 1, WS 2003/04, Folie 17-116 Friedrich-Alexander-Universität Erlangen-Nürnberg 17.8 Transitive Hülle Algorithmik 1, WS 2003/04, Folie 17-115 Friedrich-Alexander-Universität Erlangen-Nürnberg Organisatorisches Elegante Verwendung der Adjazenzmatrix } Algorithmik 1, WS 2003/04, Folie 17-118 Friedrich-Alexander-Universität Erlangen-Nürnberg } boolean [][] A = {...} int dim = A.length; ... void warshall() { for (int y = 0; y < dim; y++) { for (int x = 0; x < dim; x++) { if (A[x][y]) { for (int z = 0; z < dim; z++) { if (A[y][z]) A[x][z] = true; Warshall‘s Allgorithmus Vorlesungsbefragung 1. Papierfragebögen (vorlesungsspezifische Fragen) Was können wir an Algorithmik-1 in Zukunft verbessern? Bitte helfen Sie mir und dem nächsten Jahrgang! Nehmen Sie sich Zeit zum Lesen und Beantworten. Jede Frage einzeln lesen, nicht nur von oben nach unten ankreuzen. Langschriftliche Kommentare sind besonders nützlich. Ergebnisse werde ich auf der Material-Seite veröffentlichen. 2. Online-Evaluation (allgemeine Fragen) M. Philippsen Wir teilen nach der Vorlesung eine TAN pro Person aus. Bitte nehmen Sie sich die Zeit. Algorithmik 1, WS 2003/04, Folie 17-117 Friedrich-Alexander-Universität Erlangen-Nürnberg