Vorbereitungen zur GDI2 Klausur letztes Update: 6.10.2006 @ 20 Uhr Vers. 1.2 Grundlagen der Informatik 2 – Algorithmen & Datenstrukturen Themen-Übersicht: 1. Einführung 2. Rekursion & Komplexität 3. Graphen Definitionen 4. Graphen-Algorithmen, Traversierung, Wege- und Flußprobleme 5. Darstellung von Graphen am Rechner (Sequentiell VS Dynamisch) 6. Allgemeine und Binäre Bäume 7. Binär Bäume 8. Binäre Suchbäume 9. Mehrwegbäume, Digitale Suchbäume 10.Dynamische Programmierung 11.Sortieren 12.Hashing 13.Geometrische Algorithmen und Datenstrukturen & Data Mining Begriffe & Allgemeines • Teile und hersche (Divide et impera) -> Problem in Teilprobleme zerlegen, meist per Rekursion lösen und dann zur Gesamtlösung zusammen setzen! • Backtracking = Tiefensuche Problem-Teillösung wird ausprobiert und Restproblem rekursiv gelöst, wenn ein „Dead-Lock“ erreicht wird, probiert der Algorithmus eine Rekursionsebene höher eine andere Lösung aus. Standard Verfahren bei Brute-Force Algorithmen! • Greedy-Algorithmus Wählt eine Teillösung sinnvoll (richtig) aus, so dass sie nicht wieder zurückgenommen werden muss! • Groß-O Notation f in O(g) gdw. E. c mit f(n) <= c * g(n) f.A. n > n0 BTW: O(n!) ist im Prinzip auch exponentielles Wachstum! • Berechnung von Komplexität • Elementar Ops. O(1) • Hintereinanderausführung O(max(T1,T2)) • Verkettete Ausführung (z.B. 2 for-Schleifen ineinander gestrickt!) O(T1 * T2) Graphen Begriffe • Knotenendlich gdw. |V| < ∞ • Kantendlich gdw. |E| < ∞ • Ohne Mehrfachkanten: Knotenendlich => Kantendlich • 2 Knoten heißen adjazent, wenn sie durch eine Kante (direkt) verbunden sind! • Schlinge: Identischer Anfangs- und Endknoten • Schlichter (einfacher) Graph: Keine Mehrfachkanten und Schlingen! • Die inzidenten Kanten eines Knoten, sind alle Kanten, die ihn berühren! • Grad eines Knotens = Anzahl der inzidenten Kanten • Außengrad d+ = Anz Kanten die von v weg gehen • Innengrad d- = Anz Kanten die in v enden • Achtung: Beim Baum ist der Grad = Außengrad! • Teilgraph G' besteht aus beliebiger Untermenge von Knoten und Kanten von G • Knoten mit Grad 0 sind isoliert © 2006 J Flick – Vorbereitungen zur GDI2 Klausur – 1/11 Vorbereitungen zur GDI2 Klausur • • • • • • • • • • • • • • • • • • • • • • • • • • • letztes Update: 6.10.2006 @ 20 Uhr Vers. 1.2 Regulärer Graph: Alle Knoten vom selben Grad (Z.B. auch Graph ohne Kanten ;-) Vollständiger Graph: Jeder Knoten mit jedem anderen direkt verbunden! Clique: Maximaler vollständiger Teilgraph. (Also wieviel muss man aus dem Graph streichen, damit jeder Knoten mit jedem anderen verbunden ist!) Untergraph: Ein Teilgraph mit beliebiger Knotenuntermenge, aber sämtlichen dazugehörigen Kanten!!! (Untergraph => Teilgraph) 2 Teilgraphen sind • Kantendisjunkt gdw. keine gemeinsamen Kanten • Knotendisjunkt gdw. keine gemeinsamen Knoten Isomorphe Graphen: „Gleich“, nur Knoten anders beschriftet! Inverser Graph: Kantenrichtungen invertiert! G = G u G^-1 : Der zu G zugeordnete ungerichtete Graph Weg ist knoteneinfach gdw. jeder Knoten in p nur einmal vorkommt Weg ist kanteneinfach gdw. jede Kante in p nur einmal vorkommt (Auch Kantenzug gennant) • Königsberger Brückenproblem: Kanteneinfacher Weg gesucht! (durch alle Kanten) • Knoteneinfach => Kanteneinfach Zyklus: Anfangs- und Endpunkt identisch Weglänge |p| = Anz Knoten in p – 1 Knoten verbunden gdw. Weg zwischen ihnen existiert Graph zusammenhängend gdw. alle Knotenpaare verbunden sind Entfernt man einen Trennknoten, zerfällt der Graph in 2+ zusammenhängend Komponenten Entfernt man eine Schnittkante, zerfällt der Graph in mehrere Teile • Graph ohne Schnittkante ist mehrfach zusammenhängend Minimal aufspannender Teilgraph besitzt alle Knoten von G, aber minimale Anz. Kanten um zusammenhängend zu sein! (Siehe auch minimaler Spannbaum ^^) Eulerscher Graph hat • Eulersche Linie: Kanteneinfacher Zyklus, der alle Kanten umfasst! (Königsb. Br. P.) • Zusammenhängender Graph ist eulersch gdw. alle Knoten geraden Grad haben! Hamiltonscher Graph hat • Hamiltonsche Linie: Knoteneinfacher Zyklus, der alle Knoten umfasst! Länge dieses Zyklus = |V| Wegegraph: Enthält Kante, wenn ein nicht trivialer Weg (|p| > 0) exisitiert! • Aus dem Wegegraph ergibt sich die Erreichbarkeits-Matrix • Die Transitive Hülle berücksichtigt auch noch triviale Wege! gerichteter Graph ist azyklisch gdw. keine Zyklen existieren! Ein Graph ist Planar wenn er sich ohne Kantenüberschneidung zeichnen lässt! • Eulersche Polyederformel planarer Graphen: |V| + |Flächen| = |E| + 2 (wobei auch die äußere Fläche, die den Graph umgibt, gezählt wird! g(e) = Gewicht einer Kante, also eine Kantemarkierung die z.B. den Fluss darstellt azyklischer Graph kann partielle Ordnung (z.B. Prozessabhängigkeit) beschreiben! Das Gewicht eines Weges = Summe der Kantengewichte • Der kürzeste Weg zwischen 2 Knoten ist die Distanz zwischen den beiden! Darstellung von Graphen am Rechner durch Adjazenzmatrix, Inzidenzmatrix (V\E -> -1 für Kante geht weg von Knoten, 1 für Kante kommt an bei Knoten), Adjazenztabelle (Ne Art Adjanzentliste als Array implementiert), Adjazenzliste (Nachfolger) Transitive Hülle A* = Erreichbarkeitsmatrix, die auch triviale Wege beachtet! © 2006 J Flick – Vorbereitungen zur GDI2 Klausur – 2/11 Vorbereitungen zur GDI2 Klausur letztes Update: 6.10.2006 @ 20 Uhr Vers. 1.2 Baum Begriffe • Baum : einfacher azyklischer, zusammenhängender Graph n-Knoten => n-1 Kanten • Wurzel, Vater, Sohn, Blatt... klar • Grad eines Knotens: Anzhal seiner Kinder (Außengrad im Graph!) • Alles was kein Blatt ist, ist Innerer Knoten • Grad/ Ordnung des Baumes = Maximale Grad aller Knoten (fan-out) • Stufe: 0, 1, 2... (Pfadlänge) • Höhe: Maximale Stufe +1 (1,2,3...) • Das Gewicht eines Baums: Anzahl Blätter, oder Anzahl Knoten (gewichtsbalancierten binären Suchbäume) • geordneter Baum: Reihenfolge der Unterbäume ist relevant (z.B. Syntaxbaum) • Ähnlichkeit = Isomorphe Struktur • Äquivalenz: Ähnlich & gleiche Information! • Vollständiger Binär Baum: Maximale Anzahl an Knoten für seine Höhe • Strikter Binärbaum: Jeder innere Knoten hat Grad 2 • Fast vollständiger Binärbaum: Bis Stufe k vollständig und Stufe k+1 von links nach rechts aufgefüllt! (Also nur am rechten Rand ein „Bissen“ abgebrochen) Alle Blätter auf Stufe k und Stufe k+1 • Ausgeglichener Binärbaum: Auf Stufe k vollständig und auf Stufe k+1 beliebige Lücken (auch mitten drinnen) Fast vollständig => ausgeglichen • Baumdarstellung: • Feldbaum: Eine verkettet Darstellung auf nem Array simuliert ( #| Inhalt| Lsohn| Rsohn) • Elternknoten: Ähnlich, aber nur Elternverweise (# | Inhalt | Vater) • Halb-Sequentielle Darstellung: Knoten in PreOrder (W L R) im Array Lsohn Info durch Nachbarschaft im Array! ( #| Inhalt | Rsohn| Blatt?) (Bei Lsohn statt Rsohn Info -> W R L) • Sequentielle Darstellung: Geht von vollständigem Baum aus, Lücken im Speicher, für Lücken im Baum (# | Inhalt) Vater = Pos -> L = 2*Pos , R = 2*Pos+1 • Fädelung: Baum Traversierung (Pre/In/Postorder) in der Datenstruktur mit Zeigern vereinfachen! • Rechtsfädelung: Normale Ordnung • Linksfädelung: Gespiegelte Ordnung ( WRL statt WLR etc.) • Geht ohne zusätzliche zeiger, einfach die NULL Zeiger an den Blättern umbiegen! (allerdings dann Blatt Markierung nötig!) • Mittlere Suchtiefe: mst = (∑(Stufe(Vi) +1))/ n //von i=1 bis |V| Also die Zugriffe die man für jeden Knoten (Suche) benötigt addiert und durch n geteilt Bei gewichteten Bäumen: mst= (∑((Stufe(Vi) +1)*p(Vi))) //von i=1 bis |V| • Soll erfolglose Suche berücksichtigt werden: Einfach „Null Pointer“-Knoten für Innere Knoten mit in die Rechnung nehmen, aber für die immer Stufe-1 nehmen! • Binärer Suchbaum: v.links.key < v.key < v.rechts.key • Höhenbalancierte Bäume: |h(BL) – h(BR)| <= k • AVL – k=1 Balanciert! • von w (= Knoten wo AVL-Kri. verletzt ist), wo wurde eingefügt? • Fall LL -> Von-Linksrotation • Fall RR -> Von-Rechtsrotation • Fall LR/ RL ->Doppelrotation • Fibonacci Bäume: Bh=(Bh-1,x,Bh-2) B0 = leer, B1 = 1 Knoten © 2006 J Flick – Vorbereitungen zur GDI2 Klausur – 3/11 Vorbereitungen zur GDI2 Klausur • • letztes Update: 6.10.2006 @ 20 Uhr Vers. 1.2 Gewichtsbalancierte Suchbäume: Wurzelbalance P = |BL| +1 / |B| +1 Gewicht eines Baumes |B| = Anzahl der Knoten (hier nicht Blätter!) B-Baum Begriffe • Jeder Knoten k-2k Einträge (außer Wurzel) • min k+1 Kinder (außer Wurzel, min 2 Kinder) • m/n Baum: k = m-1 = (n-1) / 2 (minimale/maximale Kinder) • log2k+1(n+1) <= h <= logk+1((n+1)/2) +1 • B Baum mit doppeltem Überlauf: Knoten versucht erst seine Overflow auf Nachbarknoten abzugeben, erst wenn beide voll sind-> Aufbrechen (International B* tree gennant) • B+Baum (bei uns auch B*-Baum gennant) hat Daten nur in Blättern • Klasse (k,k*,h*) wobei k die max Entrys im inneren Knoten beschreibt und k* die Max Entries im Blatt • Beim Löschen nur im Blatt löschen und Wegeweiser stehen lassen! Im Blatt aber evtl rotieren! • Einfügen ähnlich wie bei normalen B-Baum, beim Splitt bleibt mittleres Element einerseits im Knoten links, aber geht zusätzlich als Wegweiser hoch! • Hohle B-Bäume • Daten nur in Blättern, pro Data ein Blatt, also bei 2 bricht das Blatt schon auf und linkes Element geht zusätzlich als Index hoch. In Inneren Knoten läuft alles wie gehabt • Im Prinzip B+ Baum mit k*=1 !? ABER: • Löschen: Einfach Blätter weg streichen!!! • Minimal befüllter B-Baum: Schlüssel aufsteigend Sortiert einfügen!!! Digitale Suchbäume • Optimiert für Lexikalische Suche -> Präfixbäume • m-ärer Trie, hat einfach Array von Pointer mit pos steht für Zeichen; nur präfixfreie Schlüssel erlaubt • Trie mit Trennzeichen: EOW Markierung um auch präfixunfreie Keys zu adden • Trie ohne Einwegverzweigung: Subbaum durch Speziielen Knoten mit Restschlüssel ersetzen • Trie mit variablem Knotenformat: Nur die Pointer die am aktuellen Knoten gebraucht werden • Binäre digitale Suchbäume: Links 0, rechts 1 • Schlüssel werden da eingefügt wo Platz ist (nicht den Schlüssel bis zum Ende durcheiern) • Patricia-Baum: Schlüssel wird bis zum Ende durchgeeiert, aber in Knoten kann BitÜbersprung Info gespeichert werden! • Binärer Radix Baum: Bereitsgelesenes Präfix im Knoten gespeichert, außerdem Information das wievielte Bit im RESTSTRING als nächstes verglichen werden soll! Notiz zu Sortierverfahren • Proxmapsort: Mapkey Funktion = Integral der Dichtefunktion! Notiz zu Hashing • Quadratisches Sondieren: hi(K) = (h0(K) – ceil(i/2)² * (-1)^i ) mod m • Erweitertes Hashing: Behältertafel muss so oft verdoppelt werden, bis die globale Tiefe der notwnedigen lokalen Tiefe entspricht! © 2006 J Flick – Vorbereitungen zur GDI2 Klausur – 4/11 Vorbereitungen zur GDI2 Klausur letztes Update: 6.10.2006 @ 20 Uhr Vers. 1.2 Algorithmen Hanoi(n,Start,Ziel) if (n = 1) Zug von Start nach Ziel else Hanoi(n-1,Start,Temp) Zug von Start nach Ziel Hanoi(n-1,Temp,Ziel) Baum-Traversieung • per Tiefensuche/ Depth First Search • besuche einen unbesuchten Knoten und rufe für alle seine Nachbarn Tiefensuche auf! (Backtracking) • • per Breitensuche/ Breadth First Search • Stecke unbesuchten Knoten in Schlange, sollange die Schlange nicht leer ist, nimm Knoten aus der Schlange und füge seine Nachbarn in die Schlange ein! O(max(|V|,|E|) Herstellung der Topologischen Sortierreihenfolge • per Top-Down (intuitiv) • Sollange G nicht leer • Finde Knoten v mit Eingangsgrad 0 • Lösche v mit allen dazugehörigen Kanten aus G • Speichere die Knoten Lösch-Reihenfolge!!! • per Bottom-Up (besser) • Alle Knoten unbesucht • z = |V| • for (v : V) if (d-(v) = 0) topSort(v); • topSort(v) • besuche v • for(k : v.successor) • if(unvisited(k)) topSort (k) • TS[k] = z; z--; © 2006 J Flick O(|V|²) • Ausgehend von allen Knoten mit Eingangsgrad 0, DFSTraversierung starten • Vergebe Besuchnummern rückwärts. Der tiefste Knoten, bekommt die höchste Nummer! O(max(|V|,|E|)) – Vorbereitungen zur GDI2 Klausur – 5/11 Vorbereitungen zur GDI2 Klausur letztes Update: 6.10.2006 @ 20 Uhr Vers. 1.2 Finden des minimalen Spannbaums (Zusammenhängend, azyklisch) • Bei Graph ohne Kantengewichte trivial -> Einfach sollange beliebige Kanten aus Zyklen entfernen, bis azyklisch! • Das Gewicht des Spannbaums ist die Summe seiner Kantengewichte • Prinzipieller Algorithmus: • E' = { } • while(not done) • wähle geeignete Kante • E' = E' u { e } • Auswahl der Kante: • Nach Kruskals Algorithmus: O(|E| log |E|) • Sortiere die Kanten nach Gewicht • Für e mit dem niedrigsten Gewicht: • Falls E' u { e } einen Zyklus bildet verwerfen • Sonst E' = E' u { e } • • • O(|E| + |V| log |V|) Algorithmus von Prim (besser) V' = { <beliebiger Anfangsknoten v aus V> } for(int i=1; i<= |V|-1; i++) • e = (u,v) aus E mit u aus V' und v nicht aus V' mit minimalem Gewicht (also die nächst kleinste Kante, die aktuell erreichbar ist und keinen Zyklus verursacht) • • V' = V' u {v} E' = E' u {e} Nützliches • Primzahlen: 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271... © 2006 J Flick – Vorbereitungen zur GDI2 Klausur – 6/11 Vorbereitungen zur GDI2 Klausur letztes Update: 6.10.2006 @ 20 Uhr Vers. 1.2 Finden des kürzesten Weges – Routing • Single Source Problem -> von einem Startpunkt alle Kürzesten Wege bestimmen • Bruteforce/ Ausprobieren, z.B. mit Backtracking -> O(2^n) • Moore-Algorithmus (nur für Graphen mit Kantengewichten von 1) • Markiere alle Knoten mit Entfernung ∞ • Markiere Startknoten S mit Entfernung 0 O(max(|E|,|V|) • Schlange mit { S } • Sollange W nicht leer • Nimm f vorne aus W • e = Entfernung(f) • für jeden Nachbarn n von f • if ( Entfernung(n) = ∞) //noch unbesucht ^^ • W =W u{n} Besucht immer den • Setze Entfernung(n) = e+1 Randknoten, der von den • • • • • • • • • • • • „Ameisen“ als nächstes M1 = bereits besuchte Knoten erreicht wird. Und wenn von M2 = Randknoten dort nun ein Knoten kürzer M3 = unerreichte Knoten = V / (M1 u M2) erreichbar ist als vorher, Dijkstra-Algorithmus (für positive Kantengewichte) wird das gemerkt. Will man • for(v : V) if(v != s) g(v) = ∞ auch den genauen Weg • M1 = { s }; M2 = { }; g(s) = 0; wissen, muss man zusätzlich ein Vorgänger • for(v : s.neighbors()) • M2 = M2 u {v}; g(v)= c((s,v)); //c – Kantengewicht Gerüst speichern! • while(M2 != { }) • v = <Knoten in M2 mit minimalem g(v);//Ameisen kommen als nächstes an • M2 = M2 \ { v }; M1 = M1 u { v }; An der Stelle wählt der A* • for(w : v.neighbors()) Algo. den Knoten aus, dessen • if (w in M3) Summe aus g(v) + • M2 = M2 u {w}; g(w) = g(v) + c((v,w)); luftlinieZumZiel(v) am • else if (g(w) > g(v) + c((v,w)) kleinsten ist!!! • g(w) = g(v) + c((v,w)); O(|V|² ) bis O(|E| log|V|) Protokollierung des Dijkstra (je nach Implementierung) Tabelle mit M1|M2|g(v) f.A. v Aufschreiben... Bellman-Ford Kweg auch mit negativen Kanten (nur ohne negativen Zyklen!) Markiere g(s) = 0 Für alle anderen v aus V: g(v) = ∞ O(|V| * |E|) Mache |V|-1 mal • Für jede Kante(v,w) • Falls g(w) > g(v) + c((v,w)) • g(w) = g(v) + c((v,w)); • p(w) = v; //Vorgängerfunktion Im W.C. kommt in jedem Durchgang nur ein Kweg zu einem neuen Knoten hinzu -> |V|-1 Iterationen! Protokollierung: Tabelle mit Iteration | Ausgewählte kante | g(v) f.A. v aus V © 2006 J Flick – Vorbereitungen zur GDI2 Klausur – 7/11 Vorbereitungen zur GDI2 Klausur letztes Update: 6.10.2006 @ 20 Uhr Vers. 1.2 Flußprobleme • Kapazitätsbeschränkung: f(e) <= c(e) • Flußerhaltung: ∑ f(w,v) = ∑ f(v,w) (Alles was rausfließt, fließt auch irgendwo rein) • Algorithmische Idee: • Sollange zunehmeder Fluss existiert -> trage ihn ein Zunehmenden Fluss per BFS oder DFS finden! Ford-Fulkerson Algorithmus • Für alle Kanten e: Setze f (e) = 0 // Zu Beginn "fließt nichts". • do • Für alle Knoten v: p (v) = null; b (v) = unbesucht • z (q) = ∞; p (q) = unbekannt; • Solange existiert: Knoten v mit b (v) == unbesucht und p (v) != null • b (v) = besucht; • Für jede Kante e = (v, x) Î E mit p (x) == null und f (e) < c (e) • p (x) = v; r (x) = vor; z (x) = min (c (e) – f (e), z (v)) • Für jede Kante e = (x, v) Î E mit p (x) == null und f (e) > 0 • p (x) = v; r (x) = rück; z (x) = min (f (e), z (v)) • Falls p (s) != null? // zunehmender Fluß bis zur Senke gefunden? • zunahme = z (s); v = s; • Solange v != q • Falls r (v) = vor // Kantenmarkierung += zunahme O(|fmax| * |E|) • f ( (p (v), v) ) = f ( (p (v), v) ) + zunahme; • Falls r (v) = rück // Kantenmarkierung -= zunahme • f ( (v, p (v) ) ) = f ( (v, p (v) ) ) - zunahme; • v = p (v) • solange p (s) != null Protokollierung: Einfach nach jeder Flußzunahme Graph zeichnen! Wege-Existenz • Erstellung des Wegegraphs • Idee: Jeden Knoten als Transitknoten betrachten, wenn die Kante (x,v) und (v,y) existiert, dann füge auch (x,y) ein! • Warshall Algorithmus • for(int v=1; v <= |V|; v++) //Transitknoten v • for(int x=1; v <= |V|; x++) //von Knoten x O(|V|³ ) • for(int y=1; y<= |V|; y++) • if (A[x,v] & A[v,y]) • A[x,y] = 1: Optimaler Codebaum • Huffman • Initialisierung: Jeder Buchstabe stellt einen Baum mit entsprechender Gewichtung da (seine Wahrscheinlichkeit) • Sollange die Anzahl d. Bäume > 1 • Fasse die 2 Bäume mit jeweils kleinstem Gewicht zu einem neuen Baum zusammen (mit neuer Wurzel) • Wurzel des neuen Baums wird markiert mit der Summe der Gewichte der ursprünglichen Wurzeln • Mittlere Anz Bits = ∑ (Codebitlänge des Bu. * P d. Buchstaben) f.A. Bu © 2006 J Flick – Vorbereitungen zur GDI2 Klausur – 8/11 Vorbereitungen zur GDI2 Klausur letztes Update: 6.10.2006 @ 20 Uhr Vers. 1.2 Aus PreOrder & InOrder Baum Rekonstruieren • 1. Aus PreOrder String die Wurzel ablesen DBACFEG • 2. Aus InOrder String ergibt sich linker und rechter Teilbaum (Länge und Knoten) ABCDEFG • 3. Zählen wieviele Knoten links & rechts im InOrder String und damit die entsprechenden TeilbaumStrings im PreOrder String identifizieren DBACFEG • Wiederhole Schritte 1-3 mit den linken und rechten Pre/Inorder SubStrings für die linken und rechten Teilbäume! Dynamische Programmierung • Bellman • Ein Optimaler Suchbaum mit Wurzel x, hat links den optimalen Suchbaum 1...x-1 und rechts x+1...n • Die Suchtiefe S = S(L)+S(R) + ∑ pi (aller beteiligten knoten) Rucksackproblem • Rucksack einer bestimmten Größe mit Objekten bestimter Größen und Werte füllen • Dynamische Programmierung: Bestimme alle optimalen Rucksäcke von 0, 1...n • Initialisierung: Alle Rucksäcke mit kleinstem Objekt vollstopfen • Dann über alle Objekte iterieren (von klein nach groß) und bei jeder Kiste probieren ob das aktuelle Objekt der Größe x + bisher optimaler Rucksack der größe g = (aktuelerRucksack-x) besser ist als der Wert des aktuellen Rucksacks, wenn ja den Gegstand rein packen Data-Mining • k-Means Clustering • 1.Lege Anz. Cluster fest = k • 2. Bestimme zufällig k-Punkte im Raum ->Cluster Mittelpunkte (CMP) • 3.Für alle m Datensätze: • Bestimme euklidschen Abstand zu allen CMPs • ordne m dem nächst gelegenen CMP zu • 4. Bestimme wahren Mittelpunkt eines Cluster als neuen CMP • 5. Wiederhole 3-5 bis alte & neue CMP sich kaum unterscheiden! © 2006 J Flick – Vorbereitungen zur GDI2 Klausur – 9/11 Vorbereitungen zur GDI2 Klausur Algorithmen-Übersicht Algorithmus letztes Update: 6.10.2006 @ 20 Uhr Wozu? Wie? Vers. 1.2 Komplexität DFS Baum traversieren Tiefensuche/ Rekursion O(max(|V|,|E|) BFS Baum traversieren Breitensuche (Schlange) O(max(|V|,|E|) Top-Down Topologische Sortierung Streiche sollange Knoten mit O(|V|² ) d- = 0 ausem Graph bis Graph leer Bottom-Up Topologische Sortierung DFS von alle Knoten mit d- = O(max(|V|,|E|)) 0 und Rückwärts Besuchnummern vergeben Kruskal minimaler Spannbaum Kanten nach Gewicht ordnen. Und Kanten, die keinen Zyklus verursachen einfügen Prim minimaler Spannbaum Von einer Knotenmenge aus O(|E| + |V| log |V|) die kürzeste erreichbare azyklische Kante hinzufügen Moore-Algorithmus Kürzester Weg bei Kantengewichte = 1 Per BFS durch den Baum O(max(|E|,|V|) gehen und für jeden Knoten die Entfernung des Nachbars als 1 + eigene Entfernung setzen Dijkstra Kürzester Weg bei Knoten besucht markieren, pos Kantengewichten Entfernung der Nachbarknoten aktualisieren und den Randknoten besuchen, dessen Entfernung am kürzesten ist A* Kürzester Weg, bei bekannter Luftline zum Ziel (und pos. Kantengewichten) Wie Dijkstra nur das der wie Dijkstra, aber Knoten gewählt wird, dessen am Mittel deutlich Luftlinie + Entfernung am schneller fertig ^^ geringsten ist Ford-Fulkerson Flußprobleme, Heiratsproblem Sollange es zunehmenden O(|fmax| * |E|) Fluss gibt, eintragen! Finden per BFS/DFS Beim Heiratsproblem, extra Quelle/Senke einfügen! Warshall Wegegraph Jeden Knoten v als O(|V|³) Transitknoten betrachten und (x,v) & (v,y) => (x,y) PreOrder Baum Traversierung WLR per Rekursion O(|V|) InOrder Baum Traversierung LWR per Rekursion O(|V|) PostOrder Baum Traversierung LRW per Rekursion O(|V|) Huffman Optimaler Codebaum Mobilé-Prinzip. Die beiden Verlustfreie kleinsten Gewichte Komprimierung! zusammen fassen... © 2006 J Flick – Vorbereitungen zur GDI2 Klausur – O(|E| log |E|) O(|V|² ) bis O(|E| log|V|) (je nach Implementierung -> Priority Queue) 10/11 Vorbereitungen zur GDI2 Klausur letztes Update: 6.10.2006 @ 20 Uhr Algorithmus Wozu? Vers. 1.2 Wie? Komplexität Bellman Optimaler Suchbaum Bottom-Up. Erst alle Optimalen Bäume von 1,2... n finden Rucksack Rucksack optimal füllen O(n³ ) Über alle Gegenstände O(Objekte * iterieren, ob sie eine Rucksackgröße) verbesserung der Rucksäcke 0,1...n zur Folge hätten Komplexitäten der Sortieralgorithmen Best Case Worst Case Ave Case Selection Sort n² n² n² Insertion Sort n n² n² Bubble Sort n n² n² Quick Sort n log n n² n log n Heap Sort n log n n log n n log n Proxmap Sort n n² n © 2006 J Flick – Vorbereitungen zur GDI2 Klausur – 11/11