Aud – Zusammenfassung Man muss sich immer die Implementierte

Werbung
Aud – Zusammenfassung
-
Man muss sich immer die Implementierte Beispiele ansehen und zumindest verstehen 
§2 Listen
Listen als Felder
-
-
-
Attribute
o T[] data
speichert Daten als Feld
o Int capacity
Länge des Feldes = momentan verfügbarer Speicherplatz
o Int size
Anzahl Einträge in Vector = momentan benötigter Speicherplatz
Operationen
o T at(int i)
Zugriff auf Eintrag i
o Reserve (int i)
reserviert Einträge/ erhöht capacity
o Rezise (int n)
erweitert oder schrumpf Vector
o Push_back(T obj)
fügt Eintrag am Ende ein
o Insert_back(int i, T obj)
fügt Eintrag an Position i ein
o Pop_back()
löscht den letzten Eintrag
o Erase()
löscht Eintrag i
Mittlerer Aufwand n:size() Einträge
o Size
O(1)
o At
O(1)
o Push_back
O(1)
o insert
O(n)
o pop_back
O(1)
o erase
O(n)
o Verschieben O(n)
Verkettete Listen
-
Jetzt Referenzen auf den folgenden Eintrag
Jeder Eintrag wird als Knoten (node) erfasst
(data, next) -> null
Operationen wie oben
Mittlerer Aufwand n:size() Einträge (immer O(n)
Einfügen/ Löschen jetzt in O(1) falls Position bekannt (front, push_front, pop_front)
Einfügen / Löschen = Umsetzen der next Referenz
Doppelt verkettete Listen
-
-
Referenz auf Vorgänger, Nachfolger (vorne und hinten = null bzw. tail oder head)
Mittlerer Aufwand für n:size() Einträge
o Size
O(n)
o Front/back
O(1)
o At
O(n)
o Push_front/push_back
O(1)
o Insert
O(n)
o Pop_front/ pop_back
O(1)
o Erase
O(n)
Einfügen/Löschen = Umsetzen der prev und next Referenzen
Iteratoren (Abstraktes Konzept zum Traversieren von Daten (Durchlaufen der Liste von head nach tail))
S. 1
Stack
-
Top
Push
Pop
Is_empty
oberstes Element auslesen
Element auf den Stapel ablegen
oberstes Element von Stapel nehmen
Ist Stapel leer ?
Enqueue
Dequeue
Front
Element hinten anstellen
Element vorne entfernen
vorderstes Element auslesen
Queue
-
(Ringpuffer, DList)
§3 Bäume
-
Knoten(node), Wurzel(root), Kante(edge)
Kanten verbinden Knoten
Bäume wachsen von oben nach unten, Wurzel = oberster Knoten
Kinderknoten(child), Elternknoten(parent), Teilbaum (subtree), Blatt(leaf)
Wurzel hat kein Elternteil
Jeder andere Knoten hat genau ein Elternknoten
Jeder Knoten definiert einen Teilbaum.
Interne und externe Knoten, Blätter haben keine Kinder
Niveau 0, Niveau 1,...
Pfad = Folge von durch Kanten verbundene Knoten
Zu jedem Knoten existiert genau ein Pfad von der Wurzel
Höhe = maximales Niveau + 1 bzw. Anzahl Ebenen
-
Ein Baum, bei dem jeder Knoten höchstens zwei Kinderknoten hat, heißt Binärbaum.
Ein Binärbaum heißt voll, wenn jeder Knoten entweder 0 (Blätter) oder 2 (innere Knoten) Kinder hat.
Ein voller Binärbaum heißt vollständig, wenn alle Blätter auf derselben Ebene liegen.
Binärbäume in Java
-
-
Attribute
o BinaryTree<T> parent_
o BinaryTree<T> left_, right_
o T data_
Zugriff über Selektoren
o BinaryTree<T> getParent()
o BinaryTree<T> getLeft(), getRight()
o Boolean isRoot()
o Boolean isLeaf()
Vater
Kinder
speichert Datum
ersetzt Eltern
ersetzt Kinder
traversiert aufwärts und liefert Wurzel
Traversierung von Binärbaumen
-
S. 2
Rechenaufgaben mit Stack bzw. Binärbaum (MUSS MAN VERSTANDEN HABEN !!!)
Durchlauf des gesamten Baumes
o Infix-Notation
x+y
o Postfix- Notation
xy+
o Prefix – Notation
+xy
Preorder Traversal
o Aktueller Knoten, Linker Teilbaum, Rechter Teilbaum
-
-
Inorder Traversal
o Linker Teilbaum, Aktueller Knoten, Rechter Teilbaum
Postorder Traversal
o Linker Teilbaum, Rechter Teilbaum, Aktueller Knoten
Levelorder Traversal
o Durchlauf der einzelnen Ebenen von links nach rechts
(Syntaxanalyse, BNF, ...)
Endrekursion
o Rekursiver Aufruf ist letzte Aktion (LERNEN WIE DAS GEHT !!!)
§4 Suchbäume
Binäre Suchbäume
-
-
-
-
S. 3
Knoten X enthält Schlüsselwert key().
Baumstruktur definierter Ordnung: Alle Schlüsselwerte im
o Linker Teilbaum left() sind kleiner als key()
o Rechter Teilbaum right() sind größer als key()
Suche (Beginn bei Wurzel, Abstieg in Baum, Rekursiv oder Iterativ)
Minimum = Knoten „links unten“ // Maximum = Knoten „rechts unten“
Inorder – Iteration zählt sortierte Folge auf
Bereich = range(), sortierte Folge im Intervall (Teilfolge)
Neuen Eintrag / Knoten einfügen
o Erfolglose Suche -> letzter besuchter Knoten X
o Erzeuge neunen Knoten Y mit Schlüssel k
o Einhängen von Y unter X als linkes oder rechtes Kind
Hilfsknoten (Head, nil)
Löschen eines Eintrages (Hochziehen eines Teilbaumes)
o X ist Blatt, X hat kein Kind
 Entferne Knoten X
o X hat ein Kind
 Ersetzte Knoten X durch dessen Kind Y (=Teilbaum)
 Hochziehen von Y
 Hier analog zum Löschen aus einer verketteten Liste
o X hat zwei Kinder
 Suche Knoten M in R, der am weitesten links steht (Minimum)
 Seien P Vater und MR rechtes Kind von M
 Ersetze X durch M
 Setze L als linkes Kind und R als rechtes Kind von M
 Setze MR als linkes Kind von P ein
Höhe abhängig von Einfügereihenfolge
Mögliche Binärbäume (Übersicht kennen !!)
Rotationen
o Einfach Rotation (rechts // links)
o Doppel Rotation (rechts- links // links – rechts)
o Algorithmus
 Sei a,b,c Inorder-Folge der Knoten x,y,z. Seien T0, T1, T2, T3 Inorder-Folge der Teilbäume
unter x,y,z.
 Ersetze Teilbaum mit Wurzel z durch Teilbaum mit Wurzel b
 Nimm a als linkes Kind von b mit Kindern T0, T1.
 Nimm c als rechtes Kind von b mit Kindern T2, T3.
Balancierte Bäume
-
Balance/Ausgleich = minimiere Höhe,
Keine Entartung zur Liste, aber auch keine voll ausgeglichenen binär Bäume möglich.
Stattdessen Garantien (Höhe h begrenzt durch O(logn))
AVL –Bäume
-
-
Definiere Balance als Höhenunterschied bal(T) = h(TR) – h(TL)
Ein binärer Baum heißt AVL-Baum, wenn bal(T) € {-1,0,1} an allen Knoten (für alle Teilbäume) T gilt.
o Das heißt die Höhe von linkem und rechten Teilbaum unterscheiden sich höchstens um 1.
o AVL-Kriterium muss für alle Teilbäume ausschlusslos gelten.
Einfügen in AVL-Baum
o Ist ja Binärer Suchbaum
o Einfügen von neuem Knoten
o Wenn AVL-Eigenschaft verletzt wiederherstellen der Eigenschaft
 Rotation oder Doppelrotation (2 Varianten: LL; RL)
2-3-4 Bäume
-
-
-
Jeder interne Knoten hat 2,3 oder 4 Kinder.
Jeder innere Knoten hält 1,2 oder 3 Schlüssel.
Sortierte Reihenfolge der Schlüssel (Teilbäume)
Split
o Reihenfolge der Teilbäume bleibt erhalten
o Neuer Wurzelknoten b wird in Elternknoten hochgezogen.
 Verschmelzung (merge) mit Elternknoten
Bottom-Up
o Erfolglose Suche bis zu einem Blatt
o 1.Fall Einfügen in 2- oder 3- Knoten
o 2.Fall Einfügen in 4-Knoten
 Teile 4-Knoten (split)
 Split des Elternknoten möglich, ggf. bis zu Wurzel möglich
o Splits von „unten nach oben“
Top-Down
o Erfolglose Suche bis zu einem Blatt
o Teile dabei im Abstieg alle besuchten 4-Knoten (split)
o Füge Eintrag in Blattknoten ein
o Splits von „oben nach unten“
Rot-Schwarz-Baum
-
-
S. 4
Ein Rot-Schwarz-Baum ist ein binärer Suchbaum, in dem jedem Knoten ein Farbattribut zugeordnet ist, so
dass gilt:
o Ein Knoten ist entweder rot oder schwarz
o Die Wurzel ist schwarz
o Alle Blätter sind schwarz
o Beide Kinder eines roten Knotens sind schwarz
o Jeder Pfad von einem gegebenen Knoten zu einem erreichbaren Blatt enthält dieselbe Anzahl
schwarzer Knoten
o (Blätter sind Null-Knoten)
Umstrukturierung bei Verletzung der Eigenschaften für Balance (BILDER ANSCHAUEN !!!!)
Eigenschaften von AVL- und Rot-Schwarz-Bäumen
-
Baum mit n Einträgen benötigt Speicherplatz in O(n)
Suche in O(logn)
Einfügen O(logn)
Löschen O(logn)
Suchen in AVL-Bäumen ist effizienter, da geringere Höhe
Einfügen in Rot-Schwarz-Baum ist effizienter, möglich.
B-Bäume
-
-
-
AVL-und Rot-Schwarz-Bäume = viele kleine Datenpakete geschrieben
Für zB. Dateisysteme (Verzeichnisstruktur) oder Datenbanken sind balancierte Binärbäume nicht geeignet.
Annahmen:
o Alle Pfade zu den Blättern sind gleich lang.
Ein Baum heißt B-Baum, wenn er für m > 0 folgende Eigenschaften erfüllt:
o Jeder Knoten hat höchstens 2m+1 Kinder
o Jeder Knoten hat mindestens m+1 Kinder – mit Ausnahme der Wurzel: sie hat mindestens 2 Kinder
oder ist ein Blatt
o Jeder innere Knoten mit k Schlüsseln hat k+1 Kinder
o Alle Blätter liegen auf der gleichen Ebene.
Jeder Knoten ist mindestens bis zu Hälfte gefüllt.
Es wird immer eine ganze Seite gelesen / geschrieben.
Suche
o Beginne bei Wurzel
o Suche Schlüssel k im Knoten
o Ggf. rekursiver Abstieg.
Einfügen
o Erfolglose Suche bis zu einem Blattknoten
o 1. Fall Knoten hat <2m Einträge -> in Liste einsortieren
o 2.Fall Knoten hat =2m Einträge -> erzeuge neuen Knoten
 Linke Hälfte der Einträge (m Stück) bleibt
 Rechte Hälfte wird in neuen Knoten verschoben
 Mittlerer Eintrag wird in Elternknoten eingefügt
o Einfügen setzt sich ggf. rekursiv bis zur Wurzel fort.
(SPlay Tree, Tries, Set, Map)
§5 Heaps
-
-
S. 5
Priority queue (Erledigt wichtigste Aufgabe zuerst, sortiert sich selbst, nach Kriterium (festgelegt))
Ein Binärbaum ist ein Heap, wenn für jeden Knoten X (außer der Wurzel) gilt X>= parent(X).
o Min-Heap
o Zugriff auf kleinsten Eintrag (=Wurzel) in O(1)
o Alle Ebenen bis auf letzte sind vollständig gefüllt.
o Die letzte Ebene ist „linksbündig“ gefüllt.
o Baum lässt sich ebenenweise auf ein Feld ak abbilden.
Operationen
o Zugriff auf den kleinsten Eintrag
o Einfügen eines neuen Eintrags
o Entfernen des kleinsten Eintrags (Wurzel)
-
-
-
-
-
-
o Ersetzen des kleinsten Eintrags
o Verwende Einfügen und Entfernen zum Sortieren: Heapsort
Im folgenden sei a Heap mit n Einträgen ak, 1<=k <=n
Einfügen
o Einfügen als neuen Blattknoten
o Erhalte dabei Struktureigeenschaft „linksbündig“
o Heapeigenschaften wieder herstellen
 Beginne mit neuem Knoten x
 Solange Wert des Vaterknotens p >x
 Vertausche Werte von p und x
 Weiter mit Überprüfung von Vaterknoten p
o Eingefügter Knoten wandert solange nach oben, bis die Heap-Eigenschaft wieder gilt.
Maximaler Aufwand ist O(logn), da Binärbaum balanciert ist.
Entfernen des kleinsten Eintrags
o Lösche Wurzel
o Ersetze Wurzel durch Eintrag „rechts unten“
o Heap schrumpft um letzten Eintrag
o Heap – Eigenschaft wieder herstellen
 Beginne mit neuer Wurzel
 Solange Wert von w größer als kleinster Wert der Kinder
 Vertausche Werte Wurzel <-> Kind
 Weiter mit entsprechendem Kind als neuer Wurzel w
o Knoten wandert nach unten, bis Heap-Eigenschaft wieder gilt
o Maximaler Aufwand ist O(log n), da Binärbaum balanciert ist.
o Balance bleibt wieder erhalten !
Bottom-up
o Annahme: alle Teilbäume unter Ebene i sind bereits Heaps
o Kann Heaps auf Ebene i durch downheap konstruieren
o Starte mit vorletzter Ebene i = h-1 -> Annahme erfüllt
 Konstruiere alle Heaps bis Ebene i mit downheap
 Wiederhole für i:=i-1 bis Wurzel erreicht wird
o Verschmelzen von Heaps mittels dwonheap
o Rechenbeispiel (schlechtester Aufwand = O(n))
Top-down
o O(n log n) im schlechtester Aufwand
o Erzeuge Binärbaum durch insert
Eigenschaften von Heapsort
o Heapsort benötigt O(n log n) Operationen im Mittel und im schlechtesten Fall
o Heapsort arbeitet in-place
o Heapsort ist nicht stabil !!!
o Sortierreihenfolge beachten !!!
Aufwand im schlechtesten Fall
o Minimum / Maximum
O(1)
o Einfügen
O(log n)
o Entfernen
O(log n)
o Kleinstes Ersetzen
O(log n)
o Aufbau/Zusammenführen
O(n)
o Heapsort
O(n log n)
§6 Hashverfahren
S. 6
Bijektive Funktion zur Zuordnung
Adressierung durch Schlüssel, aber begrenzter Speicher, und Suche in konstanter Zeit
-
-
Prinzip
o Einfache Datenstruktur (Feld, Tabelle)
o Hashtabelle (Streuwerttabelle)
o Bestimmung der Position eines Objektes durch Hashfunktion
 Objekt als Paar von Schlüssel und Wert
 Adressierung: Anwendung der Hashfunktion auf Schlüssel
Eigenschaften
o Eine Hashfunktion muss
 Konsistent sein
 Deterministisch sein
o Eine Hashfunktion soll möglichst
 Effizient berechenbar sein (in jedem Fall O(1))
 Zu einer Gleichverteilung von Schlüsseln führen
 Möglichst wenige Kollisionen
 Ganze Tabelle ausnutzen
o Die Hashfunktion soll Daten möglichst gut streuen, d.h. möglichst zufälliges Verhalten.
o H(x)=x mod m (Streuung hängt von m ab)
o Überlauf beachten
Kollisionen
-
-
S. 7
Verkettung innerhalb eines bucket
o Jeder Tabelleneintrag speichert Liste von Einträgen (verkettete Liste)
o Einfügen
 Neuer Eintrag wird in Liste eingefügt
 Bei Kollision hat Liste schon mehr als einen Eintrag
o Suchen
 Abbruch bei leerer Liste -> erfolglose Suche
 Ansonsten wird Liste nach Eintrag durchsucht, dazu wird jeder Eintrag auf Gleichheit
getestet
 Diese sequenzielle Suche kann immer noch erfolglos sein !!
o Löschen
 Erfolgreiche Suche liefert Liste und Listeneintrag
 Lösche Eintrag aus Liste
o Eigenschaften
 Einfach zu implementieren
 Einfügen in konstanter Zeit O(1)
 Reduziert Anzahl Vergleiche bei Suche im Mittel um Faktor m
 Im Vergleich zur Liste
 Trotzdem im schlechtesten Fall ebenso O(n)
 Keine Sonderbehandlung von gelöschten Einträgen
 Durchschnittlicher Aufwand für Suche (a = Durchschnittslänge von bucket)
 Erfolglos 1+a
 Erfolgreich 1+ (a/2)
Offene Adressierung
o Lineares Sondieren
 Falls ein Eintrag h(x) bereits besetzt ist, teste nacheinander die Einträge, solange bis ein
freier Eintrag gefunden wird.
 Sondieren beim Einfügen und Suchen.
 Achtung beim Löschen
 Ersetzen durch speziellen Wert, der eine vormals belegte Position markiert.
 Sonst wären nachfolgende Einträge nicht mehr erreichbar !


-
Klumpenbildung ist hier Gefahr (schelchte Streuung, schlechte Ausnutzung)
Anzahl Sondierungen im Mittel
 Erfolglos (1/2)(1+(1-a)-²)
 Erfolgreich (1/2) (1+(1-a)-1 )
 Einfügen und Suchen mit linearen Sondieren benötigt im Mittel weniger als 5 Sondierungen
 Je höher Füllstand, desto schlechter Such- und Einfügeverhalten
 Einfügen und Suchen im Mittel in O(1)
 Aber Aufwand für rehashing in O(n) !!
o Quadratisches Sondieren
 Wie lineares Sondieren, aber quadratische Funktion
 Ziel: Clustering vermeiden
 Falls Eintrag h(x) bereits besetzt ist, teste nacheinander die Einträge, solange bis ein freier
Eintrag gefunden wird.
 Allgemeiner: addiere quadratische Funktion
 Anfällig für schlecht gewählte Tabellengröße m !
 Immer noch „Sekundärkluster“ (Abbildung von Mustern)
o Doppel-Hashing
 Ziel: Reduziere clustering effektiv !
 Verwende zweite Hashfunktion h2 ungleich h
 Falls Eintrag h(x) bereits besetzt ist, teste nacheinander die Einträge h(x)+i*h2(x)
 Anzahl Sondierungen im Mittel
 Erfolglos (1/(1-a))
 Erfolgreich (1/a) ln (1/(1-a))
 Doppel-Hashing benötigt im Mittel weniger Sondierungen las lineares Sondieren
Wichtige Übersicht
o Typischerweise Suchen, Einfügen, Löschen in O(1)
o Abhängig von Füllgrad a
o Einfügen im schlechtesten Fall in O(n)
(Dynamische Hashverfahren, Anwendungen von Hashfunktionen,...)
§7 Graphen
-
-
-
S. 8
Ungerichtete Graphen
o Ein ungerichteter Graph ist ein geordnetes Paar G = (V,E) mit
 einer Menge von Knoten v und
 einer Menge von Kanten E
o Kanten sind ungerichtet (beide Richtungen)
Gerichtete Graphen
o Ein gerichteter Graph ist ein geordnetes Paar G = (V,E) mit
 einer Menge von Knoten V
 einer Menge von Kanten E
o Kanten sind jetzt geordnetes Paar, d.h. gerichtet
o Schleifen sind erlaubt
Gewichtete Graphen
o Ein gewichteter Graph ist ein (gerichteter oder ungerichteter) Graph G=(V,E) zusammen mit einer
Funktion.
o Gerichtet oder ungerichtet möglich
o Andere Wertebereiche möglich
o Keine negativen Zahlen bzw. Werte
Begriffe zu Graphen
-
-
-
-
Teilgraph definiert durch Teilmenge von V und E
Grad eines Knotens
o Anzahl der eingehenden Kanten in ungerichteten Graphen
o Unterscheide indegree und outdegree in gerichteten Graphen
Ein gerichteter Graph ist symmetrisch, wenn zu jeder Kante (i,j), auch die entgegengesetzte Kante
(j,i)existiert.
Eine Folge von Knoten v1,v2,vn ... die durch Kanten verbunden sind heißt
o Pfad (wenn alle Knoten vi verschieden sind)
o Zyklus
Ein gerichteter Graph heißt zyklisch, wenn er einen Zyklus enthält.
o Ansonsten azyklisch
Multigraphen
o Verbindung von zwei Knoten durch mehr als eine Kante
o Als Abgrenzung oft: einfacher Graph = ungerichteter Graph ohne Mehrfachkanten
Hypergraphen
o Kante verbindet mehr als einen Knoten gleichzeitig
o Kante = Teilmengen verbundener Knoten
Datenstrukturen für Graphen (ANSEHEN !!!)
-
-
-
-
S. 9
Kantenliste
o Speichere Kanten E als Liste
o Erste zwei Einträge bezeichnen die Anzahl Knoten und Kanten.
o Je zwei aufeinanderfolgende Einträge bezeichnen eine Kante.
o Knoten werden durch Indices (int) bezeichnet.
Knotenliste
o Speichere Nachbarschaft von Knoten für gerichteten Graphen ausgehende oder eingehende Kanten.
o Erste zwei Einträge bezeichnen die Anzahl der Knoten und Kanten.
o Nächste Zahl speichert Anzahl ausgehender Kanten.
o Er folgt Liste der Nachbarknoten.
o Auch Möglichkeit in zwei Listen zu speichern:
 Neue Tabelle nodeNhd speichert Indices in neighborhoods, Längenangaben entfallen.
 Nachbarschaft des i-ten Knotens in neighborhoods, an Position nodeNhd[i-1]
 Anzahl Knoten = nodeNhd.length-1
 Anzahl Kanten = nodeNhd[nodeNhd.length-1]
Eigenschaften von Kanten- und Knotenlisten
o Eignen sich für nicht veränderbare Graphen
o Kantenlisten
 Einfaches Zeichnen
 Aufzählung der Nachbarschaft von Knoten
 Knotenindices werden mehrfach gespeichert
o Knotenlisten
 Erlaubt einfache Aufzählung der Nachbarschaft von Knoten
 Zusätzliche Tabelle von Knoten erleichtert Suche !
 Entscheidung (i,j) benötigt Suche innerhalb Nachbarschaft
 Effiziente Aufzählung der eingehenden Kanten erfordert zweite Tabelle (für gerichtete
Graphen).
Adjazensmatrizen (ANSEHEN !!!!)
o Kodiere Kanten als Einträge in Matrix.
o Zeile i = Index des Startknotens
o
o
o
o
o
-
Spalte j = Index des Endknotens
Menge X mit 0 (X= {0,1}, X=N)
Zeile i in A liefert Nachbarschaft von Knoten i (von i ausgehende Kanten)
Spalte j in A liefert in j eingehende Kanten
Adjazensmatrizen sind symmetrisch für
 Ungerichtete Graphen
 Symmetrische (gerichtete) Graphen
o Es genügt, untere oder obere Dreiecksmatrix zu speichern.
o Ohne Diagonale, falls keine Schleifen erlaubt sind.
o Gewichteter Graph -> Zahlen codieren Gewichte. (Gewicht 0 ist unzulässig.)
o Eigenschaften:
 Einfügen / Löschen von Kanten in O(1)
 Entscheiden (i,j) in O(1)
 Aufzählen der Nachbarschaft eines Knoten in O(n) (Auslesen einer Zeile)
 Einfügen eines Knotens O(n²)
 Erweitern auf (n+1)*(n+1) Matrix
 Speicher vorreservieren
 Löschen eines Knotens
 O(n) falls Einträge in Zeile und Spalte auf 0 gesetzt werden
 O(n²) falls Zeile und (!) Spalte gelöscht werden
 Speicherbedarf in O(n²)
 Alle Operationen sind abhängig von Anzahl der Kanten
Adjazenslisten
o Speicherbedarf O(|V|+|E|)
o Aufwand für Operationen abhängig von Listendarstellung
o Einfügen von Kanten
 Muss testen ob Kante bereits existiert !
 Erfordert Suche in Nachbarschaft
o Löschen von Knoten
 Muss Knoten auch aus Nachbarschaften löschen !
 Erfordert Suche in alle Nachbarschaften !
(Übersicht des Aufwandes ist in Tabelle §7 Folie 31 sichtbar dargestellt)
(Dünnbesetzte Adjazensmatrizen, Implementierung, Beweis,...)
§8 Algorithmen auf Graphen
-
Tiefensuche (DFS)
o Vorgehensweise als Quelltext
Breitensuche (BFS)
o Vorgehensweise als Quelltext
Bemerkungen DFS / BFS
o Liefert Baum mit Startknoten als Wurzel = aufgespannter Baum des Graphen (spanning tree)
(Zeitpunkte, Distanzen, Klassifizierung,...)
-
S. 10
Topologisches Sortieren
o Gegeben ist ein azyklischer gerichteter Graph
o Gerichtete Kanten definieren eine partielle Ordnung
o (i,j) -> i kommt vor j
o Interpretiere Knoten
o Kanten modellieren Abhängigkeiten
o
o
o
o
-
-
-
-
-
S. 11
Gesucht ist eine Reihenfolge der Knoten, so dass jeder Knoten nach all seinen Vorgängern erscheint
Reihenfolge i.a. nicht eindeutig !!!
Reihenfolge: Quellen am Anfang, Senken am Ende
Idee:
 Starte von allen Senken
 DFS in umgekehrter Richtung (entlang eingehender Kanten)
 Gibt Knoten aus, wenn alle eingehenden Kanten abgearbeitet
o Zu ausgegebenen Knoten gibt es keine Abhängigkeit mehr.
o Erweiterung zum Erkennen von Zyklen
 Laufe über Kante (i,j) (rückwärts j -> i), wobei i noch nicht ausgegeben aber schon markiert
o Idee 2
 Finde alle Knoten ohne eingehende Kanten (Quellen)
 Gibt diese Knoten aus und...
 entferne sie zusammen mit allen ausgehenden Kanten
 Wiederhole bis Graph leer ist.
 Zyklus falls Graph nicht leer und keine Quelle gefunden wird.
 Graph wird verändert statt durchlaufen.
Kürzeste Wege
o Finde kürzeste Wege in gewichteten Graphen.
o Länge von Wegen = Summe der Kantengewichte
o Idee:
 Modifizierte Breitensuche
 Besuche immer den nächstgelegenen Knoten
Priority Queue (Quellcode)
Priority fist search = Algorithmus von Dijkstra
o Beachte mögliche Aktualisierungen von Distanzen
 D[t] wird erniedrigt, Elternknoten p[t] wird angepasst,
 Aktualisieren der PQ durch open_lower(t)
o Berechnen der kürzesten Distanzen d[] zu allen Knoten und des shortest path tree (SPT)
o Pfade in SPT zur Wurzel = kürzeste Wege zum Start
o Alternativ:
 Kürzester Weg = kürzeste Wege zum Start
 Erster Knoten = Startknoten
 Abbruch, sobald der zweite Knoten abgearbeitet wurde
Greedy Algorithmus
o Wähle in jedem Schritt die aktuell günstigste Möglichkeit !
o Entscheidung anhand lokaler Kriterien
o Gefahr: Erreichen und Verharren in lokalen Minimum
o Für Priority First Search
 Nimm Knoten mit kürzester Entfernung aus PQ
 Revidiere ggf. vorhergehende Berechnung
 PFS findet global kürzeste Wege
Backtracking (LESEN !!!)
Minimum Spanning Tree (MST)
o Als Spannbaum oder spanning tree ST) eines ungerichteten (und zusammenhängenden) Graphen
bezeichnet man einen Teilgraphen, der (1) ein Baum ist und (2) alle Knoten des Graphen enthält.
o Ein Spannbaum eines gewichteten Graphen heißt minimaler Spannbaum oder minimum spanning
tree (MST), wenn die Summe der Kantengewichte minimal ist. D.h. es gibt keinen weiteren
Spannbaum mit geringerem Gesamtgewicht.
Kürzeste Wege und MST berechnen mit PFS
o Algorithmus von Dijkstra zur Berechnung kürzester Wege
 Wähle Knoten mit kürzester Distanz
o
 Priorität = Wegstrecke
 Minimiere Länge von Pfaden im Spannbaum -> SPT
Algorithmus von Prim zur Berechnung des MST
 Wähle Knoten, der über kürzesten Weg erreichbar ist
 Priorität = Kantenlänge
 Minimiere Summe der Kantengewichte im Spannbaum -> MST
(Bellmann Ford Alg. , A* Alg.,....) //Fluss in Netzwerken // -> nicht relevant
§9 Dynamische Programmierung
-
-
-
Optimierungsprobleme (höchster Gewinn, geringste Kosten)
Systematisches Durchsuchen des Lösungsraumes
Rucksackproblem (VERSTEHEN !!!!)
Zielfunktion, Nebenbedingungen
Brute-Force-Suche
o Systematisches Aufzählen und Bewerten aller Belegungen
o O(2^n)
o Frühzeitiger Abbruch möglich, falls Kapazität erschöpft !
o Verbesserung durch pruning (Stutzen von unzulässigen Zweigen im Entscheidungsbaum)
Greedy-Algorithmus
o Bei jeder Entscheidung siegt die Gier
o Reduktion auf wenige Entscheidungen
o Beschneidung des Lösungsraums
o Keine Garantie, dass optimale Konfiguration erreicht wird !
o Lösung abhängig von Entscheidungskriterium
o Es ist oft möglich gute Konfigurationen schnell zu finden.
o In der Regel wird nur das lokale Optimum erreicht!
Optimale Lösung besteht aus optimalen Teillösungen
Gilt rekursiv für jede optimale Teillösung
Es müssen nur optimale Teillösungen beachtet werden.
Speicherung der Zwischenergebnisse in Tabelle, damit man sie nicht immer neu berechnen muss.
Backtracking zum Finden der optimalen Lösung notwendig (ANSEHEN !!!)
Dynamische Programmierung
o Ziel: Lösen von Optimierungsproblemen
o Zerlege Problem in einfache Teilprobleme
 Kleine Probleme können effizient gelöst werden
 Am besten Definition mit Indizes
o Annahme:
 Optimale Lösung, besteht aus optimalen Teillösungen
o Optimale Teillösungen sollten sich überlappen, d.h. voneinander unabhängige Teile können
wiederum gemeinsame Teilprobleme enthalten
 Im Gegensatz zu divide and conquer Ansatz
 Jede Teillösung wird einmal berechnet und gespeichert
o Definition der optimalen Lösung i.d.R rekursiv
o Iterativer Algorithmus zur Lösung
 Von kleinen zu größeren, zusammengesetzte Teilprobleme
 Speichere Lösungen in Tabelle
Voraussetzungen für Dynamische Programmierung
S. 12
Problem lässt sich geeignet zerlegen
Optimalitätsprinzip muss gelten
Beispiele für solche Probleme (siehe Hefter 9/30)
Optimierung mit Dynamischer Programmierung
-
-
Analysiere Problem
o Charakterisierung der Lösung mit ganzzahligen Indizes ?
o Optimalitätsprinzip gegeben ?
o Überlappende optimale Teillösungen ?
Definiere optimale Lösung durch Rekursionsgleichung
Iterative Konstruktion der Lösung
o Speichere optimale Teillösungen in Tabelle (Indizierung nötig !!)
o Bottom – up Konstruktion
Ansätze zur Lösung von Problemen
-
Fundamentale Prinzipien zum Entwurf von Algorithmen
Schrittweise Verfeinerung
Teile und Herrsche (divide and conquer)
Greedy Methoden
Dynamische Programmierung
Backtracking als Baustein
(Matrixprodukte, Caveat,....)
S. 13
Herunterladen