Programmierkurs Python II Stefan Thater & Michaela Regneri Universität des Saarlandes FR 4.7 Allgemeine Linguistik (Computerlinguistik) Übersicht • Topologische Sortierung (einfach) • Kürzeste Wege finden (ziemlich einfach) • Größter gemeinsamer Teilgraph - Modulares Graph-Produkt (nicht formal) Cliquen (etwas komplexer) 2 Ein Graph zum Frikadellen-Machen „X ➞ Y“: X muss erledigt sein, damit Y gemacht werden kann Zwiebel Schälen ! ! ! ➞ Zwiebeln hacken Zwiebeln hacken ! ! ! ➞ Zwiebeln in die Schüssel Hackfleisch auspacken ! ➞ Hackfleisch in die Schüssel ∅ "" " " " " " " ➞ Gewürze in die Schüssel [alles in die Schüssel] !➞ Masse Verkneten Masse Verkneten ! ! ! ➞ Frikadellen formen Frikadellen Formen ! ! ➞ Frikadellen braten [...] 3 Ein Graph zum Frikadellen-Machen Zwiebeln schälen Fett in Pfanne Zwiebeln hacken Zwiebeln in Schüssel Hackfleisch in Schüssel Masse verkneten Pfanne erhitzen Gewürze in Schüssel Frikadellen formen Frikadellen braten 4 Topologische Sortierung graphische Variante Zwiebeln schälen Zwiebeln hacken Zwiebeln in Schüssel Hackfleisch in Schüssel Masse verkneten Fett in Pfanne Pfanne erhitzen Gewürze in Schüssel Frikadellen formen lineare Ordnung, Frikadellen braten alle Kanten zeigen nach rechts 5 Topologische Sortierung Algorithmus (im Bild) Schritt 1 0 Zwiebeln schälen 1 0 0 Fett in Pfanne Zwiebeln hacken 1 Hackfleisch in Schüssel 1 Zwiebeln in Schüssel Masse verkneten 1 x: Eingangsgrad 3 Gewürze in 0 Schüssel Frikadellen formen Pfanne erhitzen 2 Frikadellen braten 6 Topologische Sortierung Algorithmus (im Bild) Schritt 2 Zwiebeln hacken 0 Masse verkneten 0 Zwiebeln schälen Fett in Pfanne Gewürze in Schüssel Pfanne erhitzen Hackfleisch in Schüssel x: Eingangsgrad Zwiebeln in 1 Schüssel 1 Frikadellen formen 1 Frikadellen braten 2 Beliebige Ordnung untereinander 7 Topologische Sortierung Algorithmus (im Bild) Schritt 3 Zwiebeln in Schüssel 0 Masse verkneten 1 Frikadellen formen 1 x: Eingangsgrad Frikadellen 2 braten Zwiebeln schälen Fett in Pfanne Gewürze in Schüssel Hackfleisch in Schüssel Zwiebeln hacken Pfanne erhitzen 8 Topologische Sortierung Algorithmus (im Bild) Schritt 6 x: Eingangsgrad Komplexität: bester Fall: O(n) worst case: O(n2) Frikadellen braten Zwiebeln schälen Fett in Pfanne Gewürze in Schüssel Hackfleisch in Schüssel Zwiebeln hacken 0 Pfanne erhitzen Zwiebeln in Schüssel Masse verkneten Frikadellen formen 9 a 1 2 Kürzeste Wege finden d b 1 5 3 8 e 7 c 2 f • „Single source shortest path problem“ • Aufgabe: Gegeben einen Knoten im Graph, finde die kürzesten Wege zu allen anderen Knoten • Meistens assoziiert mit Kantengewichten (kürzester Weg = billigster Weg) • Der Weg vom Startknoten zu unerreichbaren Knoten kann unendlich sein (unzusammenhängende ungerichtete / nicht stark zusammenhängende gerichtete Graphen) 10 a 1 2 Dijkstra-Algorithmus d b 1 5 3 8 e 7 c 2 f • Initialisierung: - Startknoten: Distanz 0, permanent, aktiv andere: Distanz ∞, temporär (nicht aktiv) • So lange es Knoten mit temporären Nachbarn gibt... - Berechne die Distanz der temp. Nachbarn des aktiven Knoten (Distanz aktiver Knoten + Kantengewicht) - wenn berechnete Distanz > notierter Distanz: - - aktualisiere notierte Distanz; notiere aktiven Knoten als Vorgänger neuer aktiver Knoten: Knoten mit kleinster (Gesamt-)Distanz; markiere den als permanent 11 Dijkstra-Algorithmus a 1 2 d 0 a 5 3 1 2 d ∞ b e ∞ b 5 3 e ∞ 8 1 7 8 1 7 c 2 f ∞ c 2 f ∞ Startknoten hier: a Initialisiere Distanzen: Startknoten = 0, alle anderen = ∞ Initialisiere Markierungen: Startknoten = permanent alle anderen = temporär Initialisiere aktiven Knoten: Startknoten 12 Dijkstra-Algorithmus 0 a 2 1 5 a e ∞ 7 f ∞ 1 1(a) 8 b ∞ c 2 1 5 e ∞ d 3 2(a) • Berechne alle Nachbar-Distanzen zum aktiven Knoten (nur zu temporären Knoten) 2 3 d 2(a) 0 ∞ c 1(a) 8 b 1 • Wenn die berechnete Distanz kleiner ist als die bisher gefundene, aktualisiere Distanz und Vorgänger • neuer aktiver Knoten: temporärer 2 Knoten mit kleinster Distanz • markiere neuen aktiven Knoten als f ∞ 7 permanent 13 Dijkstra-Algorithmus 0 a 1 2 d 2 1(a) 8 b 1 5 3 9 (b) c e 6 (b) 7 0 a 0 a 2 2 f ∞ 1 2 d 3 2(a) 1 1(a) 8 b 5 1 5 e 5(d) 1 6(e) c 2 f 7 (e) X 8(c) 12 a 2 e d 3 (b) (d) 7 X 6 (a) 5 2 1 (a) 8 b 0 9(b) c 0 a 2 2 d 3 2(a) 1(a) 8 b 5 e 5(d) 1 5 e d 3 2(a) f ∞ 1 1(a) 9X(b) 6(e) 8 b c 1 1 7 5 (d) 7 2 f 12(e) 6(e) c 2 fertig f 8(c) 14 Dijkstra-Algorithmus - Ergebnis • jeder Knoten: minimale Distanz, und direkter Vorgänger • Ableitbarer „Spannbaum“: ein Teilgraph des Graphen, der ein Baum ist und alle Knoten des Graphen enthält • die enthaltenen Kanten markieren hier die kürzesten Pfade 0 a 1 2 d 3 2(a) 1(a) 8 b 5 e 5(d) 1 7 6(e) c 2 f 8(c) 1 b a 2 d 3 e 1 c 2 f 15 Kürzeste Wege finden • Komplexität von Dijkstra: O(Knoten * log(Knoten) + Kanten) • SSSP mit neg. gewichteten Kanten - Dijkstra erlaubt keine negativen Gewichte SSSP mit negativen Gewichten (aber ohne negative Zyklen): Bellman-Ford-Algorithmus • All pairs shortest path problem - Aufgabe: berechne für alle Paare von Knoten die kürzesten Pfade zwischen den Knoten - Floyd-Warshall-Algorithmus 16 Graph-Ähnlichkeit: Größter gemeinsamer Teilgraph • Problem: Welches ist der maximale Graph, der Teilgraph von zwei Graphen ist? Person Person Hyponym Schriftsteller verfasst Dramen Hyponym Hyponym Literatur Schriftsteller Hyponym Hyponym Stephen King Lebens mittel Romane verfasst Lyrik Hyponym Stephen King verfasst liest Literatur Hyponym Romane Lyrik verfasst 17 Graph-Ähnlichkeit: Größter gemeinsamer Teilgraph • Eine Möglichkeit: - Berechne das modulare Produkt der beiden Graphen (ein neuer Graph, der beide Graphen repräsentiert) - finde den größten maximalen vollständigen Teilgraphen (Definition später) 18 Graph-Ähnlichkeit: Modulares Graph-Produkt (MGP) • oft angewendet für „reinen“ Graph isomorphismus (ungelabelte, ungerichtete Kanten, Knoten-Label egal) • MGP von G=(V,E) und H=(V‘,E‘) ist P=(W,F) so dass - W = kartesisches Produkt von E und F [(u,v) | u ∈ V, v ∈ W] - F = [((u,v),(u‘,v‘))] für alle - - (u,u‘) ∈ E & (v,v‘) ∈ E‘ (u,u‘)∉ E & ∉ (v,v‘) F Knoten sind also Knotenpaare, Kanten repräsentieren „gleiche Verbindung“ in den Ursprungsgraphen 19 Graph-Ähnlichkeit: Modulares Graph-Produkt (MGP) • Abwandlung hier für Knoten mit „Typen“ und ggf. unterschiedliche Kanten • MGP von G=(V,E) und H=(V‘,E‘) ist P=(W,F) so dass - W = [(u,v) | u ∈ V, v ∈ W, v≈u] (hier: v‘s Knoten-Typ ist kompatibel mit u) - F = [{(u,v),(u‘,v‘)}] für alle - {u,u‘} ∈ E & {v,v‘} ∈ E‘ {u,u‘} ∉ E & {v,v‘} ∉ E‘ Zur Vereinfachung ignorieren wir hier Kantentypen, weil die Datenstruktur sie so nicht vorsieht. 20 Graph-Ähnlichkeit: Modulares Graph-Produkt (MGP) 21 Graph-Ähnlichkeit: Cliquen • Ein Graph G heißt vollständig, wenn alle seine Knoten paarweise verbunden sind • Ein maximaler vollständiger Teilgraph (oder eine Clique) eines Graphen G ist ein Teilgraph G‘, so dass G‘ vollständig ist und es keinen vollständigen Teilgraphen G‘‘ von G gibt, so dass G‘ ein Teilgraph von G‘‘ ist. 22 Graph-Ähnlichkeit: größte Clique 23 Cliquen finden - Prinzip • beginne bei einem minimalen vollständigen Teilgraphen (= ein Knoten) • mache eine Cliquen-Knotenmenge (CS) damit auf • füge so lange Knoten zu CS, bis es keine Knoten mehr gibt, die mit CS zusammen eine noch unbekannte Clique ergeben • Speichere CS als Clique und suche die nächste (mit einem anderen Startknoten) 24 Cliquen finden Grundlagen des Algorithmus • eine aktuelle Cliquen-Menge CS (inital: leer) • Kandidaten, Knoten, die mit allen Elementen aus CS verbunden sind (initial: alle Knoten) C • Visited, Knoten, die schon betrachtet wurden und für das aktuelle CS gültige Erweiterungen sind (= die zu schon gesehenen Cliquen führen) (initial: leer) • ein aktueller aktiver Kandidat S • im aktuellen Schritt ignorierte Knoten 25 Cliquen finden Erfolgsbedingung (finden einer Clique) • keine Kandidaten mehr • keine Elemente in Visited - sonst gäbe es Knoten, die die aktuelle Cliquen-Menge zu einer Clique erweitern können - der vollständige Teilgraph wäre nicht maximal 26 Cliquen finden - Algorithmus • in diesem Schritt: ein Knoten in Visited (= eine Clique schon gefunden) • 3 Knoten in der CliquenMenge C C • 2 Kandidaten übrig 27 Cliquen finden - Algorithmus 1. Wähle einen aktiven Kandidaten, entferne ihn aus der Kandidaten-Menge S C 28 Cliquen finden - Algorithmus 1. Wähle einen aktiven Kandidaten, entferne ihn aus der Kandidaten-Menge 2. füge ihn zur Cliquen-Menge hinzu S C 29 Cliquen finden - Algorithmus 1.Wähle einen aktiven Kandidaten, entferne ihn aus der KandidatenMenge 2.füge ihn zur Cliquen-Menge hinzu C 3.gehe in die Rekursion mit neuen Mengen: - Entferne alle Knoten von Kandidaten u. Visited, die nicht mit dem letzten aktiven Kandidaten verbunden sind) - beginne damit bei 1 30 Cliquen finden - Algorithmus 5.Wenn Rekursion fertig: - alte Mengen (Visited und Kandidaten) wieder zurück holen - den alten aktiven Kandidaten zu Visited hinzufügen C S C 31 Cliquen finden - Algorithmus • Abbruchs-Bedingungen: - es gibt keine Kandidaten mehr es gibt einen Knoten in Visited, der mit allen übrigen Kandidaten verbunden ist C 32 Cliquen finden • der Basis-Algorithmus ist sehr ineffizient • Verbesserung des Standard-Falls: Bron-KerboschAlgorithmus - Prinzip: optimiere die Auswahl des nächsten aktiven Kandidaten, so dass möglichst früh abgebrochen wird - Ziel: möglichst früh ein Knoten in Visited, der zu allen Kandidaten adjazent ist - Für jeden Knoten in Visited wird die Anzahl der nicht Adjazenten Kandidaten gespeichert - Der nächste Kandidat hat immer eine Verbindung zu dem Knoten in Visited mit kleinsten Zähler 33 Mehr Cliquen 34 Zusammenfassung • Heute: verschiedene Graph-Algorithmen • Topologische Soritierung: „Plan-Management“ • Single Source Shortest Path: Kürzeste Wege • Größter gemeinsamer Teilgraph - Modulares Graph-Produkt Cliquen 35