Algorithmen und Datenstrukturen Einleitung

Werbung
Einleitung
Algorithmen und Datenstrukturen
Beispiel: Sortieren (Spezifikation 1)
• Eingabe: Zahl n ∈ N, Zahlenfolge a ∈ Nn
Johannes Waldmann, HTWK Leipzig
• Ausgabe: Zahlenfolge b ∈ Nn mit:
Vorlesung, SS 17
– Daten-Erhaltung:
Multimenge von a = Multimenge von b
– Monotonie:
b ist schwach monoton steigend.
Beispiel:
• Eingabe: n = 4, a = [5, 1, 0, 1].
• Multimenge von a? korrekte Ausgabe(n)?
– Typeset by FoilTEX –
– Typeset by FoilTEX –
Beispiel: Sortieren (Implementierung 1)
Beispiel: Sortieren (Implementierung 2)
• Algorithmus: Sortieren durch Auswählen (selection sort)
• nur für den Fall n = 4
• benutzt Operation cexb(i, j) (compare-exchange):
wenn bi > bj , dann vertausche bi mit bj
b := a;
für nat i von 1 bis n
nat k := i;
für nat j von i + 1 bis n
wenn b[j] < b[k] dann k := j
// b[k] ist minimal in b[i..n]
vertausche b[i] mit b[k];
• Algorithmus (Ansatz)
b := a; cexb(1, 2); cexb(3, 4); cexb(1, 3); cexb(2, 4);
• Beweise: jeder Algorithmus, der nur cex-Operationen
verwendet, ist daten-erhaltend.
• erfüllt der o.g. Algorithmus die Monotonie-Eigenschaft?
Nein. Warum nicht?
• Beispiel-Rechnung für a = [5, 1, 0, 1]
• allgemein:
– Korrektheit (Daten-Erhaltung, Monotonie)?
– Laufzeit?
• Füge eine cex-Operation hinzu, so daß resultierender
Algorithmus korrekt ist.
– Typeset by FoilTEX –
2
– Typeset by FoilTEX –
Beispiel Sortieren: Einordnung
Eine Spezifikation ist eine Relation S ⊆ E × A.
Ein Algorithmus ist
• eine Vorschrift zur schrittweisen Rechnung
• auf einer tatsächlichen (konkreten) oder gedachten
(virtuellen, abstrakten) Maschine,
• die aus einer Eingabe e ∈ E eine Ausgabe R(e) ∈ A
erzeugt—oder keine (Notation: R(e) = ⊥ mit ⊥ ∈
/ A)
• hervorragend geeignet zum Lernen v. Methoden f.
Algorithmen-Entwurf, Korrektheitsbeweis,
Laufzeit-Analyse
• der gesamte Band 3 von DEK: TAOCP behandelt
Sortieren
Der Algorithmus heißt
• . . . wer aber tatsächlich eine Liste sortiert, macht
wahrscheinlich etwas falsch:
• partiell korrekt bezüglich S,
falls ∀e ∈ E : R(e) = ⊥ ∨ (e, R(e)) ∈ S
• total (terminierend), falls ∀e ∈ E : R(e) 6= ⊥
• total korrekt bezüglich S, falls ∀e ∈ E : (e, R(e)) ∈ S
. . . und hätte besser eine andere Implementierung des
abstrakten Datentyps Menge benutzen sollen.
4
– Typeset by FoilTEX –
5
Der abstrakte Datentyp Menge (Axiome)
Der abstrakte Datentyp Menge (Signatur)
für alle e,f ∈ E, m ∈ M :
• diese Datentypen werden benutzt:
– Element-Typ E,
– Typ M der Mengen über E
1.
2.
3.
4.
5.
• diese (getypten) Funkionssymbole
gehören zur Signatur des abstrakten Datentyps Menge:
– Konstruktion:
∗ empty : M
∗ insert : E × M → M
∗ union : M × M → M
– Test:
∗ null : M → B, dabei ist B = {False, True}
∗ contains : E × M → B
– Typeset by FoilTEX –
3
Grundbegriffe: Spezifikation, Algorithmus
• das Sortieren ist eine alte und wichtige algorithmische
Aufgabe (Lochkartensortiermaschinen, Hollerith, 1908)
– Typeset by FoilTEX –
1
null(empty) = True;
null(insert(e,m)) = False;
contains(e,empty) = False;
contains(e,insert(e,m)) = True;
e6=f ⇒
contains(e,insert(f,m)) = contains(e,m);
• weitere für delete,union (Übung)
• für jede konkrete Implementierung muß Erfüllung der
Axiome nachgewiesen werden.
6
– Typeset by FoilTEX –
7
Implementierungen von Mengen
Grundbegriff: Datenstruktur
• naiv: M realisiert durch E ∗,
empty = [], insert(e, [m1, . . . , mk ]) = [e, m1, . . . , mk ]
contains(e, [m1, . . . , mk ]):
für i von 1 bis k { wenn mi = e return True } return False
lineare Laufzeit
• Def: eine (geeignete) Datenstruktur C
für einen abstrakten Datentyp S
. . . ist eine Organisationsform für Daten (ein konkreter
Datentyp) mit korrekten (und effizienten) Algorithmen,
die die Spezifikation von S implementieren.
• oft gib es mehrere geeignete C für ein S, die passende
Wahl hängt dann von weiteren Faktoren ab (z.B.
erwartetes Anzahlverhältnis einzelner S-Operationen)
• aus genauer Beschreibung der Struktur (z.B.
heap-geordneter vollständig balancierter Binärbaum)
können Implementierungen meist direkt abgeleitet
werden
• besser? verschiedene Varianten, siehe Vorlesung.
– m monoton steigende Folge:
contains logarithmisch,
aber insert und union immer noch teuer (linear)
– m als balancierter Suchbaum:
contains und insert logarithmisch,
union linear, in Spezialfällen schneller
– Typeset by FoilTEX –
8
Inhalt und Ziel der Vorlesung
• für die Lösung typischer Aufgaben, insbesondere
– Grundlagen:
konkrete Implementierungen der Konzepte (abstrakten
Datentypen), die in der Modellierung benutzt werden,
u.a.:
(Multi)Menge, Folge, Funktion, Relation, Graph
– Anwendungen: inbesondere:
Eigenschaften von Graphen (mit Kanten-Gewichten)
• (impliziert Erfüllung von Spezifikation 1)
– Eingabe: n ∈ N, a ∈ Nn
– Ausgabe: Permutation π : {1, . . . , n} → {1, . . . , n} mit:
Folge [aπ(1), . . . , aπ(n)] ist schwach monoton steigend.
• Beispiel: n = 4, a = [5, 1, 0, 1], bestimme π.
• Satz: die Abbildung von a auf aπ = [aπ(1), . . . , aπ(n)]
ist Daten-erhaltend (vorherige Def., Multimengen)
• Beweis: vergl. Anzahl der Vorkommen von z in a und aπ :
• die Methoden sind unabhängig von diesen Aufgaben
nützlich
#{i | aπ (i) = z} = #{i | aπ(i) = z} = #{π −1(j) | aj = z}|.
10
– Typeset by FoilTEX –
• Aufgabenstellung:
• naiv (schon gesehen) Sortieren durch Auswahl
– Eingabe:
∗ gerichteter Graph G = (V, E)
∗ Kanten-Gewichte w : E → Q≥0
∗ Knoten v0 ∈ V
– Ausgabe: Funktion l : V → Q≥0 ∪ {+∞} mit:
P
∗ l(v) = min{ e∈P w(e) | P ist Weg von v0 zu v}.
quadratische Laufzeit
• besser? verschiedene Varianten, siehe Vorlesung, z.B.
Set<E> m:=empty;
foreach E e in a { m:=insert(e,m); }
while not(null(m)) {
(e, m) := extract-min(m); print (e);
}
• Beispiel (siehe Tafel)
Laufzeit n · log(n) (bei guter Implementierung für Mengen)
12
Aufgabe: Rundreise
• Algorithmus? siehe Vorlesung.
– Typeset by FoilTEX –
13
Einordnung dieser VL in das Studium
• Aufgabestellung:
– Eingabe:
∗ ungerichter Graph G = (V, E) mit V = {1, . . . , n}
∗ Kanten-Gewichte w : E → Q≥0
– Ausgabe:
∗ eine Permutation π von V mit:
∗ ∀i : π(i)π(i + 1) ∈ E
P
∗ und {w(π(i)π(i + 1))|i ∈ V } ist minimal
(unter allen zulässigen π)
∗ dabei Index-Rechnung modulo n, d.h. π(n + 1) = π(1)
• Beispiel (siehe Tafel).
Auswahl von LV zu Programmierung und Algorithmen:
• 1. Sem: Modellierung
• 1./2. Sem: (AO) Programmierung
(strukturiert, imperativ, objekt-orientiert)
• 2. Sem: Algorithmen und Datenstrukturen
• 3. Sem: Softwaretechnik
• 4. Sem: Fortgeschrittene (funktionale) Progr.
• Wahl 5. Sem : Sprachkonzepte parallele Progr.
• 1. Sem Master: Prinzipien von Programmiersprachen
• Master: Theor. Inf. (Komplexität), Verifikation
• Algorithmen? siehe Vorlesung
– Typeset by FoilTEX –
11
Aufgabe: kürzeste Wege
Implementierungen von Sortierverfahren
– Typeset by FoilTEX –
9
Aufgabe: Sortieren (Spezifikation 2)
• Methoden für Analyse (Korrektheit, Laufzeit) und Entwurf
von Algorithmen und Datenstrukturen
– Typeset by FoilTEX –
– Typeset by FoilTEX –
• Wahl Master: Algorithm Design
14
– Typeset by FoilTEX –
15
Organisatorisches
Zeitplan für Übungsserien
• jede Woche 2 VL
Folien und weitere Informationen: http://www.imn.
htwk-leipzig.de/˜waldmann/lehre.html
(Sprechzeit: mittwoch 11:15, per Mail anmelden)
Grundsätzlich:
• jede Woche 1 Übung (pro Seminargruppe),
dort Vorrechnen Ihrer Lösungen der Übungsaufgaben
sollen in Kleingruppen (3 bis 4 Leute) bearbeitet werden
zur Initialisierung: in KW 14 (= aktuelle Woche = Woche 0)
• jeweils am Anfang der Woche x werden die Aufgaben der
Übungsserie x + 1 bekanntgegeben, die in Übungen der
Woche x + 1 vorgerechnet und bewertet werden.
• Ü-Serie 0 (am Ende dieses Skriptes)
zur Diskussion in Woche 0 (ab morgen),
ohne Punkte, aber autotool-Pflichtaufgabe zählt
• online-Übungsaufgaben im autotool
• Prüfungszulassung: erfolgreich Vorrechnen (60 %)
und erfolgreich autotool (60 % der Pflichtaufgaben)
• in Übungen Woche 0: Einteilung in Gruppen
• Ü-Serie 1 wahrscheinlich morgen (Dienstag):
ähnlich zu Serie 0 (kein neuer Stoff), aber mit Punkten.
• Prüfung: Klausur, keine Hilfsmittel
– Typeset by FoilTEX –
16
– Typeset by FoilTEX –
17
Literatur
Bewertung von Übungsserien
• autotool: bewertet individuell (ca. 1 Pflicht-A/Woche)
• Übungen: für jede der aktuellen Aufgaben A (ca. 4 Stück)
– Übungsleiter ruft einen Teilnehmer T auf, dieser rechnet
vor, die Leistung wird bewertet, alle anwesenden
Mitglieder der Gruppe G von T erhalten diesen Wert.
– T darf ersatzweise eine andere aktuelle Aufgabe A0
auswählen
– bei Abwesenheit von T darf G einen anderen Vertreter
T 0 ∈ G benennen.
– es wird Gleichverteilung über alle T angestrebt
• Übungsleiter kann von dieser Regelung im Einzelfall
abweichen.
– Typeset by FoilTEX –
• K. Weicker und N. Weicker: Algorithmen und
Datenstrukturen, Springer 2013, https:
//link.springer.com/book/10.1007/978-3-8348-2074-7
• T. Ottman und P. Widmayer: Algorithmen und
Datenstrukturen, Springer 2012, https:
//link.springer.com/book/10.1007/978-3-8274-2804-2
• T. H. Cormen, C. E. Leiserson, R. L. Rivest: Algorithms,
MIT Press 1991, https:
//mitpress.mit.edu/books/introduction-algorithms
• D. E. Knuth: The Art of Computer Programming, Vol. 3
(Sorting and Searching), Addison-Wesley, 1998,
http://www-cs-faculty.stanford.edu/˜uno/taocp.html
18
– Typeset by FoilTEX –
19
Alternative Quellen
Übung KW14
Ablauf der Übung
• – Q: Aber in Wikipedia/Stackoverflow steht, daß . . .
– A: Na und.
• Es mag eine in Einzelfällen nützliche Übung sein, sich mit
dem Halbwissen von Nichtfachleuten
auseinanderzusetzen.
Beachte aber https://xkcd.com/386/
• In VL und Übung verwenden und diskutieren wir die durch
Dozenten/Skript/Modulbeschreibung vorgegebenen
Quellen (Lehrbücher, referierte Original-Artikel,
Standards zu Sprachen und Bibliotheken)
• Diskussion der unten angegebenen Aufgaben 0.0 bis 0.3
• kurze Erläuterung des kooperativen Übungskonzeptes
und Einteilung (durch Übungsleiter) in Gruppen (je 3 bis 4
Personen)
• Bearbeitung der Aufgabe 0.4 (in den neu gebildeten
Gruppen) und Diskussion
• . . . gilt entsprechend für Ihre Bachelor- und Master-Arbeit.
– Typeset by FoilTEX –
20
– Typeset by FoilTEX –
21
Aufgabe 0.1 (Mengen)
Übungsserie 0 (Diskussion in KW14)
• Beweisen Sie mittels der angegebenen Axiome:
Aufgabe 0.0 (Leseübung)
contains(2,insert(1,insert(3,empty)))=False
• Wie begründen Ottman/Widmayer, daß es in der
Vorlesung AD nicht so sehr auf die exakte Formulierung
des Algorithmenbegriffs ankommt? In welcher anderen
Vorlesung wird das wichtiger und warum? (Quelle mit
Seiten- und Zeilennummer angeben.)
• Geben Sie ein passendes Axiom für die Vereinigung
union : M × M → M an. Verwenden Sie eine passende
aussagenlogische Verknüpfung.
• Der Wert von delete(e, m) soll die Menge m \ {e} sein.
Geben Sie den Typ von delete an.
Untersuche Sie (Beweis oder Gegenbeispiel):
– ∀e ∈ E, m ∈ M : delete(e, insert(e, m)) = m
– ∀e ∈ E, m ∈ M : insert(e, delete(e, m)) = m
– Typeset by FoilTEX –
22
– Typeset by FoilTEX –
23
Aufgabe 0.3 (kürzestes Wege)
Aufgabe 0.2 (Sortieren)
Wir betrachten den Graphen Gn auf der Knotenmenge
Vn = {0, 1, . . . , n}2 mit den Kanten
Für a = [3, 1, 4, 1, 5, 9]:
• geben Sie alle Permuationen π an, die die Spezifikation
(Variante 2) des Sortierens erfüllen.
• ((x, y), (x + 1, y)) vom Gewicht 4
• Führen Sie den Algorithmus Sortieren durch Auswahl mit
Eingabe a aus.
• ((x, y), (x, y + 1)) vom Gewicht 1
• ((x, y), (x + 1, y + 1)) vom Gewicht 2
(jeweils für alle x, y, für die das angegebene Paar
tatsächlich in Vn2 liegt)
• Zeichnen Sie G2.
• Geben Sie in G2 alle Wege von (0, 0) zu (1, 2) an. Geben
Sie zu jedem dieser Wege die Kosten an. Bestimmen Sie
– Typeset by FoilTEX –
24
– Typeset by FoilTEX –
Aufgabe 0.4 (Sortieren mit
compare-exchange)
l(1, 2), wobei l die Funktion aus der Spezifikation ist, und
v0 = (0, 0).
• Geben Sie weitere konkrete Funktionswerte von l an.
25
• Begründen Sie, daß folgendes Verfahren jede Eingabe
der Breite 4 sortiert. Jedes Paar (i, j) bedeutet cex(i, j).
• Beweisen Sie für i < j: Die Funktion l für Gi ist (als
Menge von geordneten Paaren) Teilmenge der
entsprechenden Funktion für Gj . (Zeichnen Sie G3)
[(1,2), (3,4), (2,3), (1,2), (3,4), (2,3)]
• Begründen Sie (jeweils durch ein Gegenbeispiel), daß
man keines dieser Paare weglassen kann.
• Begründen Sie l(k, 0) = 4k (in Gk und allen größeren)
• Geben Sie weitere allgemeine Aussagen über l an.
– Typeset by FoilTEX –
26
– Typeset by FoilTEX –
27
Aufgabe 0.5(A) (autotool)
Übungsserie 1 (Diskussion in KW15)
• Geben Sie ein compare-exchange-Sortierverfahren für 6
Elemente an mit weniger als 15 cex-Operationen.
Aufgabe 1.0 (Leseübung)
• (1 P) Wo und unter welchem Namen erscheint der
Algorithmus Sortieren durch Auswählen in
Weicker/Weicker? (Kapitel, Seitennummer)
• (2 P) Welche zwei Unterschiede gibt es zur Version hier
im Skript?
– Typeset by FoilTEX –
28
– Typeset by FoilTEX –
Aufgabe 1.1 (Mengen)
Aufgabe 1.2 (Sortieren mit
compare-exchange)
• (1 P) Beweisen Sie mittels der angegebenen Axiome:
contains(2,insert(1,insert(2,empty)))=True
• (1 P) Geben Sie ein passendes Axiom für die
Mengendifferenz difference : M × M → M an.
• (3 P) Begründen Sie, daß folgendes Verfahren jede
Eingabe der Breite 4 sortiert. Jedes Paar (i, j) bedeutet
cex(i, j).
[(2,3), (1,2), (3,4), (2,3), (1,2), (3,4)]
• (2 P) Wie läßt sich ein Test equals : M × M → B auf
Mengengleichheit implementieren, wenn nur die bis hier
in Skript und Aufgaben angegebenen Operationen des
abstrakten Datentyps Menge sowie alle
aussagenlogischen Verknüpfungen zur Verfügung
stehen?
– Typeset by FoilTEX –
29
• (1 P) Begründen Sie durch ein Gegenbeispiel, daß man
die erste Operation cex(2, 3) nicht weglassen kann.
30
– Typeset by FoilTEX –
31
Aufgabe 1.3 (kürzeste Wege)
das lG4 (v) > lG5 (v) ist.
Wir betrachten den Graphen Gn auf der Knotenmenge
Vn = {1, . . . , n}2 und der Kantenmenge
En = {((x1, x2), (y1, y2)) | (x1 − y1)2 + (x2 − y2)2 = 5}, die
alle Gewicht 1 haben.
• (1 P) Dieser Graph hat eine Beziehung zu einem
Brettspiel—welche?
• (1 P) Bestimmen Sie die Abstandsfunktion lG4 von
v0 = (1, 1) aus.
• (1 P) Erklären Sie das Muster der Vorkommen der
geraden und ungeraden Funktionswerte von l.
• (1 P) immer noch für v0 = (1, 1): Geben Sie ein v an, für
– Typeset by FoilTEX –
32
Komplexität von Algorithmen und
Problemem
• auf einer konkreten Maschine:
die konkrete (physikalische) Zeit
einer Ausführung des Programms für eine Eingabe
• Definition: worst-case-Zeitkomplexität eines Algorithmus
• Definition: Komplexität eines Problems,
Komplexitätsklassen
• Bestimmung der Komplexität von Algorithmen mit
Schleifen
• asymptotischer Vergleich von Funktionen
• (später) weitere Ressourcen (Platz, parallele Zeit)
• (später) average-case-Komplexität
• auf einer (konkreten oder) abstrakten Maschine:
die Anzahl der Rechenschritte für eine Eingabe
(beachte: Def. Algorithmus: schrittweise Ausführung)
• Beispiel: Profiling/Coverage-Analyse (für C-Programme)
– gprof zählt Unterprogramm-Aufrufe
– gcov zählt Ausführungen von Anweisungen (Zeilen)
Literatur: vgl. WW 2.3/2.4, OW S. 4/5
34
Coverage mit gcov
ist die Funktion
g++ -fprofile-arcs -ftest-coverage ex.cc -o ex
cP : N → N : s 7→ max{time(A, x) | size(x) ≤ s}
• ausführen: ./ex, erzeugt ex.gcda
• Report: gcov ex.cc, erzeugt: less ex.cc.gcov
in der ersten Spalte steht Anzahl der Ausführung:
cP (s) = größte Laufzeit auf allen Eingaben mit Größe ≤ s
• Bsp: prüfe, ob a[1 . . . n] schwach monoton steigt:
for (int i = 0; i<n; i++) {
int k = i;
for (int j = i+1; j<n; j++)
if (b[j]<b[k]) k = j;
swap(b[i],b[k]);
for nat i von 1 bis n-1
if a[i] > a[i+1] return False
return True
1 Vergleich für [8, 1, 7, 2], aber n − 1 Vgl. für [1, 2, . . . , n]
Vollständiger Quelltext: https://gitlab.imn.
htwk-leipzig.de/waldmann/ad-ss17
– Typeset by FoilTEX –
die Zeitkomplexität ist s 7→ (if s = 0 then 0 else s − 1)
36
Zeitkomplexität von Problemen
– Typeset by FoilTEX –
37
Komplexität von Programmen
• strukturiertes imperatives Programm ist Baum:
– Blätter: elementare Anweisung
– innere Knoten (zusammengesetzte Anweisungen):
Nacheinanderausführung, Verzweigung, Wiederholung
• für jede Funktion f : N → N:
TIME(f ) := die Menge der Probleme (Spezifikationen),
die sich durch einen Algorithmus mit Komplexität f
lösen (implementieren) lassen.
• Bsp (vorige Folie): Monotonie ∈ TIME(n 7→ n),
Bsp (vorige VL): Sortieren ∈ TIME(n 7→ n(n − 1)/2)
• für jede Menge von Funktionen F ⊆ N → N:
S
TIME(F ) = f ∈F TIME(f )
• Monotonie ∈ TIME(linear), Sortieren ∈ TIME(quadrat.)
• TIME(alle Polynome) (Abkürzung: P)
gilt als die Klasse der effizient lösbaren Probleme.
• in der VL Alg. und DS sind wir fast immer in P
– Typeset by FoilTEX –
35
• Definition: die Zeitkomplexität des Algorithmus A
• kompilieren mit Instrumentierung
8:
9:
10:
11:
12:
– Typeset by FoilTEX –
Zeitkomplexität von Algorithmen
https://gcc.gnu.org/onlinedocs/gcc/Gcov.html
5:
4:
10:
6:
4:
33
Was bedeutet Zeit?
Plan
– Typeset by FoilTEX –
– Typeset by FoilTEX –
• die Komplexität bestimmen wir durch:
– elementar: 1 Schritt
– zusammengesetzt:
∗ Nacheinanderausführung: Summe
∗ Verzweigung: 1 plus Maximum über die Zweige
∗ Wiederholung (Schleife): parametrische Summe,
abhängig von Schleifensteuerung (Laufbereich)
• später: Komplexität für (rekursive) Unterprogramme
38
– Typeset by FoilTEX –
39
Komplexität v. Progr. (Verzweigung)
Komplexität v. Progr. (Schleifen)
• Eingabe ist immer [a1, . . . , an]
• Eingabe: [a1, . . . , an], Ausgabe und Spezifikation egal
nat s := 0;
for i from 1 to n
if a[i] > 0 then s := s + 1
• for i from 1 to n { for j from 1 to n
P P
Kosten: ni=1 nj=1 1 = n2
• for i from 1 to n { for j from 1 to i
P P
Kosten: ni=1 ij=1 1 = . . .
• Kosten für die Verzweigung: 1 + 1 oder 1 + 0,
also wenigstens 1, höchstens 2
• Kosten für die Schleife:
P
P
wenigstens ni=1 1 = n, höchstens ni=1 2 = 2n
• Kosten für gesamtes Programm: bei jeder Eingabe
wenigstens 1 + n, höchstens 1 + 2n
• Es gibt für jedes n eine Eingabe mit Kosten 1 + 2n:
Komplexität ist 1 + 2n
• for i from 1 to n
for j from i+1 to n
for k from j+1 to n
e; }
e; }
e
geschlossene Darstellung?
Verallgemeinerung (mehr Schleifen dieser Art)?
– Typeset by FoilTEX –
40
Asymptotischer Vergleich von
Funktionen
– Typeset by FoilTEX –
41
Motivation: Abstraktion von. . .
• konkreten Kosten elementarer Operationen
s := s + 1 kostet 1 oder 2 oder 3? — egal!
Wiederholung
Funktion n 7→ 2n soll genauso gut sein wie n 7→ 3n.
unterschiedliche Komplexitätsfunktionen
und ihre Auswirkungen bei Änderung der Eingabegröße:
• Kosten durch unwesentliche Programmteile,
• wenn f (n) = log2 n, dann f (2n) = . . .
z.B. Initialisierungen, die bei kleinen Eingaben evtl. die
Gesamtkosten dominieren
• wenn f (n) = c · n, dann f (2n) = 2 · f (n)
n 7→ max(100, n) soll genauso gut sein wie n 7→ n
• wenn f (n) = n2, dann f (2n) = . . .
• Sprungstellen, z.B. n 7→ 2blog2 nc
• wenn f (n) = 2n, dann f (n + 1) = . . .
das ist nützlich, aber nicht alle Funktionen sind so einfach
– Typeset by FoilTEX –
42
– Typeset by FoilTEX –
Definition, Beispiele
43
Eigenschaften
• Def: O(g) := {f | ∃s ≥ 0, c ≥ 0 : ∀n ≥ s : f (n) ≤ c · (g(n))}
Funktion f wächst höchstens wie Funktion g
Bezeichnung aus der Analysis (das Landau-Symbol)
• ist reflexiv
• ist nicht symmetrisch (Gegenbeispiel?)
• betrachte: f1(n) = n, f2(n) = max(100, n), f3(n) = n /2.
2
• ist nicht antisymmetrisch (Gegenbeispiel?)
• f1 ∈ O(f2), Beweis: wähle s = 0, c = 1.
• ist transitiv
• f2 ∈ O(f1), Beweis: wähle . . .
• ist nicht total:
• f1 ∈ O(f3), Beweis: wähle s = 0, c = 2.
Für f1(n) = n, f5(n) = if 2 | n then n2 else 0
• f3 ∈
/ O(f1), Beweis (indirekt):
gilt f1 ∈
/ O(f2) und f2 ∈
/ O(f1).
falls s und c lt. Def., dann . . . Widerspruch
– Typeset by FoilTEX –
die Relation {(f, g) | f ∈ O(g)}:
44
Aber wenn es nur um Polynome geht. . .
– Typeset by FoilTEX –
45
Abgekürzte Notation für Funktionen
. . . wozu dann der Aufwand? Polynome erkennt man leicht!
Nein. Welche der folgenden Funktionen sind (beschränkt
durch) Polynome? Von welchem Grad?
• richtig: n 7→ n2 (historisch korrekt: λn.n2)
• n 7→ n2
• häufig wird Notation der gebundenen Variable vergessen:
n2 soll dann eine Funktion bezeichnen.
• n 7→ n2 + 10n − 100 log n
• Anwendung: n ∈ O(n2)
• n 7→ (log n)log n
P
• n 7→ nk=1blog kc
P
• n 7→ nk=1blog(n/k)c
• gefährlich wird das hier: ist x2y quadratisch oder linear?
unklar, ob x 7→ x2y gemeint ist oder y 7→ x2y oder. . .
• lustige work-arounds zur Vermeidung der richtigen
Notation: für ein festes y“ u.ä.
”
Solche Funktionen kommen als Kostenfunktionen von
Algorithmen vor und müssen richtig eingeordnet werden.
– Typeset by FoilTEX –
die gebundene Variable n wird explizit notiert.
46
– Typeset by FoilTEX –
47
Abgekürzte Notation f. Mengen v. Funktionen
• richtig: f ∈ O(g), denn O(g) ist eine Menge
• Satz: falls lim
• stattdessen häufig: f = O(g) . . . auch: n = O(n )
• Anwendungen
(für f1(n) = n, f2(n) = max(100, n), f3(n) = n2/2)
• wie bei allen Abkürzungen:
für Fachleute nützlich, aber der Anfänger wundert sich.
• limn→+∞ f1(n)/f2(n) = 1, limn→+∞ f2(n)/f1(n) = 1
• Anwendung: 3n + O(n2) = O(n2)
ist Gleichung zwischen Mengen von Funktionen
∀f ∈ O(n2) : (n 7→ 3n + f (n)) ∈ O(n2)
∧ ∀g ∈ O(n2) : ∃f ∈ O(n2) : ∀n : 3n + f (n) = h(n)
• limn→+∞ f1(n)/f3(n)?, limn→+∞ f3(n)/f1(n)?,
• Umkehrung diese Satzes gilt nicht!
Bsp: f4 = n 7→ 2blog2 nc, vergleiche mit f1.
48
Weitere Notationen
– Typeset by FoilTEX –
49
Asympt. Vergleich von Standardfunktionen
(wie immer: alle Funktionen aus N → N)
• Def: O(g) := {f | ∃s ≥ 0, c ≥ 0 : ∀n ≥ s : f (n) ≤ c · (g(n))}
f ∈ O(g) bedeutet: f wächst höchstens so wie g
• Def: Ω(g) := {f | g ∈ O(f )}.
f ∈ Ω(g) bedeutet: f wächst wenigstens so wie g
• Def: Θ(g) := O(g) ∩ Ω(g).
f ∈ Θ(g) bedeutet: f und g wachsen gleich schnell.
• Potenzen verschiedener (auch nicht-ganzer) Grade:
∀p, q ∈ R>0 : p < q ⇒ np ∈ o(nq )
• Logarithmus und Potenz
∀p, q ∈ R>0 : logp(n) ∈ o(nq )
√
Bsp: log10 n ∈ o( 3 n)
• Potenz und Exponential
∀p ∈ R>0, q ∈ R>1 : np ∈ o(q n)
• Produkte von Potenz und Logarithmus
np1 · logq1 n ∈ o(np2 · logq2 n) gdw. . . .
ω(g) := Ω(g) \ O(g).
• Satz: falls limn→+∞ f (n)/g(n) = 0, dann f ∈ o(g)
Beweis (indirekt): falls g ∈ O(f ), dann für . . .
– Typeset by FoilTEX –
= c ∈ R existiert, dann f1 ∈ O(f2).
• Beweis (Skizze): Definition, Einsetzen, Umformen
limn xn = c ⇐⇒ ∀ > 0 : ∃s : ∀n ≥ s : c − ≤ xn ≤ c + ,
• gefährlich, weil das Symbol =“
”
dann nicht mehr symmetrisch und transitiv ist:
n = O(n2) und n2 = O(n2), also folgt (optisch) n = n2
• Def: o(g) := O(g) \ Ω(g),
f1(n)
n→+∞ f2(n)
2
– Typeset by FoilTEX –
Eine Vergleichsmethode
alle Beweise mittels Limes-Kriterium
50
– Typeset by FoilTEX –
51
Anwendung
Spezielle Funktionen
Eine klassische Übungsaufgabe aus [CLR]:
• Logarithmus
• Ordne das asymptotische Wachstum von
– in der Informatik grundsätzlich zur Basis 2
– die Basis ist oft ganz egal: log10 ∈ Θ(log2).
• iterierter Logarithmus: log
(d.h., bestimme alle O-Relationen zwischen)
∗
√ log n
∗
(log n)log n 2log n
2
n2
n!
(log n)!
∗
log log n
log log n log n
n
n · 2n
log n
1
2
3
2n
1/ log n
(3/2)n
n
log
n
log(n!)
2
n
√
n+1
log∗(log n) 2 2 log n
n
n log n
2n
22
√
∗
log n
log n
2
exp(n) log(log n) 4
(n + 1)!
log n
– definiert durch n 7→ if n ≤ 1 then 0 else 1 + log∗blog nc
– sehr langsam wachsend
x
0 1 2 4 16 65536 265536
∗
log x 0 0 1 2 3
4
5
• Fakultät, Def: n! := 1 · 2 · . . . · n
– Satz: log(n!) = Θ(n log n)
– Beachte: es gilt nicht n! ∈ Θ(nn)
– Typeset by FoilTEX –
• insbesondere: welche Paare sind Θ-äquivalent?
52
– Typeset by FoilTEX –
53
• (2 P) Wie oft wird Anweisung e ausgeführt? Geben Sie
die Antwort als Funktion von n an.
Übungsserie 2 (für KW 16)
Aufgabe 2.1
for x = 1 to n
for y = 1 to n
if not (x = y)
for z = 1 to n
if not (x = z) && not (y = z)
e
• (1 P) Geben Sie die Folge der Belegungen von x, y, z an
für n = 2,
• (1 P) . . . , für n = 3.
– Typeset by FoilTEX –
54
– Typeset by FoilTEX –
55
Aufgabe 2.2
Die Binärdarstellungen aller Zahlen von 0 bis n werden
nebeneinandergeschrieben.
Als Darstellung der 0 benutzen wir dabei die leere
Ziffernfolge.
Die Gesamt-Anzahl der Vorkommen der 1 nennen wir B(n).
Beispiel: von 0 bis 3: [[], [1], [1, 0], [1, 1]], B(3) = 4.
• (1 P) Bestimmen Sie B(100) (z.B. durch ein Programm)
Darstellung von n wird.
Die Gesamt-Anzahl der dabei hinzugefügten 0 nennen wir
F (n).
Beispiel: [[0, 0], [0, 1], [1, 0], [1, 1]], F (3) = 3.
• (1 P) Bestimmen Sie F (100) (z.B. durch Modifikation des
vorigen Programms)
• (2 P) Geben Sie F (n) als Θ einer einfachen Funktion von
n an.
• (1 P) Geben Sie B(2w − 1) exakt an.
• (2 P) Begründen Sie B(n) ∈ Θ(n log n).
Die Binärdarstellungen von 0 bis n − 1 werden durch
führende Nullen ergänzt, so daß jede so lang wie die
– Typeset by FoilTEX –
56
– Typeset by FoilTEX –
57
Aufgabe 2.2 (Musterlösung einer Teilaufgabe)
• B(100) = 319
1
1
1
1
• experimentell kann Wertetabelle bestimmt werden:
w
0 1 2 3 4 5 6
7
8
B(2w − 1) 0 1 4 12 32 80 192 448 1024
• Zu zeigen ist B(n) ∈ Θ(n log n).
Beweis: alle Binärzahlen untereinanderschreiben
Bekannt sind
58
– ∀w > 0 : B(2w − 1) = w · 2w−1 (siehe oben)
– B ist streng monoton
(wenn x < y, dann B(x) < B(y), denn von x bis y sind
y − x Zahlen hinzugekommen und jede enthält
wenigstens ein 1-Bit)
Beweis:
– für jedes n gibt es w mit 2w − 1 ≤ n < 2w+1 − 1, nämlich
w = blog(n + 1)c.
Begründung: dann gilt w ≤ log(n + 1) < w + 1 nach Def.
von b·c,
also 2w ≤ n + 1 < 2w+1, daraus Behauptung.
– wegen Monotonie von B und bekannten Werten gilt
w · 2w−1 = B(2w − 1) ≤ B(n) < B(2w+1 − 1) = (w + 1) · 2w
– in der oberen Schranke schätzen wir w nach oben ab:
– Typeset by FoilTEX –
60
– Typeset by FoilTEX –
59
B(n) < (w + 1) · 2w+1 ≤ (log(n + 1) + 1) · 2log(n+1) =
(log(n + 1) + 1) · (n + 1)
Für n ≥ 1 setzen wir die Ungleichungskette fort
· · · ≤ (log(2n)+1)·2n = (log n+1+1)·2n = (log n+2)·2n
Für n ≥ 4 weiter: · · · ≤ (log n + log n) · 2n = 4n log n
Daraus folgt B ∈ O(n log n), denn wir haben gezeigt
∀n ≥ 4 : B(n) ≤ 4n log n.
– entsprechend für untere Schranke:
B(n) ≥ w · 2w−1 > (log(n + 1) − 1) · 2log(n+1)−2 >
(log n − 1) · 2log n−2 = (log n − 1) · n/4
Für n ≥ 4 ist log n ≥ 2 und log n − 1 ≥ log n − (log n/2),
also B(n) ≥ · · · ≥ (log n/2) · n/4 = (1/8)n log n
Daraus folgt n log n ∈ O(B), denn wir haben gezeigt
∀n ≥ 4 : n log n ≤ 8B(n).
– Typeset by FoilTEX –
61
Aufgabe 2.3
Diskussion:
aus B(2 − 1) = w · 2
mit n = 2 − 1 kann man (sollte
man zunächst) die Überschlagsrechnung durchführen:
w
1
0
1
0
1
0
1
das sind 2w Zeilen (die erste ist leer) mit je w Spalten und
in jeder Spalte ist die Hälfte der Einträge gleich 1.
daraus Vermutung: B(2w − 1) = w · 2w−1
– Typeset by FoilTEX –
1
1
0
0
1
1
w−1
w
n ≈ 2w , also w ≈ log n, also
B(n) ≈ log n · 2log n−1 = log n · n/2 ∈ Θ(n log n).
(4 P)
Welche O, Θ-Relationen gelten
zwischen
√
√ √n
f1(n) = n − n, f2(n) = n , f3(n) = n
Aber: das ist kein Beweis, man muß nachrechnen daß
der Fehler bei ≈ “ nicht wesentlich ist, und das geht am
”
sichersten durch exakten Nachweis der beiden
O-Beziehungen
– Typeset by FoilTEX –
62
– Typeset by FoilTEX –
63
Einfache Algorithmen auf Zahlen und
Feldern
Aufgabe 2.4
• (4 P) Für Funktionen f, g : N → N:
Beweisen Sie max(f, g) ∈ Θ(f + g).
Übersicht
Hierbei bezeichnen
• Euklidischer Algorithmus
max(f, g) die Funktion n 7→ max(f (n), g(n))
• Multiplizieren durch Verdoppeln
sowie f + g die Funktion n 7→ f (n) + g(n).
• Schleifen-Invarianten
• Schranken
• binäre Suche in geordnetem Feld
• dutch national flag
– Typeset by FoilTEX –
64
Eingabe: nat x, nat y; Ausgabe: gcd(x,y)
// x = X, y = Y (Bezeichung für Eingabe)
while true // I: gcd(x,y) = gcd(X,Y)
if x = 0 then return y
if y = 0 then return x
if x = y then return x
if x < y then y := y - x else x := x - y
• partielle Korrektheit: wg. Schleifen-Invariante I:
1. anfangs wahr, 2. invariant, 3. schließlich nützlich
• Termination: x+y ist Schranke: (bound, ranking function)
– Wertebereich ⊆ N
– Wert nimmt bei jedem Schleifendurchlauf ab
• Komplexität: linear in x + y, exponentiell in log x + log y
• Die Teilbarkeitsrelation auf N:
Def: a | c : ⇐⇒ ∃b ∈ N : a · b = c
• Bsp: 13 | 1001, 13 | 13, 13 | 0, ¬(0 | 13), 0 | 0
• Eigenschaften: Halbordnung, nicht total.
• der größte gemeinsame Teiler. Def: gcd(x, y) = g gdw.
g | x ∧ g | y und ∀h : h | x ∧ h | y ⇒ h | g
Beachte: hier kommt kein < “ vor!
”
• Eigenschaften:
gcd(0, y) = y, gcd(x, x) = x, gcd(x, y) = gcd(y, x)
gcd(x, y) = gcd(x, x − y)
66
• zu jeder Schleife gehören:
– Spezifikation
∗ die Invariante I (eine logische Formel)
∗ die Schranke S (ein Ausdruck mit Wert ∈ N)
– Programmtext while B do K ( B edingung, K örper)
I ist vor der Schleife wahr
I ist invariant unter K
I ist nach der Schleife nützlich
K verringert S oder macht B falsch
68
Algorithmus von Euklid (Variante 2)
• Multiplikation durch: Halbieren, Verdoppeln, Addieren
• Eingabe: nat a, nat b; Ausgabe: a * b
// A = a, B = b
p := ...
while a > 0 // I: a * b + p = A * B
// Schranke: log (a)
if odd a then p := ...
(a, b) = (div(a,2), ...)
return p
– Typeset by FoilTEX –
69
Laufzeit von Euklid (Variante 2)
• Folge der Belegungen (xs, ys), (xs−1, ys−1), . . . , (x1, 0).
• Plan: wiederholte Subtraktion ⇒ Division mit Rest
wobei ∀k : yk = xk−1 ∧ mod(xk , xk−1) = xk−2 und x0 = 0
• Def: mod(x, y) = z ⇐⇒ ∃f : x = f · y + z ∧ 0 ≤ z < y
• ∀s > k : xk > xk−1 (Rest ist kleiner als Divisor)
• Satz: y > 0 ⇒ gcd(x, y) = gcd(mod(x, y), y)
• ∀s > k : xk − xk−1 ≥ xk−2 (Quotient ist ≥ 1)
• Eingabe: nat x, nat y; Ausgabe: gcd(x,y)
// x = X, y = Y (Bezeichung für Eingabe)
while true // I: gcd(x,y) = gcd(X,Y)
if y = 0 then return x
(x,y) := (y, mod(x,y)) // simultan!
• daraus folgt ∀s > k ≥ 2 : xk ≥ xk−1 + xk−2
• damit xs−1 ≥ Fs−1 für Fibonacci-Zahlen
F0 = 0, F1 = 1, ∀k ≥ 0 : Fk+2 = Fk+1 + Fk
• aus Fk ∈ Θ(q k ) für q ≈ 1.6 (Details: nächste Folie)
• partiell korrekt wg. I (wie Variante 1)
folgt logq (xs−1) ≥ s (Schrittzahl ist O(log y))
• Schranke: x + y wie vorher — es gibt besser Schranke
– Typeset by FoilTEX –
67
• Anwendung in der Kryptographie (RSA):
Potenzieren (nach einem Modul) durch
Halbieren, Quadrieren, Multiplizieren
(David Gries: The Science of Programming, Springer,
1981; Kapitel 11)
– Typeset by FoilTEX –
– Typeset by FoilTEX –
Multiplizieren durch Verdoppeln
Entwurf und Analyse von Schleifen
•–
–
–
–
65
Algorithmus von Euklid (Variante 1)
Der größte gemeinsame Teiler (gcd)
– Typeset by FoilTEX –
– Typeset by FoilTEX –
70
– Typeset by FoilTEX –
71
Die Fibonacci-Zahlenfolge
Binäre Suche in geordnetem Feld
• Def: F0 = 0, F1 = 1, ∀k ≥ 0 : Fk+2 = Fk+1 + Fk
• Leonardo Pisano, ca. 1200, http://www-groups.dcs.
st-and.ac.uk/history/Biographies/Fibonacci.html
•
k 0 1 2 3 4 5 6 10
20
30
Fk 0 1 1 2 3 5 8 55 6765 832040
wächst exponentiell, Basis ist goldener Schnitt q ≈ 1.6
√
• Satz: mit q = ( 5 + 1)/2 gilt Fk = (q k − 1/(−q)k )/(q + q −1)
Beweis: Induktion, benutze q 2 = q + 1, q −2 = −q −1 + 1
• wegen limk→∞ 1/(−q)k = 0 folgt Fk ∈ Θ(q k )
– Typeset by FoilTEX –
72
Spezifikation:
Eingabe: a[1..n] schwach monoton steigend, x
Ausgabe: falls exists i: a[i] = x,
dann ein i mit a[i] = x, sonst NEIN
Implementierung (divide and conquer )
nat l := ... ; nat r := ...
while ... // Schranke: log (r - l)
// I: a[1 .. l-1] < x , x < a[r+1 .. n]
nat m = div (l+r,2)
if a[m] = x then return m
else if a[m] < x then ...
else ...
Laufzeit: Θ(log n).
– Typeset by FoilTEX –
Binäre Suche in geordnetem Feld (Var. 2)
Binäre Suche (Var. 2) in Java
Spezifikation (beachte: Grenzen sind l und r)
• Eingabe: a[l..r] schwach monoton steigend, x
• Ausgabe: falls ∃i : a[i] = x, dann solch ein i, sonst NEIN
Implementierung (mit Rekursion statt Schleife):
search (a [l .. r], x) =
if l > r then return NEIN
else nat m = div (l+r,2);
if a[m] = x then return m
else if a[m] < x then search(a[m+1 .. r],x)
else search(a[l .. m-1],x)
Korrektheit: x ∈ a[l . . . r] ⇐⇒ a nicht leer und
(x < a[m] ∧ x ∈ a[l . . . m − 1])
∨x = a[m] ∨ (x > a[m] ∧ x ∈ a[m + 1 . . . r])
boolean search (List<Integer> a, int x) {
if (a.isEmpty()) return false; else {
int m = (a.size() - 1) / 2;
if (a.get(m) == x) return true;
else if (a.get(m) < x)
return search(a.subList( 0,
m), x);
else
return search(a.subList(m+1,a.size()), x); }
• benutzt interface List<T> mit Methode
List<T> subList(int from, int to)
zur Konstruktion einer Teilfolge (slice) als Ansicht (view)
(d.h., ohne Daten zu kopieren)
• in Var. 1 (Schleife) ist diese Ansicht implizit repräsentiert
(durch l und r), das ist schlecht für den Leser
– Typeset by FoilTEX –
74
Bemerkung zum Programmierstil
75
E.W. Dijkstra: A Discipline of Programming (Kap. 14),
Prentice-Hall, 1976
• Eingabe: Folge a[1 . . . n] ∈ {Blau, Rot}∗
• Ausgabe: Folge b mit
– Multimenge von a = Multimenge von b
– b schwach monoton bzgl. B < R
• Sonst wird der (optische, mentale) Abstand zwischen
Spezifikation, Beweis und Implementierung zu groß . . .
• und deswegen (der Beweis schwierig und) die
Implementierung wahrscheinlich falsch.
• Wenn man die explizite Repräsentation nicht vernünftig
hinschreiben kann, hat man die falsche Sprache gewählt;
• wenn die Repräsentation nicht effizient ist, dann den
falschen Compiler.
– Typeset by FoilTEX –
– Typeset by FoilTEX –
Die Flagge färben (Vorbereitung: 2 Farben)
• Das, worüber man (in Spezifikation, in Beweis) spricht,
soll im Programmtext explizit repräsentiert sein.
Bsp. hier: Teilfolgen
76
Die Flagge färben (wirklich: 3 Farben)
Ansatz (b wird in a konstruiert)
while ( ... ) // Schranke: r - l
// I: a[1..l-1] = B, a[r+1..n] = R
if a[l] = B then ...
else if a[r] = R then ...
else { a[l] <-> a[r]; ... }
– Typeset by FoilTEX –
77
Hinweis zu Übungsaufgabe 3.3
• Eingabe: Folge a[1 . . . n] ∈ {Blau, Weiß, Rot}
∗
• Eingabe: Felder a[1..s], b[1..t] schwach monoton steigend.
Ausgabe: ein Paar (i, j) mit a[i] = b[j], falls das existiert.
• Ausgabe: Folge b mit
• Vorgehen: funktional (rekursiv) ⇒ iterativ (Schleife)
– Multimenge von a = Multimenge von b
– b schwach monoton bzgl. B < W < R
Ansatz:
l = ... ; m = ... ; r = ...
// I: a[1..l-1]=B, a[l..m-1]=W, a[r+1..n]=R
// Schranke?
while ...
if
a[m]=B { a[m] <-> a[...]; ... }
else if a[m]=R { a[m] <-> a[...]; ... }
else
{
... }
– Typeset by FoilTEX –
73
78
• verallgemeinere (Teilfolgen): Eingabe: a[p . . . s], b[q . . . t]
• Zerlegungen a = a[p] ∪ a[p + 1 . . . s], b = b[q] ∪ b[q + 1 . . . t]
a ∩ b = (a[p] ∪ a[p + 1 . . . s]) ∩ b
a[p] < b[q] ⇒ a[p] ∩ b = ∅, also a ∩ b = a[p + 1 . . . s] ∩ b
entspr. für a[p] > b[q]
• Variablen p, q in Schleife repräsentieren a[p . . . s], b[q . . . t]
Invariante: a[1 . . . s] ∩ b[1 . . . t] = a[p . . . s] ∩ b[q . . . t]
– Typeset by FoilTEX –
79
Aufgabe 3.2 (Euklid, Variante 3)
Übungsserie 3 (für KW 17)
Aufgabe 3.1 (Euklid, Variante 1)
• (1 P) Kann man Zeile if x = y ... weglassen?
• (1 P) Kann man Zeile if x = 0 ... weglassen?
• (1 P) Die beiden Anweisungen if x = 0 ...,
if y = 0 ... können aus der Schleife entfernt und vor
diese geschrieben werden. Warum? Geben Sie die
verschärfte Invariante an.
• (1 P) Interessant ist dabei immer nur die Termination,
denn partielle Korrektheit gilt in jedem Fall – warum?
– Typeset by FoilTEX –
Die GNU Multiprecision-Bibliothek (T. Granlund et al., FSF,
1991–2016)
https://gmplib.org/manual/Binary-GCD.html
enthält diesen gcd-Algorithmus, der (wie Variante 1, im
Gegensatz zu Variante 2) keine Divisionen benutzt
(Division durch 2 ist binär leicht realisierbar).
while ...
(a,b) := (abs(a-b), min(a,b)) // 1
if even(a) then a := div(a,2) // 2
if even(b) then b := div(b,2) // 3
Die Invariante soll auch hier sein: I : gcd(a, b) = gcd(A, B)
(der gcd der aktuellen a, b ist der gcd der Eingabe).
• (1 P) Begründen Sie, daß I invariant ist unter Anweisung
80
– Typeset by FoilTEX –
81
Aufgabe 3.3 (Suche in mehreren Feldern)
1, aber nicht invariant ist unter Anweisung 2 (ebenso 3)
Spezifikation:
Eingabe: Felder a[1..s], b[1..t], jedes ist schwach monoton
steigend.
Ausgabe: ein Paar (i, j) mit a[i] = b[j], falls das existiert,
sonst NEIN.
• (2 P) Deswegen wird Bedingung U : wenigstens einer
”
von a, b ist ungerade“ betrachtet.
Begründen Sie, daß I ∧ U invariant ist unter
Anweisungen 2 (ebenso 3).
• (1 P) Begründen Sie, daß I ∧ U invariant ist unter
Anweisung 1.
• (1 P) Beschreiben Sie das Verhalten dieses Algorithmus
für a = sehr groß, b = sehr klein, und vergleichen Sie mit
Euklid in Variante 1.
• (3 P) Geben Sie eine Implementierung mit einer Laufzeit
an, die durch eine lineare Funktion von s + t beschränkt
ist.
Benutzen Sie ein Programm mit einer Schleife. Geben
Sie deren Invariante und Schranke an.
• (2 P) Geben Sie
√ ein Verfahren an, das die Aufgabe in o(t)
löst, falls s = t. Benutzen Sie einen Algorithmus aus
– Typeset by FoilTEX –
82
– Typeset by FoilTEX –
83
Aufgabe 3.4 (Suche im Rechteck)
dem Skript.
Spezifikation:
Eingabe: ein Feld a[1..n, 1..n], eine Zahl x,
wobei jede Zeile und jede Spalte von a schwach monoton
steigen
Ausgabe: ein Paar (i, j) mit a[i, j] = x, falls das existiert,
sonst NEIN.
• (4 P) Geben Sie eine Implementierung mit einer Laufzeit
O(n) an.
Benutzen Sie ein Programm mit einer Schleife. Geben
Sie deren Invariante und Schranke an.
– Typeset by FoilTEX –
84
– Typeset by FoilTEX –
Sortieren in Feldern und Listen
85
Entscheidungsbäume
• jedes Sortierverfahren, das die Elemente der Eingabe
nur vergleicht (a[i] > a[j]) und vertauscht
– Beispiele sind: Sortieren durch Auswählen,
Compare-Exchange-Netzwerke
– Nicht-Beispiele: Arithmetik a[i] + a[j], Indizierung b[a[i]]
Übersicht
• untere Schranke für Sortieren durch Vergleichen [WW]
6.3
• Inversionen [WW] 1.3
• Shell-Sort [WW] 4.3, [OW] 2.1.3
• läßt sich für jede Eingabelänge n als Baum darstellen:
– innere Knoten sind Vergleiche a[i] > a[j],
haben 2 Kinder (Fortsetzung bei >, bei ≤)
– Blatt-Knoten sind Ausgaben (Permutationen)
• Rechnen mit Folgen (Listen)
• Jede der n! Permutationen kommt ≥ 1 mal vor
• Sortieren durch Einfügen [WW] 4.1.3, [OW] 2.1.2
• Merge-Sort [WW] 7.1, [OW] 2.4
– Typeset by FoilTEX –
• ⇒ Höhe des Baumes ist ≥ log2(n!)
86
– Typeset by FoilTEX –
87
Untere Schranke für Sortierverfahren
Höhe und Breite von Binärbäumen
• Def: Die Höhe h(t) eines Baumes t ist die Länge eines
längsten Pfades von der Wurzel zu einem Blatt.
• Für jedes vergleichsbasierte Sortierverfahren A gilt:
für jedes n gilt: es gibt eine Eingabe der Länge n,
für die A wenigstens dlog2(n!)e Vergleiche durchführt.
• Def: Die Länge eines Pfades = Anzahl der Kanten
(Schritte) auf dem Pfad
•
(die Anzahl der Knoten ist um eins größer)
n 1 2 3 4 5 6 7 8 9 10
dlog2(n!)e 0 1 3 5 7 10 13 16 19 22
• welche speziellen Verfahren (für diese n)
erreichen diese Schranke?
• Satz: Für jeden Binärbaum t gilt:
Die Anzahl der Blätter B(t) ist ≤ 2h(t).
• Die Komplexität des Sortierens ist Ω(n log n).
• Beweis durch Induktion. Anfang: h(t) = 0 : t ist Blatt.
• welche allgemeinen Sortiervefahren sind in O(n log n)?
Sortieren durch Auswählen nicht — ist in Θ(n2)
Schritt: h(t) > 0: t hat Kinder t1, t2 mit h(ti) ≤ h(t) − 1
B(t) = B(t1) + B(t2) ≤ 2 · 2h(t)−1 = 2h(t)
– Typeset by FoilTEX –
88
– Typeset by FoilTEX –
Nebenrechnung: Wachstum von log n!
Zählen von Inversionen
• Def: für eine Folge a[1 . . . n]: Menge der Inversionen ist
Inv(a) := {(i, j) | 1 ≤ i < j ≤ n ∧ a[i] > a[j]}
# Inv(a) : Anzahl der Inversionen von a
• Satz: log2 n! ∈ Θ(n log n)
• Beweis:
Q
P
– Umformung: log2 n! = log2 nk=1 k = nk=1 log2 k
– Abschätzung nach oben
(mit k ≤ n, Monotonie des log, Monotonie der Summe)
Pn
Pn
k=1 log2 k ≤
k=1 log2 n = n log2 n
deswegen log2 n! ∈ O(n log n)
– Abschätzung nach unten
Pn
Pn
k=1 log2 k ≥
k=dn/2e log2 k ≥ (n − 1)/2 · log2(n/2)
Für n ≥ 4 gilt: (n − 1)/2 ≥ (n − n/2)/2 = n/4
und log2(n/2) = log2 n − 1 ≥ (log2 n)/2
deswegen n log n ∈ O(log2 n!)
– Typeset by FoilTEX –
• Bsp: a = [4, 2, 5, 3, 1],
Inv(a) = {(1, 2), (1, 4), (1, 5), (2, 5), (3, 4), (3, 5)}
• für alle a der Länge n: 0 ≤ # Inv(a) ≤ n(n − 1)/2
• Satz: wenn (k, k + 1) ∈ Inv(a)
und b aus a durch a[k] ↔ a[k + 1] entsteht
dann # Inv(b) = # Inv(a) − 1.
• Bsp (forgesetzt von oben): k = 3, b = [4, 2, 3, 5, 1]
Inv(b) = {(1, 2), (1, 3), (1, 5), (2, 5), (4, 5)}
90
– Typeset by FoilTEX –
91
Inversionen und einfache Sortierverfahren
Zählen von Inversionen (Beweis)
Bijektion zwischen Inv(a) \ {(k, k + 1)} und Inv(b):
durch vollst. Fallunterscheidung für (i, j) ∈ Inv(a):
• Satz: Jedes Sortierverfahren, das nur benachbarte
Elemente vertauscht,
• (i, j) und (k, k + 1) sind disjunkt:
hat Komplexität Ω(n2).
falls {i, j} ∩ {k, k + 1} = ∅, dann (i, j) ∈ Inv(b).
• Beweis: jeder solche Tausch entfernt nur eine Inversion,
• (i, j) und (k, k + 1) stimmen an einer Stelle überein:
–
–
–
–
89
es gibt aber Eingaben mit n(n − 1)/2 Inversionen.
falls i < k = j, dann (i, j + 1) ∈ Inv(b)
falls i < k ∧ k + 1 = j, dann (i, j − 1) ∈ Inv(b)
falls i = k ∧ k + 1 < j, dann (i + 1, j) ∈ Inv(b)
falls i = k + 1 < j, dann (i − 1, j) ∈ Inv(b)
• Anwendung 1: (Satz) jedes Sortiernetz der Breite n, das
nur benachbarte Positionen vergleicht (und tauscht),
benötigt ≥ n(n − 1)/2 CEX-Bausteine.
• Anwendung 2: (Plan) Sortieren durch Auswählen
verbessern durch größere Abstände
• (i, j) und (k, k + 1) stimmen an beiden Stellen überein:
das ist genau Inversion, die entfernt wird
– Typeset by FoilTEX –
92
– Typeset by FoilTEX –
Inversionen und Laufzeit
93
Sortieren durch Einfügen
• Plan (Sortieren durch Einfügen):
• Sortieren durch Auswählen dauert immer |a| /2
2
for i from 2 to n // I: a[1..i-1] monoton
füge a[i] in a[1..i-1] ein
• wenn Inv(a) klein, dann ist a fast monoton,“
”
• dann sollte das Sortieren schneller gehen.
• Realisierung (durch Vertauschungen):
// I1: a ist Permutation der Eingabe
//
und a[1..i-1] ist monoton steigend
for i from 2 to n { nat j := i-1;
// I2: a[1..j] monoton und a[j+1..i] monoton
// und (0<j and j<i-1) => a[j] <= a[j+2]
while (j >= 1 and a[j] > a[j+1])
a[j] <-> a[j+1]; j := j-1; }
• Gibt es Sortierverfahren mit Komplexität in O(# Inv(a))?
• Nein, selbst wenn # Inv(a) = 0, muß man die gesamte
Eingabe lesen, um Monotonie festzustellen
• realistisches Ziel: Sortierverfahren in O(|a| + # Inv(a))
• Zeit: Θ(n + # Inv(a))
– Typeset by FoilTEX –
94
– Typeset by FoilTEX –
95
Shell-Sort: Vorbereitung
Shell-Sort: Vorbereitung—Beweis
• Bezeichnungen: k-geordnetes a , Resultat b := h-Sort(a)
• (Eigenschaft) a[1..n] heißt k-geordnet,
falls ∀i : a[i] ≤ a[i + k]
• Beweis: zu zeigen ist ∀i : b[i] ≤ b[i + k]
Bsp: a = [4, 2, 0, 6, 5, 1, 7, 8, 3] ist 3-geordnet.
• Fall 1: wenn h | k, dann b[i] ≤ b[i + h] ≤ · · · ≤ b[i + p · h].
• (Algorithmus) a wird k-sortiert:
• Fall 2: wenn nicht h | k,
für i von 1 bis k − 1: sortiere a[i, i + k, i + 2k, . . . ]
dann E = a[. . . , i − h, i, i + h, . . . ]
Bsp: 2-Sort von a ist [0, 1, 3, 2, 4, 6, 5, 8, 7]
• Satz: für h < k: wenn a k-geordnet ist und h-sortiert wird,
ist es danach immer noch k-geordnet.
und F = a[. . . , i + k − h, i + k, i + k + h, . . . ]
b[i + k] ist ≥ als (i + k)/h Elemente von F .
Davon sind i/h Stück ≥ als i/h Stück von E.
Die sind ≥ als die i/h kleinsten von E, d.h. ≥ b[i].
– Typeset by FoilTEX –
96
– Typeset by FoilTEX –
Shell-Sort: Idee
97
Shell-Sort: Hilfssatz 1
• Algorithmus: für eine geeignete Folge hl > . . . > h2 > h1:
für s von l bis 1: a wird hs-sortiert durch Einfügen
• Satz (trivial). h1 = 1 ⇒ Algorithmus ist korrekt.
• Komplexität: hängt von h ab. z.B. h = [1]: quadratisch
• Ziel bei der Konstruktion von h:
– hi groß ⇒ Teilfolgen kurz ⇒ schnell sortiert
– dabei genügend viele Inversionen entfernen
– so daß weitere Schritte (kleine hi) auch schnell
• D.L. Shell, CACM 2(7) 30–32, 1959.
ausführliche Analyse in [DEK] Band 3, Abschnitt 5.2.1
• Implementierung: https://gitlab.imn.htwk-leipzig.
• Lemma: Wenn gcd(h, k) = 1 und a ist h-geordnet und
k-geordnet,
– Typeset by FoilTEX –
– Typeset by FoilTEX –
dann für jedes d ≥ (h − 1) · (k − 1): a ist d-geordnet
• Beweis: ∃a, b ∈ N : d = ah + bk (Satz v. Sylvester, 1884)
• Beispiel: gcd(4, 7) = 1, größte nicht als a · 4 + b · 7
darstellbare Zahl ist . . . .
de/waldmann/ad-ss17/blob/master/kw17/shell.cc
98
Shell-Sort: Hilfssatz 2
Shell-Sort: eine geeignete Differenzenfolge
• Satz: Shell-Sort mit [. . . , 22 − 1, 21 − 1] dauert O(n3/2).
• Lemma: Für Shell-Sort mit Differenzenfolge
[. . . , hs+2, hs+1, hs, . . . ] mit gcd(hs+2, hs+1) = 1
• Vor hs-Sortieren gilt: Anzahl aller Inversionen in allen
hs-Teilfolgen ist ≤ n · 2s+3 (nach Lemma 2)
gilt nach hs+1-Sortieren: jede hs-Teilfolge hat
≤ (n/hs) · ((hs+2 − 1) · (hs+1 − 1)/hs) Inversionen
• Anzahl aller Inversionen in allen hs-Teilfolgen ist
≤ hs · (n/hs)2
• Beweis: das Resultat ist d-geordnet für
d ≥ (hs+2 − 1) · (hs+1 − 1).
(Anzahl der Folgen, max. Inversionszahl einer Folge)
Jede Teilfolge hat Länge ≤ n/hs
• das hs-Sortieren kostet ≤ min(hs(n/hs)2, n · 2s+3)
√
benutze linke Schranke für hs > n, dann rechte
und ist d-geordnet für d ≥ (hs+2 − 1) · (hs+1 − 1)/hs.
Von jeder Position jeder Teilfolge aus gibt es
< (hs+2 − 1) · (hs+1 − 1)/hs Inversionen.
– Typeset by FoilTEX –
≤ 2t +2t+1 +· · ·+2t+t/2 +2t+t/2 +· · ·+2t ∈ O(23t/2) = O(n3/2).
√
(vereinfachte Rechnung mit n = 2t, n = 2t/2, hs = 2s)
100
Rechnen mit Folgen (Listen)
– Typeset by FoilTEX –
101
Das Zusammenfügen von monotonen Folgen
• Spezifikation: merge : L × L → L
(a, b schwach monoton steigend und c = merge(a, b)) ⇒
– Multimenge(a) ∪ MM(b) = MM(c)
– und c ist schwach monoton steigend
• Bsp. merge([1, 2, 2, 3, 5], [0, 3]) = [0, 1, 2, 2, 3, 3, 5]
• Implementierung:
– merge(empty, b) = b; merge(a, empty) = a
– merge(cons(x, a0), cons(y, b0)) =
wenn x ≤ y, dann cons(x, merge(a0, cons(y, b0)))
sonst cons(y, merge(cons(x, a0), b0))
• Korrektheit: benutzt MM(cons(x, y)) = {x} ∪ MM(y)
• Komplexität (Anzahl der Vergleiche) ist ≤ |a| + |b| − 1
Das ist auch die Schranke für die Rekursion.
• abstrakter Datentyp Folge L mit Elementtyp E
mit Operationen
– Konstruktoren: empty : L, cons : E × L → L
– Accessoren (für nicht leere Folgen):
head : L → E, tail : L → L
– Test: null : L → B
mit Axiomen: ∀x ∈ E, y ∈ L:
– 1. head(cons(x, y)) = x, 2. tail(cons(x, y)) = y
– 3. null(empty), 4. ¬ null(cons(x, y))
• Implementierung (Mathematik): L = E ∗
• Impl. (Programmierung): Zeiger, typedef C * L
– leere Liste: nullptr
– nichtleer: struct C { E head; L tail; }
– Typeset by FoilTEX –
99
102
– Typeset by FoilTEX –
103
Merge: Korrektheit (1)
Wegen Assoziativität:
· · · = ({x} ∪ MM(a0)) ∪ MM(b) = MM(a) ∪ MM(b)
zu zeigen: MM(a) ∪ MM(b) = MM(merge(a, b))
Beweis durch Induktion nach |a| + |b|
• Falls . . . und x > y, dann symmetrisch.
• – falls null(a), dann merge(a, b) = b und
MM(a) ∪ MM(b) = ∅ ∪ MM(b) = MM(b).
– falls null(b), dann symmetrisch
• Falls a = cons(x, a0) und b = cons(y, b0) mit x ≤ y,
dann merge(a, b) = cons(x, merge(a0, b)) und
MM(merge(a, b)) = MM(cons(x, merge(a0, b))) =
{x} ∪ MM(merge(a0, b).
Wegen |a0| + |b| < |a| + |b| ist Induktionsvoraussetzung
anwendbar und es gilt · · · = {x} ∪ (MM(a0) ∪ MM(b))
– Typeset by FoilTEX –
104
Merge: Korrektheit (2)
– Typeset by FoilTEX –
105
Also ∀z ∈ MM(a0) ∪ MM(b) : x ≤ z.
Def: a ist monoton ⇐⇒ null(a) oder a = cons(x, a ) und
∀z ∈ MM(a0) : x ≤ z und a0 ist monoton.
Zu zeigen: wenn a monoton und b monoton, dann
merge(a, b) monoton.
Beweis durch Induktion nach |a| + |b|
0
Wg. Multimengen-Erhaltung ist
MM(merge(a0, b)) = MM(a0) ∪ MM(b)
und damit ∀z ∈ MM(merge(a0, b)) : x ≤ z
• Falls null(a), dann merge(a, b) = b, das ist nach
Voraussetzung monoton. Falls null(b), dann symmetrisch
Nach Induktion ist merge(a0, b) monoton und (eben
gezeigt) x ist ≤ jedem Element aus merge(a0, b).
Damit ist cons(x, merge(a0, b)) monoton.
• Falls . . . und x > y, dann symmetrisch.
• Falls a = cons(x, a0) und b = cons(y, b0) mit x ≤ y,
nach Def. Monotonie gilt ∀x0 ∈ MM(a0) : x ≤ x0 und
∀y 0 ∈ MM(b0) : y ≤ y 0
Wg. Transitivität gilt ∀y 0 ∈ MM(b0) : x ≤ y ≤ y 0
– Typeset by FoilTEX –
106
– Typeset by FoilTEX –
Sortieren durch Zusammenfügen (Merge-S.)
Merge-Sort: Korrektheit (1)
zu zeigen: MM(a) = MM(sort(a)).
Beweis durch Induktion nach |a|:
• sort(a) =
– wenn |a| ≤ 1, dann a
– sonst: merge(sort(l), sort(r)), wobei (l, r) = split(a)
• split(a[1 . . . n]) = (a[1 . . . h], a[h + 1 . . . n]) mit h = bn/2c
• Bsp: sort([4, 1, 3, 2]) = merge(sort[4, 1], sort[3, 2]) =
merge(merge(sort[4], sort[1]), merge(sort[3], sort[2])) =
merge(merge([4], [1]), merge([3], [2])) =
merge([1, 4], [2, 3]) = [1, 2, 3, 4]
• erfüllt die Spezifikation des Sortierens (Beweis?)
• funktioniert für beliebige Eingabelänge (nicht nur 2e)
• Komplexität (Anzahl der Vergleiche)?
für Beispiel: 5, allgemein: O(n log n) (noch zu zeigen)
– Typeset by FoilTEX –
107
• falls |a| ≤ 1, dann sort(a) = a und MM(sort(a)) = MM(a)
• falls |a| ≥ 2, dann
MM(a) = MM(l) ∪ MM(r). Es gilt |l| < |a| und |r| < |a|,
also lt. Induktion MM(sort(l)) = MM(l) und
MM(sort(r)) = MM(r)
nach Korrektheit von merge gilt
MM(sort(a)) = MM(merge(sort(l), sort(r))) =
MM(sort(l)) ∪ MM(sort(r)) = MM(l) ∪ MM(r) = MM(a)
108
– Typeset by FoilTEX –
Merge-Sort: Korrektheit (2)
109
Komplexität von Merge-Sort
zu zeigen: sort(a) ist monoton.
Beweis durch Induktion nach |a|:
• Bezeichnungen
– S(n) = Kosten für sort auf Eingabe der Länge n
– M (p, q) = p + q − 1 Kosten für merge von Längen p, q
• falls |a| ≤ 1, dann sort(a) = a und a ist monoton.
• Berechnung: S(n) =
– wenn n ≤ 1, dann 0,
– sonst S(bn/2c) + S(dn/2e) + M (bn/2c, dn/2e)
• falls |a| ≥ 2, dann
Es gilt |l| < |a| und |r| < |a|, nach Induktion sind sort(l)
und sort(r) monoton.
Also ist Voraussetzung für Aufruf von
merge(sort(l), sort(r)) erfüllt.
• Bsp: S(2) = S(1) + S(1) + M (1, 1) = 0 + 0 + 1 = 1,
S(3) = S(1) + S(2) + M (1, 2) = 0 + 1 + 2 = 3,
S(4) = S(2) + S(2) + M (2, 2) = 1 + 1 + 3 = 5, . . .
Nach Spezifikation von merge ist dann das Resultat
monoton.
• Werteverlauf:
– Typeset by FoilTEX –
n 0 1 2 3 4 5 6 7 8 9 10
S(n) 0 0 1 3 5
25
vergleiche mit unterer Schranke für Sortieren!
110
– Typeset by FoilTEX –
111
Asymptotische Komplexität von Merge-Sort
• S(n) = if n < 2 then 0 else S(bn/2c) + S(dn/2e) + n − 1
• speziell: S(2k ) = if k < 1 then 0 else 2 · S(2k−1) + 2k − 1
•
Aufgaben 4.A (autotool)
• Sortierverfahren für 5 Elemente mit höchstens 8
Vergleichen.
0 1 2 3 4 5
6
k
S(2k ) 0 1 5 17
321
• Eigenschaften von Permutationen (k-Ordnung,
Inversionszahl), Beispiel:
• Vermutung: S(2 ) = . . . , Beweis durch Induktion nach k
k
Gesucht ist eine Permutation von [1 .. 9]
mit den Eigenschaften:
And [ Inversions EQ 7
, Ordered 6
, Ordered 4
]
• für beliebiges n: mit k = blog nc gilt 2k ≤ n < 2k+1,
benutze spezielle Werte und Monotonie von S
• Satz: S ∈ Θ(n log n), d.h.: Merge-Sort ist ein
asymptotisch optimales Sortierverfahren
– Typeset by FoilTEX –
Übungsserie 4 (für KW 18)
112
– Typeset by FoilTEX –
Aufgabe 4.1 (Permutationen)
113
Aufgabe 4.2 (Shell-Sort)
Bestimmen Sie die Anzahl A(n) der Permutationen von
[1 . . . n], die sowohl 2-geordnet als auch 3-geordnet sind.
Für Eingabe [10, 9, . . . , 2, 1] (o.ä. — wird dann vom
Übungsleiter vorgegeben):
• Zusatz: (1 P) Diese Aufgabe erscheint in einem der im
Skript zitierten Bücher. Geben Sie die exakte Fundstelle
an.
• (2 P) Shell-Sort mit Differenzenfolge [3, 2, 1] (o.ä.) an der
Tafel vorrechnen.
• (1 P) Geben Sie alle solche Permutationen für n = 4 an.
• (1 P) Dabei Ordnung und Anzahl der Inversionen mit
Schranken aus Hilfssatz 1 und 2 aus Skript vergleichen.
• (1 P) Jede solche Permutation ist auch 5-geordnet,
warum?
Bestimmen Sie experimentell Zahlen c, d, so daß Shell-Sort
mit Differenzenfolge [c, d, 1] möglichs wenig
Element-Vergleiche ausführt.
• (2 P) Beweisen Sie A(n) = Fn+1 (Fibonnaci-Folge).
• (2 P) auf Eingabe [100, . . . , 2, 1]
• (Zusatz) auf 100 zufälligen Eingaben der Länge 100
– Typeset by FoilTEX –
114
Hinweis: Bei der Bearbeitung der Aufgaben könnte diese
Implementierung von Shell-Sort nützlich sein:
https://gitlab.imn.htwk-leipzig.de/
waldmann/ad-ss17/blob/master/kw17/shell.cc.
Bei der Präsentation im Seminar rechnen Sie an der Tafel
ohne maschinelle Hilfe.
– Typeset by FoilTEX –
116
j + 1, falls diese in [1 . . . n] liegen).
Nachdem der Student eine Weile überlegt hat, erhebt er
sich vom Schreibtisch, . . . (siehe oben).
Untersuchen Sie für jedes n ≥ 1:
– Typeset by FoilTEX –
115
Zusatz-Aufgabe 4.3 (Der Osterhase)
(Wird diskutiert, sobald eine Gruppe eine Lösung anmeldet
und sofern in der Übung Zeit ist. Das und evtl. Vergabe von
Zusatzpunkten liegt im Ermessen der Übungsleiter.)
Der listige Osterhase hat ein buntes Osterei versteckt,
hinter einem der Grasbüschel 1, 2, . . . , n.
Der fleißige Student sucht das Ei.
Er erhebt sich vom Schreibtisch, geht zu Grasbüschel i und
sieht nach. Ist das Ei dort, hat er gewonnen.
Ist das Ei nicht dort, geht er zum Schreibtisch zurück, um
weitere Übungsaufgaben zu bearbeiten.
Hinter seinem Rücken nimmt der Osterhase das Ei von der
Stelle j (diese war ungleich i) und versteckt es in einer der
maximal zwei direkt benachbarten Positionen (j − 1 oder
– Typeset by FoilTEX –
117
Übungsserie 5 (für KW 19)
Aufgabe 5.A (autotool)
Merge von a und b mit |a| = 2 und |b| = 4 (oder ähnlich) mit
wenig Vergleichen.
• Kann der Student das Ei finden?
• Wenn ja, wie lange dauert das?
Beispiel: n = 3. Schritt 1: teste Position 2. Falls das Ei nicht
dort ist, dann ist es in 1 oder 3. Im nächsten Schritt muß es
der Hase nach 2 legen, weil das die einzige
Nachbarposition von 1 und von 3 ist. Deswegen ist Schritt
2: teste Position 2 sicher erfolgreich.
– Typeset by FoilTEX –
118
– Typeset by FoilTEX –
119
Aufgabe 5.1 (Merge-Sort)
ist das eine Verbesserung?
Für Eingabe [10, 9, . . . , 2, 1] (o.ä. — wird dann vom
Übungsleiter vorgegeben):
• (2 P) Merge-Sort an der Tafel vorrechnen.
• (1 P) Dabei die Vergleichs-Operationen aller Teilschritte
zählen und mit Schranken aus Vorlesung vergleichen.
Such-Aufgabe: zur Implementierung von sort in der
Haskell-Standardbibliothek Data.List
• (1 P) Wo ist der zugrundeliegende Algorithmus
beschrieben (welches ist die älteste zitierte Quelle)?
• Zusatz (1 P) Welche Änderung gegenüber Merge-Sort
enthält dieser Algorithmus, und für welche Eingabefolgen
– Typeset by FoilTEX –
120
Aufgabe 5.2 (Entscheidungsbäume, Merge)
– Typeset by FoilTEX –
121
von merge erreicht?
Benutzen Sie Entscheidungsbäume, um eine untere
Schranke für die Anzahl der notwendigen Vergleiche bei
merge(a, b) als Funktion von |a| und |b| zu erhalten.
Die Blätter des Entscheidungsbaumes sind Permutationen
von a · b, welche die relative Reihenfolge der Element aus a
sowie der Elemente aus b beibehalten.
Beispiel: eine solche Permutation von [a1, a2] · [b1, b2, b3] ist
[b1, a1, b2, b3, a2].
• (1 P) Geben Sie alle Permutationen von [a1, a2, b1, b2, b3]
mit dieser Eigenschaft an.
• (1 P) Bestimmen Sie die minimale Anzahl der Blätter
sowie die daraus resultierende Schranke allgemein als
Funktion von |a| und |b|.
Hinweis: verwenden Sie eine aus der Kombinatorik
bekannte Funktion/Notation.
• (1 P) Begründen Sie: unsere Implementierung von merge
ist nicht optimal für |a| = 1.
• (1 P) Geben Sie für |a| = 1 eine optimale
Implementierung an. Benutzen Sie einen Algorithmus
aus der Vorlesung (leicht modifiziert).
• (1 P) Welche untere Schranke folgt daraus für M (2, 3)?
Wird diese von der in VL angegebenen Implementierung
– Typeset by FoilTEX –
122
– Typeset by FoilTEX –
Analyse rekursiver Algorithmen
Definition, Motivation
• Wortbedeutung Rekursion: zurück (re) laufen (cursor)
Übersicht
• inhaltliche Bedeutung: ein rekursiver Algorithmus
löst ein Problem mit Eingabe E durch:
1. E in (kein, ein oder mehrere) E1, . . . zerlegen
– kein: ergibt Ende der Rekursion
– ein: lineare Rekursion
– mehrere: Baum-Rekursion
2. jedes Ei durch denselben Algorithmus lösen (ergibt Ai)
3. aus A1, . . . die Lösung A von E bestimmen
[WW] Kapitel 7
• Multiplizieren durch Verdoppeln
• Karatsuba-Multiplikation [OW] 1.2.3
• Master-Theorem [WW] 7.2
• Quick-Sort, Laufzeit im Mittel [WW] 7.3
• Median-Bestimmung in Linearzeit [WW] 7.4
– Typeset by FoilTEX –
• Vorteil der Rekursion: man muß nur über 1. (teilen) und
3. (zusammensetzen) nachdenken, denn 2. ist nach
Induktion richtig
124
– Typeset by FoilTEX –
125
Multiplizieren durch Verdoppeln
Termination und Komplexität rekursiver
Algorithmen
(vgl. früher angegebener iterativer Algorithmus)
mult(nat a, nat b) = if a = 0 then 0
else mod(a,2) * b + 2 * mult(div(a,2),b)
• Termination: folgt aus Existenz einer Schranke S,
die bei jedem rekursiven Aufruf abnimmt:
wenn E −→ Ei, dann S(E) > S(Ei) ≥ 0
• offensichtlich partiell korrekt nach Def. von mod, div
• terminiert, weil a eine Schranke ist
(falls a > 0, dann a > a/2 ≥ ba/2c = div(a, 2))
• lineare Rekursion: Laufzeit ≤ Schranke
• Baum-Rekursion: Laufzeit mglw. größer als Schranke
a(n) = if n>0 then a(n-1) + a(n-1) else 1
Schranke ist n (linear), Laufzeit ist 2n (exponentiell)
• mod(a,2) * b realisiert durch Fallunterscheidung
• Laufzeit (Anzahl der Additionen)
implizit: M (a) = if a = 0 then 0 else 1 + M (ba/2c)
explizit: M (a) = if a = 0 then 0 else 1 + blog2 ac
Beweis: benutzt a ≥ 2 ⇒ blog2 ac = 1 + blog2ba/2cc
• Laufzeit implizit (Bsp. S(n) = 2 · S(n/2) + n − 1)
explizite Form (Bsp. S ∈ Θ(n log n)) nach Rechnung
– Typeset by FoilTEX –
123
126
– Typeset by FoilTEX –
127
Multiplikation von Binärzahlen
Multiplikation von Binärzahlen
mit bisher bekanntem Verfahren:
• a = 2w a1 + a0, b = 2w b1 + b0
• mult(a,b) kostet log a Additionen.
• a·b = (2w a1 +a0)(2w b1 +b0) = 22w a1b1 +2w (a1b0 +a0b1)+a0b0
eine Multiplikation für Bitbreite 2w
⇒ vier Mult. für Breite w und 3 Additionen für Breite 2w
• jede dieser Additionen kostet ≥ log b Bit-Operationen
• Multiplikation kostet log a · log b Bit-Operation.
• Kosten: M (1) = 1, M (2w) = 4M (w) + 6w
8
16
32
w 1 2 4
Daten:
M (w) 1 16 88 400 1696 28288
Vermutung: M (2k ) = 7 · 4k − 6 · 2k , Beweis: Induktion.
geht das schneller? Überraschenderweise: ja!
• Ansatz: w = d(log max(a, b))/2e (Hälfte der Bitbreite)
a = 2w a1 + a0, b = 2w b1 + b0 mit 0 ≤ a0 < 2w , 0 ≤ b0 < 2w
• also M (w) = 7w2 − 6w für w = 2k
• Bsp. a = 13, b = 11, w = 2, a = 22 · 3 + 1, b = 22 · 2 + 3
• also M ∈ Θ(w2), also keine Verbesserung
• Bestimme a· aus Teilprodukten der a1, a0, b1, b0
– Typeset by FoilTEX –
128
• a · b = (2w a1 + a0)(2w b1 + b0)
benutze Nebenrechnung p = (a1 + a0) · (b1 + b0)
a · b = 22w a1b1 + 2w (p − (a1b1 + a0b0)) + a0b0
• eine Multiplikation für Bitbreite 2w
⇒ drei Mult. für Breite w und 6 Additionen für Breite ≤ 2w
• Kosten M 0(1) = 1, M 0(2w) = 3M 0(w) + 12w
w 1 2
4
8
16
32
2k
0
k
M (w) 1 27 129 483 1641 16689 25 · 3 − 24 · 2k
• M 0(w) = 25(wlog2 3)−24w ∈ Θ(wlog2 3) = Θ(w1.58...) ⊆ o(w2)
• A. Karatsuba, J. Ofman: Multiplication of Many-Digital
Numbers by Automatic Computers, Doklady Akad. Nauk
SSSR 145, 293-294, 1962.
130
Begründung des Hauptsatzes (1)
e
x
f (n) = Θ(nlogb a) + ae ·
= Θ(nx) + nx ·
e
X
k=0
e
X
g(bk )/ak
k=0
Begründung des Hauptsatzes (3)
– Typeset by FoilTEX –
133
Begründung des Hauptsatzes (4)
• für n = b , also e = logb n. Dann a = n mit x = logb a.
P
• f (n) = Θ(nx) + nx · ek=0 g(bk )/ak
• für n = be, also e = logb n. Dann ae = nx mit x = logb a.
P
• f (n) = Θ(nx) + nx · ek=0 g(bk )/ak
x
• Falls g ∈ Θ(n 7→ nx), dann c1 · bkx ≤ g(bk ) ≤ c2 · bkx,
P
P
• dann nx · ek=0 g(bk )/ak ∈ Θ(nx · ek=0(bx/a)k )
P
= Θ(nx · ek=0 1) = Θ(nx · e) = Θ(nx log n)
• Falls ∃y > x : g ∈ Θ(ny ), dann c1 · bky ≤ g(bk ) ≤ c2 · bky ,
P
P
• dann nx · ek=0 g(bk )/ak ∈ Θ(nx · ek=0(by /a)k )
Summe ist geom. Reihe zur Basis q = by /a > 1
q e+1 − 1
) = Θ(nx(by /a)e) = Θ(nx · bye/ae)
q−1
= Θ(bey ) = Θ(g(n))
• also f (n) ∈ Θ(nx) + Θ(nx log n) = Θ(nx log n)
– Typeset by FoilTEX –
131
• also · · · ≤ Θ(nx) + c0 · nx · S = Θ(nx) + Θ(nx).
132
e
– Typeset by FoilTEX –
• die Summe ist geometrische Reihe zur Basis by /a < 1,
P
P
1
y
k
=S
also ek=0(by /a)k < ∞
k=0(b /a) =
1 − by /a
drei Fälle: A) nx am größten, B) Summanden für alle k
ähnlich groß. C) Summand für k = 0 am größten.
e
• Anwenden für beide Varianten der Binärmultiplikation
• Falls g ∈ O(n 7→ ny ) mit y < x, dann g(bk ) ≤ c0 · bky ,
P
• also · · · ≤ Θ(nx) + c0 · nx · ek=0(by /a)k
a−k · g(bk )
– Typeset by FoilTEX –
• Herleitung und Aussage:
– bestimme x aus Ansatz f (n) = nx (ignoriere g)
nx = a · (n/b)x ⇒ x = . . .
– vergleiche g mit nx, der größere bestimmt das Resultat
∗ polynomiell kleiner: ∃y < x : g ∈ O(ny ) ⇒ f ∈ Θ(nx)
∗ gleich: g ∈ Θ(nx) ⇒ f ∈ Θ(nx log n)
∗ poly. größer: ∃y > x : g ∈ Θ(ny ) ⇒ f ∈ Θ(g)
(Version mit g ∈ Ω(ny ) siehe [CLR])
• für n = be, also e = logb n. Dann ae = nx mit x = logb a.
P
• f (n) = Θ(nx) + nx · ek=0 g(bk )/ak
f (be) = a · f (be−1) + g(be)
= a(a · f (be−2) + g(be−1)) + g(be)
e
X
= ae · f (b0) +
ae−k · g(bk )
k=0
• beschreibt asymptotisches Wachstum der Lösung f von
f (n) = if n < s then c else a · f (n/b) + g(n)
für a ≥ 1, b > 1, und n/b kann bn/bc oder dn/be sein
Begründung des Hauptsatzes (2)
für n = b , also e = logb n. Dann a = n mit x = logb a.
e
129
Hauptsatz über Rekursionsgleichungen
Multiplikation von Binärzahlen
– Typeset by FoilTEX –
– Typeset by FoilTEX –
• · · · = Θ(nx ·
134
– Typeset by FoilTEX –
135
Anwendungen des Hauptsatzes
Quicksort (Algorithmus)
Spezifikation: Ordnet a[1 . . . n] schwach monoton steigend
Q(a[1 . . . n]): wenn n ≤ 1, dann fertig, sonst
p = a[n] (das Pivot-Element)
tausche Elemente in a[1 . . . n − 1], bestimme k ∈ [1 . . . n],
so daß ∀1 ≤ i < k : a[i] < p und ∀k ≤ i < n : p ≤ a[i]
vgl. dutch national flag (mit 2 Farben)
a[k] ↔ a[n] ; Q(a[1 . . . k − 1]) ; Q(a[k + 1 . . . n])
• Mult. durch Verdoppeln: f (n) = f (n/2) + 1
Hauptsatz mit a = 1, b = 2, also x = log2 1 = 0; nx = 1
Fall 2: g ∈ Θ(nx), also f ∈ Θ(nx log n) = Θ(log n)
• Mult. von Binärzahlen: f (n) = 4f (n/2) + 3n
Hauptsatz mit a = 4, b = 2, also x = log2 4 = 2; nx = n2
Fall 1: g ∈ O(ny ) mit y = 1 < x, also f ∈ Θ(nx)
• Karatsuba-Mult. f (n) = 3f (n/2) + 6n
Hauptsatz mit a = 3, b = 2, also x = log2 3 ≈ 1.58,
Fall 1: g ∈ O(ny ) mit y = 1 < x, also f ∈ Θ(nx)
• f (n) = 2f (n/2) + n log n, a = 2, b = 2, x = log2 2 = 1,
HS nicht anwendbar : g ∈
/ O(n1−), g ∈
/ Θ(n), g ∈
/ Θ(n1+)
2
Lösung (mit anderen Methoden): f ∈ Θ(n log n)
– Typeset by FoilTEX –
• Korrektheit:
– Multimengen-Erhaltung, weil nur getauscht wird
– Ordnung: vor den beiden Q-Aufrufen gilt:
∀1 ≤ i < k : a[i] ≤ a[k] und ∀k < i ≤ n : a[k] ≤ a[i]
• Termination: |a| ist Schranke (aber Laufzeit ∈
/ O(|a|))
• C.A.R. Hoare, Computer Journal 5 (1962), 10–15
136
Quicksort (Laufzeit)
• Element-Vergleiche nur beim Partitionieren.
Eingabe-Elemente x, y werden genau dann verglichen,
wenn x oder y das Pivot ist und beide nicht bereits durch
eine vorigen Pivot getrennt wurden.
Q(n) = Q(k − 1) + Q(n − k) + n − 1
• Komplexität (d.h. maximale Laufzeit über alle Eingaben
jeder Länge) ist quadratisch,
• falls Eingabe eine zufällige Permutation von [1 . . . n],
betrachte Elemente (nicht Indizes) x < y
und das erste Pivot p mit x ≤ p ≤ y.
betrachte geordnete Eingabe [1, 2, . . . , n], dann k = n
Q(n) = Q(n − 1) + Q(0) + n − 1 = Q(n − 1) + n − 1
• falls p ∈ {x, y}, dann wird x mit y verglichen, sonst nicht.
die Wahrscheinlichkeit dafür ist 2/(y − x + 1).
• Laufzeit bei ungeordneten“ Eingaben ist besser
”
⇒ mittlere Laufzeit (über alle Eingaben) ist besser
• besser Wahl des Pivot-Elements ist möglich
138
• die erwartete Vergleichszahl (= Laufzeit) ist
P
Q(n) = 1≤x<y≤n 2/(y − x + 1).
– Typeset by FoilTEX –
Quicksort (mittle Laufzeit – Rechnung)
• Q(n) =
P
1≤x<y≤n 2/(y
• unser Pivot: a[n], schlecht für geordnete Eingabe
− x + 1)
• ist a[div(n, 2)] besser?
für geordnete Eingabe ideal
aber auch für diese Wahl gibt es schlechte Eingaben (Ü)
• Unter- und Obersumme des Integrals:
R n+1
Rn
P
1
(1/x)dx ≤ n−1
k=1 k+1 ≤ 1 (1/x)dx
2
Pn−1 1
loge(n + 1) − loge 2 ≤ k=1 k+1 ≤ loge n
• zufällige Wahl des Pivot-Index ist besser
• Implementierung in openjdk-1.8.0: Dual-Pivot Quicksort,
Vladimir Yaroslavskiy, Jon Bentley, and Joshua Bloch.
• Folgerung: Q ∈ Θ(n log n)
Auf zufälligen Eingaben ist Quicksort asymptotisch
optimal.
– zwei Pivots ⇒ drei Teilfolgen
– Pivots berechnet aus mehreren Kandidaten
140
Median-Bestimmung
– Typeset by FoilTEX –
141
Median ohne Sortieren (ein Spezialfall)
• Def: Ein Element m einer Folge a[1 . . . n] heißt Median:
#{i | a[i] < m} ≤ n/2 und #{i | a[i] > m} ≤ n/2
(etwas umständlich wg. Möglichkeit von Duplikaten in a)
• Bsp: median([3, 0, 1, 20, 2]) = 2 (vgl. mit Mittelwert)
• Median von [a1, . . . , a5] mit 6 Vergleichen?
d.h. ohne zu sortieren, denn dlog2(5!)e = 7
• Implementierung (replacement selection)
– ein KO-Turnier für [a1, . . . , a4] (3 Spiele = Vergleiche)
– der Sieger as ist nicht der Median (sondern zu groß)
– setze a5 dort ein, wo as begonnen hat,
a5 wiederholt die 2 Spiele von as
– der Sieger at ist nicht der Median (sondern zu groß)
– noch ein Spiel zwischen denen, die gegen at verloren
haben, der Sieger ist der Median
• Motivation: Median ist der ideale Pivot für Quicksort.
kann man den Median effizient bestimmen?
• ein naheliegendes, Verfahren ist: sort(a[1 . . . n])[dn/2e]
das kann man aber in Quicksort nicht benutzen
• überraschenderweise:
Median kann in Linearzeit bestimmt werden.
– Typeset by FoilTEX –
139
Quicksort (Verbesserungen)
n 1 2 3 4 5
6
7
8
29
37
103
472
• Q(n) 0 1
3
6
5
10
35
0 1 2.7 4.8 7.4 10.3 13.5
P
Pn−1 1
n−k
• Q(n) = 2 n−1
k=1 k+1 = 2(n + 1)
k=1 k+1 − 2(n − 1)
– Typeset by FoilTEX –
137
Quicksort (mittle Laufzeit — Herleitung)
• Kosten für |a| = n ≥ 2 abhängig von k:
– Typeset by FoilTEX –
– Typeset by FoilTEX –
(A. Hadian und M. Sobel, 1969, zitiert in [DEK] 5.3.3.)
142
– Typeset by FoilTEX –
143
Median und Selektion (Plan)
Selektion in Linearzeit (Realisierung)
• Spezif.: select(k, a) := ein k-kleinstes Element
• gestattet Implementierung median(a) := select(d|a|/2e, a)
• Implementierung von select(k, a[1 . . . n]) für n groß:
– m := ein Wert in der Nähe des Medians von a
– L := {a[i] | a[i] < m}; E = {· · · = m}; R := {· · · > m}
– falls k ≤ |L|, dann select(k, L)
– falls |L| < k ≤ |L| + |E|, dann m
– falls |L| + |E| < k, dann select(k − (|L| + |E|), R)
• Lemma: für |a| = n gilt |L| ≥ 3n/10, |R| ≥ 3n/10.
Beweis: zähle Elemente x ≤ mi ≤ m.
Folgerung: |L| ≤ 7n/10, |R| ≤ 7n/10
• Komplexität S(n) für select(k, a) mit |a| = n, n groß:
S(n) ≤ 6n + S(n/5) + n + S(7n/10)
Ansatz: S(n) ≤ c · n. Resultat: S ∈ O(n)
• Korrektheit: L 3 x < m < y ∈ R und richtig zählen
• Laufzeit: hängt von geeigneter Wahl von m ab:
Ziele: weder |L| noch |R| groß, m schnell zu berechnen
– Typeset by FoilTEX –
• der Wert m wird so bestimmt:
– teile a in Gruppen G1, G2, . . . je 5 Elemente
– für jedes i bestimme mi := der Median von Gi
– m := der Median von {m1, m2, . . .} (rekursiv)
• Blum et al., JCSS 7(4) 448-461, 1973: https:
//doi.org/10.1016/S0022-0000(73)80033-9
144
– Typeset by FoilTEX –
145
Aufgabe 6.2 (Rekursionsgleichungen)
Übungsserie 6 (für KW 20)
Entscheiden Sie, ob der Hauptsatz anwendbar ist.
Falls ja, lösen Sie dann die Gleichung. (Jeweils 2 P)
Falls nein, lösen Sie dann die Gleichung. (Zusatz: 2 P)
Aufgabe 6.A (autotool)
zur Bestimmung des Medians von 5 Elementen mit 6
Vergleichen.
• T1(n) = 8 · T1(n/2) + 4 · n3
• T2(n) = 8 · T2(n/4) + n2
• T3(n) = 8 · T3(n/2) + n log n
• T4(n) = 9 · T4(n/3) + n2 log n
– Typeset by FoilTEX –
146
Aufgabe 6.2 (ein seltsames Sortierverfahren)
Zum Sortieren einer Folge a[1 . . . n] wird dieses rekursive
Verfahren V vorgeschlagen:
wenn n ≤ 2, dann sortiere a mit 0 oder 1 Vergleich.
sonst: p = bn/3c + 1, q = d2n/3e
V (a[1 . . . q]); V (a[p . . . n]); V (a[1 . . . q])
– Typeset by FoilTEX –
147
wesentlich, ob bei der Bestimmung von p und q auf- oder
abgerundet wird?
• (1 P) Bestimmen Sie die Laufzeit von V nach dem
Hauptsatz über Rekursionsgleichungen. Ist V ein
nützliches Sortierverfahren?
• (1 P) Wenden Sie V an auf [8, 2, 4, 5, 1, 6, 3]
(oder ähnlich, wird vom Übungsleiter vorgegeben)
Expandieren Sie dabei nur die obersten rekursiven
Aufrufe. Nehmen Sie an, daß die weiteren korrekte
Resultate liefern.
• (2 P) Beweisen Sie die Korrektheit von V . Ist es dabei
– Typeset by FoilTEX –
148
Aufgabe 6.3 (Quicksort)
149
Zusatz (1 P) . . . beliebiger Länge n.
• (2 P) Quicksort für eine vorgegebene Eingabe (z.B.
[1, 3, 5, 7, 9, 8, 6, 4, 2]) an der Tafel vorrechnen.
• Betrachten Sie diese Variante von Quicksort, für eine
vorher gewählte Zahl B ≥ 1:
bei jedem rekursiven Aufruf: wenn die Länge der
Eingabefolge ≤ B ist, dann kehren wir sofort zurück,
ohne die Eingabe zu verändern. Ansonsten (Eingabe
länger als B) Partition und Rekursion.
• Um das Verhalten von Quicksort von a[1 . . . n] bei
monotoner Eingabe zu verbessern, wählt man als Pivot
immer das Element auf dem mittleren Index.
Man führt dazu (bei jedem rekursiven Aufruf) für n > 1
zunächst a[bn/2c] ↔ a[n] aus und partitioniert dann
a[1 . . . n − 1] usw. wie im Algorithmus aus Skript.
Nach Rückkehr aller rekursiven Aufrufe sortieren wir das
Array durch Einfügen.
(2 P) Wie teuer ist das abschließende Sortieren
(abhängig von Schranke B und Eingabelänge n)?
(1 P) Wie schnell werden monotone Eingaben dadurch
sortiert? (1 P) Geben Sie eine für dieses Verfahren
aufwendigste Eingabe der Länge 8 an.
– Typeset by FoilTEX –
– Typeset by FoilTEX –
150
– Typeset by FoilTEX –
151
Dynamische Programmierung
Beispiel, Definition
Übersicht
• F (0) = 0, F (1) = 1, ∀n ≥ 2 : F (n) = F (n − 1) + F (n − 2)
Bestimmung von F (n) lt. Def. benötigt Fn Zeit, also Θ(q n)
[WW] Kapitel 8
• das geht aber in Linearzeit, mit Array f [0 . . . n]:
f [0] := 0; f [1] := 1;
für k von 2 bis n: f [k] := f [k − 1] + f [k − 2];
return f [n]
• Definition
• Münzenwechseln
• längste gemeinsame Teilfolge
• Definition: dynamische Programmierung
– Implementierung eines rekursiven Algorithmus
– durch Vorausberechnung und dann Nachnutzung der
Resultate rekursiver Aufrufe
– besonders wirksam, wenn viele Aufrufe übereinstimmen
• Matrixproduktkette
• RNA-Strukturbestimmung
– Typeset by FoilTEX –
152
Beispiel: Geldwechseln (Plan)
• gegeben: Münzwerte m ∈ Nk>0, s ∈ N
gesucht: minimale Anzahl von Münzen mit Summe s
• rekursiv:
A(s) = if s = 0 then 0
else 1 + min{A(s − mi) | 1 ≤ i ≤ k, s ≥ mi}
• dynamische Programmierung: benutze Array a[0 . . . s]
a[0] := 0;
für t von 1 bis s:
a[t] := 1 + min{a[t − mi] | 1 ≤ i ≤ k, t ≥ mi}
return a[s]
154
– Typeset by FoilTEX –
Verstreute Teilfolgen
• Spezifikation (longest common subsequence)
– gegeben: v, w ∈ Σ∗
– gesucht: u mit u ≤ v ∧ u ≤ w, so daß |u| maximal
lcs(v, w) := die Länge eines solchen u
• Bsp: aba ≤ bacbacba wegen i = [2, 4, 8]
• äquivalent: u entsteht aus v durch Löschen von Zeichen
(aber ohne Umordnung der nicht gelöschten)
• Eigenschaften der Relation ≤ auf Σ∗
– (trivial) ist Halbordnung, ist nicht total,
– (nicht trivial — C. Nash-Williams, 1965) jede Antikette
(Menge v. paarweise unvergleichbaren Elementen) ist
endlich
• Anwendung: kürzeste Editier-Folge
– von v zu u: Zeichen löschen (|v| − lcs(v, w) Stück)
– von u zu w: Zeichen einfügen (|w| − lcs(v, w) Stück)
• Anwendungen:
– (algorithmische) Biologie: Vergleich von RNA-Folgen
– Analyse der Ähnlichkeit von Texten
– Bestimmung von Patches bei Quelltextverwaltung
(automat. Zusammenführung von unabh. Änderungen)
156
Bestimmung von LCS (Plan)
– Typeset by FoilTEX –
157
Bestimmung von LCS (Realisierung)
• Eingabe: v[1 . . . p], w[1 . . . q], Ausgabe: lcs(u, w)
• benutze Array L[1 . . . p + 1, 1 . . . q + 1]
mit Spezifikation L[i, j] = lcs(v[i . . . p], w[j . . . q])
• Invariante: die bereits zugewiesenen Werte sind korrekt
L[∗, q + 1] := 0; L[p + 1, ∗] := 0;
für i von p bis 1: für j von q bis 1:
• lcs(empty, w) = 0; lcs(v, empty) = 0
• lcs(cons(v1, v 0), cons(w1, w0)) = das Maximum von . . .
(vollst. Fallunterscheidung nach Startposition einer
längsten gemeinsamen Teilfolge)
– 1 in v und 1 in w: falls v1 = w1, dann 1 + lcs(v 0, w0)
– ≥ 1 in v und > 1 in w: lcs(cons(v1, v 0), w0)
– > 1 in v und ≥ 1 in w: lcs(v 0, cons(w1, w0))
jedes Argument von lcs ist Suffix von v bzw. von w.
L[i, j] := max{ if v[i] = w[j] then 1 + L[i + 1, j + 1] else 0,
L[i, j + 1], L[i + 1, j]};
• dyn. Prog.: berechne L[i, j] := lcs(v[i . . . |v|], w[j . . . |w|])
für i von |v| + 1 bis 1, j von |w| + 1 bis 1
benötigt Θ(|v| · |w|) Zeit (und Platz)
– Typeset by FoilTEX –
155
Gemeinsame Teilfolgen
• Def: u ∈ Σ∗ ist (verstreute) Teilfolge (scattered
subsequence) von v ∈ Σ∗, Notation u ≤ v,
falls ∃i1 < . . . < i|u| : ∀k : uk = vik
– Typeset by FoilTEX –
153
Beispiel: Geldwechseln (Realisierung)
• Spezifikation
– gegeben: Münzwerte m ∈ Nk>0, Betrag s ∈ N
P
– gesucht: Münz-Anzahlen a ∈ Nk mit s = ni=1 miai
Pn
– so daß i=1 ai (Anzahl der Münzen) minimal
• Satz: wenn a eine optimale Lösung für s ist und a0 eine
P
P
optimale Lösung für s − mi, dann
a ≤ 1 + a0.
• deswegen Implementierung: A(0) = [0, . . . , 0],
A(s) := ein Vektor mit minimalem Gewicht aus:
für i ∈ [1, . . . n]: falls s ≥ mi:
bestimme A(s − mi), füge 1 für i hinzu.
• Baum-Rekursion, Verzweigungsgrad k
• dynamische Programmierung: A(0), A(1), . . . , A(s)
– Typeset by FoilTEX –
– Typeset by FoilTEX –
158
return L[1, 1];
• Quelltexte und Profiling: siehe Archiv
• lange gemeinsame Teilfolge durch Analyse von L
– Typeset by FoilTEX –
159
LCS (Anwendung bei Quelltextverwaltung)
RNA-Sekundärstruktur (Definitionen)
• Bezeichnungen:
– RNA: Molekülkette, steuert Protein-Synthese
– Primärstruktur: Folge der Moleküle ∈ {A, C, G, U }∗
– Sekundärstruktur: Paarbindungen der Moleküle
erlaubte Bindungen: {{C, G}, {G, U }, {U, A}}
– Tertiärstruktur: 3-dimensionale Anordnung
• Aufgabe (git rebase):
– betrachte eine Datei in Version A,
– Entwickler 1 ändert A →1 A1,
– Entwickler 2 ändert A →2 A2,
– . . . und will Änderungen von Ent. 1 übernehmen
https://git-scm.com/book/en/v2/
Git-Branching-Rebasing
• Aufgabe (RNA-Sekundärstruktur-Vorhersage):
– Eingabe: eine Primärstruktur p
– Ausgabe: eine dazu passende Sekundärstruktur s
mit minimaler freier (maximaler gebundener) Energie
• Lösung:
– berechne kürzeste Editierfolgen (patch) Pi : A → Ai,
mittels lcs(A, Ai) auf Zeilen (nicht auf Buchstaben)
– wenn P1 ∩ P2 = ∅, dann wende P2 auf A1 an
sonst markiere Konflikt, erfordet manuelle Lösung
– Typeset by FoilTEX –
• s als Klammer-Wort über Alphabet {., (, )}
ohne Kreuzungen: a1 − a2, b1 − b2, a1 < b1 < a2 < b2
160
RNA-Sekundärstruktur (Implementierung)
161
RNA-Sekundärstruktur (Impl. — Detail)
• . . . die richtigen Werte in geeigneter Reihenfolge:
– schließlich benötigt wird M [1, n]
– M [i, j] hängt ab von M [i + 1, j − 1]
sowie für i ≤ k < j : M [i, k] und M [k + 1, j]
– Schranke für diese Abhängigkeiten ist: (j − i)
• Eingabe: p[1 . . . n] ∈ {A, C, G, U }
∗
• Ausgabe: max. Bindungszahl aller Sekundärstrukt. für p
• Implementierung (Plan): SP(p) =
wenn |p| ≤ 4 (minimal hairpin length), dann 0,
sonst das Maximum von
– wenn {p[1], p[n]} ∈ B, dann 1 + SP(p[2 . . . n − 1])
– für k von 1 bis n − 1: SP(p[1 . . . k]) + SP(p[k + 1 . . . n])
• Realisierung durch dynamische Programmierung:
Matrix M [1 . . . n, 1 . . . n] mit Spezif. M [i, j] = SP(p[i . . . j]).
füllen in geeigneter Reihenfolge; return M [1, n];
• Ruth Nussinov et al., SIAM J. Applied Math, 1978
– Typeset by FoilTEX –
– Typeset by FoilTEX –
162
• – insgesamt benötigt werden M [i, j] für 1 ≤ i ≤ j ≤ n
– Bestimmung nach aufsteigenden Werten der Schranke:
erst für j − i = 0 (Diagonale), dann j − i = 1, usw.
• Realisierung:
for d from 0 to n : for i from 1 to n − d : j := i + d, . . .
https://gitlab.imn.htwk-leipzig.de/
waldmann/ad-ss17/tree/master/kw20
– Typeset by FoilTEX –
163
Greedy (gierige) Algorithmen
Weiteres zu RNA-Strukturen
• Struktur-Vorhersage: mehr Realismus durch:
– genaueres Energie-Modell z.B. E(C, G) = 3, . . .
– Pseudoknoten (2 Klammerntypen) .((.[[..).]].).
(die Dyn.-Prog.-Matrix wird dadurch 4-dimensional)
• Struktur-Design: (ist schwieriger, kein dyn. Prog.)
– gegeben ist Sekundarstruktur s (Klammernwort)
– gesucht ist Primärstruktur p, für die s eine (oder sogar:
die einzige) optimale Sekundärstruktur ist
A. Bau et al.: RNA Design by Program Inversion, WCB
2013 http://cp2013.a4cp.org/sites/default/files/
Übersicht
• Definition
• Nochmal Münzenwechseln
• Approximations-Algorithmen für Bin-Packing
uploads/WCB13_proceedings.pdf
• F. Hufsky, 2016: http://bioinfowelten.uni-jena.de/
2016/12/07/spielen-fuer-die-wissenschaft/
– Typeset by FoilTEX –
164
Beispiel, Definition
165
Bin Packing (Koffer packen): Spezifikation
• naive Implementierung f. Münzenwechseln:
• Spezifikation (als Entscheidungsproblem):
M (s) := bestimme die größte Münze mi ≤ s
– Eingabe: Kapazität eines Behälters (Eimer, Koffer)
c ∈ N, Anzahl e ∈ N, Folge x von Zahlen
– Frage: gibt es eine Zerlegung von x in höchstens e
disjunkte zerstreute Teilfolgen, jede mit Summe ≤ c?
und dann 1 + M (s − mi).
• Bsp: m = [1, 5, 8]; 19 → [8, 8, 1, 1, 1], optimal ist [8, 5, 5, 1]
Bsp: m = [1, 2, 5, 10], s = 19 (EUR-Münzen/Scheine)
• Spezifikation (als Optimierungsproblem):
• Vergleich der Algorithmenentwurfsprinzipien:
– Eingabe: c, x wie oben
– Ausgabe: ein minimales e, so daß . . . (wie oben)
– rekursiv : Lösung aus Teillösungen zusammensetzen
– dyn. Prog.: diese Teillösungen effizient verwalten
– gierig: eine Teillösung benutzen, andere ignorieren
dadurch evtl. inkorrekte (nicht optimale) Ausgabe
eventuell reicht diese für den Anwendungsfall aus
– Typeset by FoilTEX –
– Typeset by FoilTEX –
• Bsp: c = 10, e = 4, x = [3, 3, 3, 3, 5, 6, 6, 6]
• ist Modell für reale Ressourcen-Zuordnungs-Aufgaben
166
– Typeset by FoilTEX –
167
Bin Packing: Algorithmen
Online- und Offline-Algorithmen
• vollständige Lösung durch Aufzählen aller Zuordnungen
z: Gegenstand → Koffer, davon gibt es e|x| viele
• kein effizienter Algorithms (Polynomialzeit) bekannt
• dynamische Programmierung verbessert die Laufzeit
nicht, denn es gibt zu viele Teilprobleme
(jede Teilmenge von x, also 2|x| viele)
jedes Element xi ohne Kenntnis von [xi+1, . . . , xn]
verarbeitet (platziert) wird und die Entscheidung nicht
zurückgenommen werden kann
• die ursprüngliche Spezifikation verlangt nur einen
offline-Algorithmus:
die Eingabe kann vollständig gelesen werden, bevor eine
Entscheidung fällt.
• wir betrachten gierige Algorithmen:
schnell (quadratisch), aber nicht optimal.
• – (Börsen)handel online: Kaufvertrag wirkt sofort
– Interbankenhandel offline (Ausgleich bei
Tagesabschluß)
• interessant ist dann die Frage, wie weit Ausgabe des
Algorithmus höchstens vom Optimum entfernt ist
(wir suchen Schranke für den Approximationsfehler)
– Typeset by FoilTEX –
• ein Algorithmus (für Bin Packing) heißt online, wenn
168
– Typeset by FoilTEX –
169
Online-Algorithms: First Fit (FF)
Untere Schranke für Online-Algorithmen
• First Fit: für i von 1 bis n:
– lege xi in den Eimer mit kleinstem Index, in den es paßt.
• Satz: für jeden Online-Algorithmus A für Binpacking gibt
es eine Eingabe, für die A wenigstens 4/3 der optimalen
Eimerzahl verbraucht.
• Satz: First Fit benutzt ≤ 2 mal soviele Eimer wie nötig.
P
• ab jetzt: Kapazität 1, Gewichte xi ∈ Q, S := xi
• Beweis: betrachte m mal 1/2 − , dann m mal 1/2 + .
– nach Verarbeiten der ersten Hälfte sind b Eimer belegt.
Es gilt b < (m/2) · 4/3 (sonst Gegenbeispiel)
– nach Verarbeiten der zweiten Hälfte:
jeder neue Eimer enthält genau einen Gegenstand
die alten Eimer (b Stück) höchstens zwei G.
– insgesamt ≥ 2m − b Eimer benutzt.
– Optimum ist m, also 2m − b < m · 4/3 (sonst Gegenb.)
– addiere beide Ungl ⇒ Widerspruch
• Lemma: optimale Packing benutzt ≥ dSe Eimer.
• Lemma: wenn FF Eimer b1 bis bk verwendet,
dann ist b1 > 1/2, . . . , bk−1 > 1/2.
• Beweis (Satz):
P
– bk ≥ 1/2 ⇒ k · 1/2 ≤
bi = S
P
– bk < 1/2 ⇒ (k − 1) · 1/2 < k−1
bi = S − bk < S − 1/2
1
– Typeset by FoilTEX –
170
Schärfere untere Schranke für FF
– Typeset by FoilTEX –
Übungsserie 7 (für KW 21)
• Satz: Es gibt Eingaben, für die FF ≥ 5/3 des Optimums
benutzt.
Organisatorisches
• in KW 21 wegen der Feiertage keine Übungen
• Beweis (für klein genug):
• stattdessen
m mal 1/7 + , m mal 1/3 + , m mal 1/2 + .
– autotool-Aufgaben (RNA, LCS, Binpack–FFD)
– ein Hörsaal-Übung (zur regulären Vorlesungszeit)
– welche Verteilung liefert FF?
– welches ist die optimale Verteilung?
– Typeset by FoilTEX –
171
172
Aufgabe 7.1 (RNA-Struktur)
– Typeset by FoilTEX –
173
.(((((...)))((...))), ausgibt.
Begründen Sie die Korrektheit, beschreiben Sie die
Laufzeit.
• (1 P) Algorithmus aus Skript für vorgegebene
Primärstruktur an der Tafel ausführen.
• (1 P) Modifizieren Sie den Algorithmus aus dem Skript
so, daß das genauere Energiemodell aus der zitierten
Arbeit von Bau et al. (S. 89 unten) benutzt wird.
• (2 P) Der im Skript angegebene Algorithmus bestimmt
die maximale Anzahl (bzw. maximale gebundene
Energie) der Bindungen, aber nicht die Bindungen selbst.
Geben Sie einen Algorithmus an, der aus dem fertig
befüllten Array M eine optimale Menge von
Paarbindungen bestimmt und als Klammerwort, z.B.
– Typeset by FoilTEX –
174
– Typeset by FoilTEX –
175
Aufgabe 7.2 (Greed)
https://gitlab.imn.htwk-leipzig.de/waldmann/adss17/tree/master/kw20
Wir nennen ein Münzsystem einfach, wenn das gierige
Verfahren für jeden Betrag eine Darstellung mit minimaler
Münzenzahl liefert.
Zusatz (1 P) Welche Systeme [x, y, 1] sind einfach?
• (1 P) (Lese-Übung) Der Pearson-Test (zitiert in J. Shallit,
2002, http://www.cs.uwaterloo.ca/˜shallit/
Papers/change2.ps) stellt fest, ob ein System einfach
ist. Führen Sie diesen Algorithmus für das Münzsystem
[1, 2, 5, 10, 25] (oder ein anderes vom Übungsleiter
vorgegebenes) aus.
• (1 P) vollständige und gierige Zerlegungen mit
gegebenen Parametern an der Tafel ausrechnen.
• (2 P) Welche der Systeme mit drei Münzen [x, y, 1] mit
10 ≥ x > y > 1 sind einfach?
Geben Sie dabei für die nicht einfachen Systeme jeweils
den kleinsten Betrag an, für den der gierige Algoritmus
keine optimale Zerlegung liefert.
Benutzen Sie ggf. Implementierungen aus
– Typeset by FoilTEX –
176
– Typeset by FoilTEX –
177
Bäume als Impl. von Mengen,
Abbildungen, Folgen
Aufgabe 7.3 (Bin Packing)
First Fit Decreasing (FFD) = First Fit für die absteigend
sortierte Eingabefolge.
• Für eine Eingabefolge aus: je 6n Gegenständen der
Größen 1/2 + , 1/4 + 2, 1/4 + und 12n Gegenständen
der Größe 1/4 − 2, und klein genug:
– (1 P) welches ist die optimale Packung?
– (2 P) welche Packung wird von FFD berechnet? Was
genau heißt dabei klein genug“?
”
Übersicht
vgl. [WW] 4.4, 6.2
• Suchbäume, Suchen, Einfügen, Löschen
• Höhen-Balance, Rotation
• evtl. Größen-Balance
• (1 P) warum nützt First Fit Increasing“ (FF für
”
aufsteigend geordnete Eingabe) nichts?
• ADT Menge, Vereinigung, Durchschnitt
• ADT Folge, disjunkte Vereinigung (Verkettung)
– Typeset by FoilTEX –
178
– Typeset by FoilTEX –
Bäume in der Graphentheorie
Bäume in der Informatik
• Graph, Knoten, Kanten, Weg, Zusammenhang, Kreis
• Satz: die folgenden Eigenschaften ungerichteter Graphen
G = (V, E) sind paarweise äquivalent:
– G ist zusammenhängend und G ist kreisfrei
– G ist (kanten)minimal zusammenhängend
d. h., G ist zshg. und ∀e ∈ E : (V, E \ {e}) ist nicht zshg.
– G ist (kanten)maximal kreisfrei
d. h., jedes Hinzufügen einer Kante erzeugt einen Kreis
jede kann als Definition von G ist Baum“ dienen.
”
• Eigenschaft: Baum mit n Knoten hat n − 1 Kanten.
Beweis durch Induktion nach n
– Typeset by FoilTEX –
179
180
• gerichtet:
– ein Knoten ist Wurzel, hat Eingangsgrad 0
– Kanten zeigen von Wurzel weg
– Knoten mit Ausgangsgrad 0: Blätter
– die anderen: innere Knoten
• geordnet:
– die Nachbarn jedes Knoten haben eine Reihenfolge
– können linkes Kind von rechtem Kind unterscheiden
• markiert: (innerer) Knoten enthält Schlüssel
• Bäume sind wichtige Datenstrukturen:
– Bäume repräsentieren Mengen (von Schlüsseln)
– Operationen in O(Grad · Höhe) möglich
– Typeset by FoilTEX –
Binärbäume
181
Binärbäume (Beispiele Größe, Höhe)
• Def: mit zwei Arten von Knoten:
– Blattknoten, äußerer Knoten
(keine Kinder, kein Schlüssel): Leaf
– Verzweigungsknoten, innerer Knoten:
(zwei Kinder l, r, ein Schlüssel k): Branch(l, k, r)
• Größe (Anzahl der Knoten)
size(Leaf) = 1, size(Branch(l, k, r)) = 1 + size(l) + size(r)
• Höhe (Länge eines längsten Pfades von Wurzel zu Blatt)
height(Leaf) = 0,
height(Branch(l, k, r)) = 1 + max{height(l), height(r)}
=
=
=
=
size (Branch(Branch(Leaf,2,Leaf),3,Branch(Leaf,5,L
1 + size(Branch(Leaf,2,Leaf)) + size (Branch(Leaf,
1 + 1 + size (Leaf) + size(Leaf) + 1 + size(Leaf)
1 + 1 +
1
+
1
+ 1 +
1
7
=
=
=
=
=
height (Branch(Branch(Leaf,2,Leaf),3,Branch(Leaf,5
1 + max (height (Branch(Leaf,2,Leaf)), height(Bran
1 + max (1 + max(height(Leaf),height(Leaf)), 1 + m
1 + max (1 + max(0,0)
, 1 + max
1 + max (1 + 0, 1 + 0)
2
• Satz: ∀t : size(t) ≤ 2height(t)+1 − 1
– Typeset by FoilTEX –
182
– Typeset by FoilTEX –
183
Binärbäume (Beweis Größe/Höhe)
Binärbäume (Realisierungen)
Satz: ∀t : size(t) ≤ 2height(t)+1 − 1
Beweis: Induktion nach height(t):
• in Sprachen mit algebraischen Datentypen (Haskell)
data Tree k = Leaf
| Branch (Tree k) k (Tree k)
• Anfang: height(t) = 0 ⇒ t = Leaf ⇒ size(t) = 1
• Schritt: wenn 0 < h = height(t), dann t = Branch(l, k, r)
• in Sprachen mit Zeigern (C, Java, . . . )
height(l) ≤ height(t) − 1 und height(r) ≤ height(t) − 1.
struct branch
{tree left, K key, tree right}:
leaf = nullptr;
typedef branch * tree;
size(t) = size(Branch(l, k, r)) = 1 + size(l) + size(r) ≤
1 + 2height(l)+1 − 1 + 2height(r)+1 − 1 ≤
2height(t)−1+1 + 2height(t)−1+1 + (1 − 1 − 1) = 2height(t)+1 − 1
• implizite Realisierungen
z.B.: a[1 . . . n], Kinder von a[i] sind a[2i] und a[2i + 1]
– Typeset by FoilTEX –
184
Baum-Durchquerungen
185
Baum-Durchquerungen (Beispiele)
t = Branch(Branch(Leaf,2,Leaf),1,Branch(Branch(Leaf,
• Abbildung von Binärbaum zu Folge von Schlüsseln
immer l vor r, Lage von k unterschiedlich:
• pre(Leaf) = [], pre(Branch(l, k, r)) = [k] ◦ pre(l) ◦ pre(r)
• ino(Leaf) = [], ino(Branch(l, k, r)) = ino(l) ◦ [k] ◦ ino(r)
• post(Leaf) = [], post(Branch(l, k, r)) = post(l)◦post(r)◦[k]
• Preorder und Postorder auch für beliebigen Knotengrad.
Inorder nur für Binärbäume sinnvoll definierbar.
• ohne Berücksichtigung der Reihenfolge: die Menge der
Schlüssel.
keys(Leaf) = ∅,
keys(Branch(l, k, r)) = keys(l) ∪ {k} ∪ keys(r)
– Typeset by FoilTEX –
– Typeset by FoilTEX –
ino(t)
= ino(Branch(Branch(Leaf,2,Leaf),1,Branch(Branch(Lea
= ino(Branch(Leaf,2,Leaf)) ++ [1] ++ ino(Branch(Bran
= ino(Leaf) ++ [2] ++ ino(Leaf) ++ [1] ++ ino(Branch
= [] ++ [2] ++ [] ++ [1] ++ ino(Leaf) ++ [4] ++ ino(
= [2,1,4,3]
pre(t) = [1,2,3,4]
post(t) = [2,4,3,1]
keys(t) = {1,2,3,4}
186
Suchbäume — Definition, Suchen
– Typeset by FoilTEX –
187
Suchbäume — Suchen (Beispiel)
contains (4, Branch(Branch(Leaf,2,Leaf),3,Branch(L
= contains (4, Branch(Leaf,5,Leaf))
= contains (4, Leaf)
= false
• Def: ein binärer Baum t heißt Suchbaum
gdw. ino(t) ist monoton steigend.
• äquivalent: für jeden Teilbaum Branch(l, k, r) von t gilt:
∀x ∈ keys(l) : x < k und ∀x ∈ keys(r) : k < x
• Such(K) := Menge der Suchb. mit Schlüsseln vom Typ K
• Spezif.: contains(x, t) ⇐⇒ (x ∈ keys(t)), Impl.:
contains(x, Leaf) = false
contains(x, Branch(l, k, r)) = if x = k then true
else if x < k then contains(x, l) else contains(x, r)
• Korrektheit: durch Induktion nach height(t), ist Schranke
für lineare Rekursion, Komplexität: Θ(height(t))
– Typeset by FoilTEX –
188
Suchbäume — Einfügen
189
Suchbäume — Einfügen (Beispiel)
• Spezifikation: insert : K × Such(K) → Such(K),
keys(insert(x, t)) = {x} ∪ keys(t)
• Implementierung:
insert(x, Leaf) = Branch(Leaf, x, Leaf)
insert(x, Branch(l, k, r)) =
if x = k then Branch(l, k, r)
else if x < k then Branch(insert(x, l), k, r)
else Branch(l, k, insert(x, r))
• Korrektheit: Induktion. Zu zeigen ist (u.a.), daß jeder
konstruierte Knoten die Suchbaum-Eigenschaft hat
• Termination/Komplexität: lineare Rekursion mit Schranke
height(t)
– Typeset by FoilTEX –
– Typeset by FoilTEX –
190
insert (4,Branch(Branch(Leaf,3,Leaf),5,Branch(Bran
= Branch(insert(4,Branch(Leaf,3,Leaf)),5,Branch(Bran
= Branch(Branch(Leaf,3,insert(4,Leaf)),5,Branch(Bran
= Branch(Branch(Leaf,3,Branch(Leaf,4,Leaf)),5,Branch
– Typeset by FoilTEX –
191
Suchbäume — Einfügen (Beweis)
Branch(l, k, insert(x, r)) ∈ Such(K).
1. Lemma t ∈ Such(K) ⇐⇒ t = Leaf ∨t =
Branch(l, k, r) ∧ l ∈ Such(K) ∧ r ∈ Such(K) ∧ ∀x ∈
keys(l) : x < k ∧ ∀x ∈ keys(r) : k < x.
Beweis:
Es gelten:
∀y ∈ keys(l) : y < k weil t Suchbaum ist
• ⇒ “ :ino(Branch(l, k, r)) monoton ⇒ ino(l) monoton und
”
ino(r) monoton, also nach Induktion l, r ∈ Such(K).
∀y ∈ keys(insert(y, r)) : k < y, weil
keys(insert(x, r)) = {x} ∪ keys(r) nach Induktion und
k < x (haben wir getestet) und ∀y ∈ keys(r) : k < y, weil
t Suchbaum ist.
2. Korrektheit des Einfügens: zu zeigen sind
• keys(insert(x, t)) = {x} ∪ keys(t) — das ist einfach
• x ∈ K, t ∈ Such(K) ⇒ insert(x, t) ∈ Such(K)
Bsp. betrachte letzten Zweig des Algorithmus: zeige, daß
(unter den gegebenen Voraussetzungen)
– Typeset by FoilTEX –
192
Persistente und ephemere Datenstrukturen
193
Bestimmen und Löschen des Minimums
• wir betrachten persistente (unveränderliche) Suchbäume:
– werden einmal konstruiert und nie verändert,
– Operationen (wie insert) erzeugen neuen Baum
• das Gegenteil sind ephemere (veränderliche) Strukturen:
– Operationen können Daten in-place“ verändern
”
• vollständige Persistenz hat diese Vorteile:
– Semantik nicht von implizitem Zustand abhängig
– beliebiges sharing von Teilstrukturen möglich
– einfache Parallelisierung von Operationen
• ist Operationen erzeugen neuen Baum“ ineffizient?
”
nein, es werden nur O(height(t)) neue Knoten allokiert.
– Typeset by FoilTEX –
– Typeset by FoilTEX –
• Spezifikation:
extractMin : Such(K) → K × Such(K)
wenn keys(t) = M 6= ∅,
dann extractMin(t) = (m, t0)
mit m = min M und keys(t0) = M \ {m}.
• Implementierung: extractMin(Branch(l, k, r)) =
– falls l = Leaf, dann . . .
– sonst let (m, l0) = extractMin(l) in . . .
• lineare Rekursion, Laufzeit: O(height(t))
194
Suchbäume — Löschen
– Typeset by FoilTEX –
195
Übungsserie 8 für KW 22
• Spezifikation: delete : K × Such(K) → Such(K)
Aufgabe 8.A (autotool)
keys(delete(x, t)) = keys(t) \ {x}
• Rekonstruktionsaufgaben pre/in/post-order
• Implementierung:
• Einfügen/Löschen in Suchbäumen
– delete(x, Leaf) = . . .
– delete(x, Branch(l, k, r)) =
∗ falls x < k, dann Branch(delete(x, l), k, r)
∗ falls x > k, dann . . .
∗ falls x = k, dann
· falls r = Leaf, dann . . .
· sonst let (m, r0) = extractMin(r) in . . .
• lineare Rekursion, Laufzeit: O(height(t))
– Typeset by FoilTEX –
196
– Typeset by FoilTEX –
Grundsätzliches
197
Aufgabe 8.1 (Bäume)
Auch wenn es nicht explizit dasteht: alle Aussagen sind zu
begründen.
Es mag ja sein, daß in der Schule trainiert wird,
bestimmen Sie“ von geben Sie an“ zu unterscheiden.
”
”
Sie sind jetzt aber an einer Hochschule, und dort gibt es
nicht für jeden Arbeitsschritt eine separate Einladung und
Anleitung,
denn das Studienziel ist, daß Sie wissenschaftliche
Methoden des Fachgebietes selbständig anwenden.
Das wissenschaftliche Vorgehen zeichnet sich gerade
dadurch aus, daß jeder Schritt begründet und jedes
Resultat überprüfbar ist.
Für die durch
B(n) := if n >
0 then Branch(B(n − 1), n, B(n − 1)) else Leaf
definierten Binärbäume:
– Typeset by FoilTEX –
– Typeset by FoilTEX –
198
• (1 P) Wieviele innere Knoten hat B(n)?
• (1 P) Wieviele Blätter?
• (2 P) Summe der Schlüssel?
199
Aufgabe 8.2 (Suchbäume)
Aufgabe 8.3 (Suchbäume)
Implementieren Sie diese Spezifikation
• (1 P) Gegen Sie für M = {3, 5, 7, 8, 11, 13, 25}
Suchbäume t mit keys(t) = M der Höhe 2, 3, 4, 5 an.
• up : K × Such(K) → Such(K)
• (1 P) Für einen Suchbaum t wird contains(20, t)
ausgewertet. Dabei wird der gesuchte Wert der Reihe
nach mit [5, 40, 30, 10, 11, 33, 14] verglichen — angeblich.
Begründen Sie, daß das nicht stimmen kann.
in Zeit O(height(t)).
(3 P) Ergänzen Sie den Ansatz
• up(x, Leaf) = . . .
• (2 P) Beweis oder Gegenbeispiel:
• up(x, Branch(l, k, r)) =
– ∀x ∈ K, t ∈ Such(K) : x ∈ keys(t) ⇒
insert(x, delete(x, t)) = t
– ∀x ∈ K, t ∈ Such(K) : x ∈
/ keys(t) ⇒
delete(x, insert(x, t)) = t
– Typeset by FoilTEX –
keys(up(x, t)) = {k | k ∈ keys(t) ∧ x ≤ k}
– falls x ≤ k, dann. . .
– falls x > k, dann. . .
(1 P) Bestimmen Sie up(5, t) für t = der Baum, der durch
200
– Typeset by FoilTEX –
201
Balancierte Suchbäume
Einfügen von [1, 8, 2, 7, 3, 6, 4, 5] in dieser Reihenfolge in
Leaf entsteht.
Motivation
• Laufzeit vieler Algorithmen f. Suchbäume: O(height(t)).
• für jeden binären Suchbaum t gilt
height(t) ≤ # keys(t) < 2height(t) (Beweis: Induktion)
also log2 # keys(t) < height(t) ≤ # keys(t).
• ein effizienter Suchbaum ist ein solcher mit Höhe
log2 # keys(t) . . . oder Θ(log # keys(t)).
• das kann erreicht werden durch eine strukturelle
Invariante ( jeder Teilbaum ist balanciert“)
”
• das Herstellen der Invariante (bei jedem
Konstruktor-Aufruf) darf aber nicht zu aufwendig sein
– Typeset by FoilTEX –
202
– Typeset by FoilTEX –
Zu strenge Balance
Höhen-Balance (Definition)
• Ein Binärbaum t heißt vollständig, wenn jedes Blatt die
Tiefe height(t) hat.
– ⇒ # keys(t) = 2height(t) − 1, also
height(t) = log2 # keys(t)
– gibt es nur für diese Schlüssel-Anzahlen!
• Def: ein Baum t heißt höhen-balanciert,
falls für jeden Teilbaum Branch(l, k, r) von t gilt:
height(l) − height(r) ∈ {−1, 0, +1}.
• . . . fast vollständig, falls jede Blatt-Tiefe ∈ {h, h − 1} mit
h = height(t) und Blätter mit Tiefe h links von denen mit
Tiefe h − 1 stehen
– ⇒ 2h−1 ≤ # keys(t) ≤ 2h − 1, ⇒ h = dlog2 # keys(t)e
– für jede Schlüssel-Anzahl genau ein solcher Baum,
– finde t1, t2 mit keys(t1) = {2 . . . 7}, keys(t2) = {1 . . . 7},
– was folgt für die Komplexität des Einfügens?
– Typeset by FoilTEX –
204
Höhen-Balance erzwingt logarithmische Höhe
• Satz: t ∈ AVL(K) ⇒ # keys(t) ≥ Fheight(t)+2 − 1
• die Menge der höhen-balancierten Suchbäume: AVL(K),
mit Höhe h: AVLh(K)
Adelson-Velski, Landis; 1962
• das ist eine nützliche strukturelle Invariante, denn:
– t ∈ AVL(K) ⇒ height(t) ∈ Θ(log(size(t)))
– eine durch Einfügen eines Schlüssels zerstörte
Invariante läßt sich leicht reparieren
– Typeset by FoilTEX –
205
Operationen für balancierte Suchbäume
• aus dem Code für insert(x, t), delete(x, t)
für unbalancierte Suchbäume
wird Code für balancierte Suchbäume:
mit Fibonacci-Zahlen F0 = 0, F1 = 1, Fn+2 = Fn + Fn+1
• Beweis:
– height(t) = 0. Dann t = Leaf, # keys(t) = 0 = F2 − 1
– height(t) = 1. Dann t = . . .
– height(t) = h ≥ 2. Dann t = Branch(l, k, r)
mit (height(l) = h − 1 und height(r) ≥ h − 2)
oder (height(l) ≥ h − 2 und height(r) = h − 1).
dann # keys(t) ≥ (Fh − 1) + 1 + (Fh+1 − 1) = Fh+2 − 1
• Anwendg.: log(Fh) ∈ Θ(h) ⇒ log # keys(t) ≥ c · height(t),
⇒ height(t) ∈ O(log # keys(t))
– Typeset by FoilTEX –
203
206
• jeder Aufruf des Konstruktors Branch(l, k, r)
wird ersetzt durch smart constructor
balance(Branch∗(l, k, r)),
• dabei gilt ∀x ∈ keys(l) : x < k, ∀y ∈ keys(r) : k < y,
l, r ∈ AVL(K) und | height(l) − height(r)| ≤ 2.
Resultat ∈ AVL(K)
• Zusatzkosten O(height(t)), falls Rebalancieren in Θ(1)
für insert: tatsächlich nur Θ(1)
– Typeset by FoilTEX –
207
Balancieren durch Rotieren (1)
Balancieren durch Rotieren (2)
• Fall 1.2: t = Branch∗(Branch(ll, lk, lr), k, r),
• Knoten mit Höhendifferenz 2 :
ll ∈ AVLh(K), lr ∈ AVLh+1(K), r ∈ AVLh(K)
– Fall 1: t = Branch∗(l, k, r),
l = Branch(ll, lk, lr) ∈ AVLh+2(K), r ∈ AVLh(K)
∗ Fall 1.1: ll ∈ AVLh+1(K), lr ∈ AVL{h,h+1}(K)
∗ Fall 1.2: ll ∈ AVLh(K), lr ∈ AVLh+1(K)
– Fall 2 (Fälle 2.1, 2.2) symmetrisch
• eine Rechts-Rotation allein hilft nicht (nachrechnen!)
• lr = Branch(lrl, lrk, lrr) mit lrl, lrr ∈ AVL{h,h−1}(K)
• Links-Rot. in l ⇒ l0 = Branch(Branch(ll, lk, lrl), lrk, lrr)
keys(l) = keys(l0),l ∈ Such(K) ⇒ l0 ∈ Such(K),
Branch(ll, lk, lrl) ∈ AVLh+1(K)
• löse Fall 1.1 durch Rotation nach rechts
– ersetze t durch t0 = Branch(ll, lk, Branch(lr, k, r)).
keys(t) = keys(t0), t ∈ Such(K) ⇒ t0 ∈ Such(K)
Branch(lr, k, r) ∈ AVLh+1(K), t0 ∈ AVLh+2(K).
– beachte: funktioniert auch für lr ∈ AVLh−1(K),
das wird für Behandlung von 1.2 benötigt
– Typeset by FoilTEX –
• dann erfüllt Branch∗(l0, k, r) die Voraussetzung von 1.1
(ggf. unter Benutzung von beachte:“)
”
Rechts-Rotation ergibt t0 ∈ AVLh+2(K).
208
– Typeset by FoilTEX –
209
Korrektheit und Anzahl der Rotationen: Insert Korrektheit und Anzahl der Rotationen: Delete
• für alle (smart) Konstruktor-Aufrufe Branch∗(l, k, r) zeige:
| height(l) − height(r)| ≤ 2
• für alle Aufrufe balance(Branch∗(l, k, r)) ist zu zeigen
| height(l) − height(r)| ≤ 2
• folgt aus height(t) ≤ height(insert(x, t)) ≤ height(t) + 1
• folgt aus height(t) − 1 ≤ height(delete(x, t)) ≤ height(t)
• Begründung:
– durch nicht balanc. Einfügen steigt Höhe um max. 1
– betrachte untersten Knoten (Teilbaum) t mit
Höhendifferenz 2
dann height(balance(t)) = height(t) nur im Fall . . .
und dieser tritt beim Einfügen nicht ein.
– ⇒ nach Rotieren wieder Original-Höhe
– ⇒ Knoten darübe benötigen keine Rotationen
• wenn beim Rotieren die Höhe verringert wird, dann muß
darüber auch evtl. auch noch rotiert werden, usw.
• Das Löschen eines Knotens kann Θ(height(t))
Rotationen erfordern.
• Bsp: betrachte Fibonacci-Baum
T0 = T1 = Leaf, Tk+2 = Branch(Tk+1, Tk )
und lösche den Knoten ganz rechts
• insgesamt beim Einfügen höchstens einmal rotieren
– Typeset by FoilTEX –
210
– Typeset by FoilTEX –
Ergänzungen
Anwendungen Suchbäume
• AVL-Operationen ausprobieren: benutze
autotool-Aufgabe
• realisieren abstrakten Datentyp (ADT) Menge
–
–
–
–
• Quelltexte https://gitlab.imn.htwk-leipzig.de/
waldmann/ad-ss17/tree/master/kw22/avl
https://gitlab.imn.htwk-leipzig.de/autotool/all0/
blob/master/collection/src/Baum/AVL/Ops.hs
java.util: TreeSet<K> implements Set<K>
contains : K × Set(K) → B, empty, insert, delete
Komplexität O(height(t))
für balancierte Bäume: O(log # keys(t))
• in inneren Knoten Schlüssel und Wert speichern:
• exakte Spezifikationen mit vollständig maschinell
überprüften Beweisen (Nipkow et al., 2004):
realisiert ADT Abbildung
– lookup: K × Map(K, V ) → V ∪ {⊥},
empty, insert (update), delete (Ü: welche Typen?)
– Komplexität wie oben
https://www.isa-afp.org/browser_info/current/AFP/
AVL-Trees/AVL.html
– Typeset by FoilTEX –
211
212
Weitere Operationen für Suchbäume
– Typeset by FoilTEX –
213
Übungsserie 9 für KW 23
• Massen-Operationen: intersection, difference,
union: Set(K) × Set(K) → Set(K),
compose (join): Map(A, B) × Map(B, C) → Map(A, C)
Aufgabe 9.A
• (autotool) Einfügen und Löschen in AVL-Bäumen
• Komplexität für Union(t1, t2): durch Iterieren über
Schlüsselmenge des kleineren Baumes:
min(|t1|, |t2|) · log max(|t1|, |t2|)
• durch Implementierung von balance(Branch∗(l, k, t))
für beliebige | height(l) − height(r)|
in O(height(t1) + height(t2))
• schnelleres Union für disjunkte Mengen
(das ist auch nützlich in Teilbäumen)
– Typeset by FoilTEX –
214
– Typeset by FoilTEX –
215
Aufgabe 9.1 (Rotieren)
Aufgabe 9.2 (AVL-Struktur)
Aufgabe 13.2–4 aus [Cormen, Leiserson, Rivest, Stein]
(deutsche Ausgabe als E-Buch in der Bibliothek)
Die Aussage ist zu ergänzen: . . . in jeden anderen binären
”
Suchbaum mit der gleichen Schlüsselmenge . . .“, sonst ist
sie trivial falsch.
(2 P) Lösen Sie die Aufgabe für den Spezialfall, daß t1 ein
vollständiger binärer Suchbaum mit 7 Schlüsseln und t2
eine rechtsläufige Kette ist.
(2 P) Lösen Sie die Aufgabe allgemein.
– Typeset by FoilTEX –
216
• (2 P) Was ist die minimale Tiefe (d.h. Abstand von der
Wurzel) der Blätter aller AVL-Bäume mit Höhe h?
• (2 P) Leiten Sie daraus einen weiteren Beweis für
height(t) ∈ O(log size(t)) ab.
• (3 P) Konstruieren Sie einen Baum
t = Branch(l, k, r) ∈ AVL(K) mit size(l)/ size(r) > 1000.
(Nicht konkret aufmalen, sondern beweisen, daß es
einen gibt. Welche Höhe hat er?)
– Typeset by FoilTEX –
Heap-geordnete Bäume
Aufgabe 9.3 (AVL-Operationen)
• (3 P) Bestimmen Sie t1, . . . , t7 für
t0 = Leaf, tk = insert(k, tk−1).
Übersicht
• der abstrakte Datentyp PWS (PQ)
Welche Balance-Operationen finden dabei statt?
• heap-geordnete Bäume [WW] Kap. 10, [OW] Abschn. 6.1
• (3 P) Bestimmen Sie t1, . . . , t7 für t0 = vollständiger
binärer Suchbaum mit Schlüsseln {1, 2, . . . , 7},
tk = delete(k, tk−1).
• vollständig balancierte Binärbaume (Anwendung:
Heap-Sort)
Welche Balance-Operationen finden dabei statt?
– Typeset by FoilTEX –
• evtl. Ausblick: Quake Heaps
218
– Typeset by FoilTEX –
Motivation und Plan
• wird u.a. für Bestimmung kürzester Wege benötigt
• wir benutzen Binärbäume t mit diesen Eigenschaften:
– heap-geordnet: für jeden Teilbaum Branch(l, k, r) von t:
∀x ∈ keys(l) : k ≤ x, ∀y ∈ keys(r) : k ≤ y
– fast vollständig balanciert:
alle Blätter in Tiefe h oder (rechts davon) h − 1.
• diese Forderung ist diesmal nicht zu streng, denn es gibt
genügend viele Repräsentationen einer festen Menge
von Schlüsseln
(Bsp: {1, 2, . . . , 7})
• die Menge soll nicht vollständig geordnet werden,
weil das evtl. zu teuer ist (also kein Suchbaum)
• Operationen in O(height(t)) = O(log # keys(t)) . . . oder
noch weniger
220
Binäre Heaps (Implementierung)
– Typeset by FoilTEX –
221
Binäre Heaps: Einfügen, Verringern
• die fast vollständige Balance wird durch eine implizite
Baumdarstellung erreicht:
–
–
–
–
219
Binäre Heaps (Plan)
• abstrakter Datentyp: Vorrang-Warteschlange (priority
queue) (Priorität ∈ N, kleiner ⇒ wichtiger), Operationen:
– insert : (K × N) × PQ(K) → PQ(K)
– extractMin : PQ(K) ,→ (K × PQ(K)) (partielle Ftk.)
bestimmt und entfernt einen wichtigsten Eintrag
– decrease : (K × N) × PQ(K) → PQ(K) erhöht Priorität
das ist der Plan, tatsächlich sind die Typen noch anders
– Typeset by FoilTEX –
217
• insert(k, A[1 . . . n]):
– füge neues Element an: A[n + 1] := k,
– repairere Heap-Ordnung (auf Pfad von n + 1 zu Wurzel)
∗ i := n + 1, (A[i] ist evtl. zu klein, wandert nach oben)
∗ solange i > 1 und A[parent(i)] > A[i]:
A[parent(i)] ↔ A[i]; i := parent(i).
Branch-Knoten stehen in einem Array A[1 . . . n]
K1 ist die Wurzel
Ki = Branch(K2i, A[i], K2i+1)
für i > n : Ki = Leaf
• Korrektheit (Invariante): ∀j : j 6= i ⇒ A[parent(j)] ≤ A[j].
• diese Form bleibt immer erhalten
• Laufzeit: O(height(t)) = O(log n).
(evtl. ändern wir n um 1)
• gleicher Algorithmus zum Reparieren nach
decrease(i, v, A): Aneu[i] := v ≤ Avorher[i]
• die Operationen reparieren ggf. die Heap-Ordnung
durch Vertauschung von Elementen.
– Typeset by FoilTEX –
222
– Typeset by FoilTEX –
223
Binäre Heaps: Minimum bestimmen und
entfernen
Binäre Heaps: Heap erzeugen
• gegeben: Folge (Multimenge) von Schlüsseln M
gesucht: binärer Heap t mit keys(t) = M
• triviale Lösung: fortgesetztes Einfügen
P
Laufzeit (mit h = log n): hk=1 2k · k = Θ(n log n)
(welches ist der schlechteste Fall?)
• alternative Lösung:
– Eingabe in A[1 . . . n] schreiben,
– für i von n/2 bis 1: repariere A[i] ist zu groß“.
”
Invariante: ∀j : j > i ⇒ Teilbaum ab j ist heap-geordnet
Ph
Laufzeit: k=1 2k · (h − k) = Θ(n)
• NB: Unterschied Heap/Suchbaum: beweise, daß es nicht
möglich ist, einen Suchbaum in O(n) zu konstruieren.
• Heap-Ordnung ⇒ das Minimum steht immer in A[1]
• Minimum entfernen: A[1] := A[n], n := n − 1,
reparieren (A[i] ist evtl. zu groß, wandert nach unten)
– i := 1,
– solange A[i] > A[left(i)] ∨ A[i] > A[right(i)]:
A[i] ↔ min(A[left(i)], A[right(i)])
i := vorige Position des Minimums
• Korrektheit (Invariante):
∀j : (parent(j) 6= i) ⇒ A[parent(j)] ≤ A[j]
• Laufzeit: O(height(t)) = O(log n).
– Typeset by FoilTEX –
224
Bemerkung zur Implementierung (I)
– Typeset by FoilTEX –
225
Bemerkung zur Implementierung (I)
• wir hatten in erster Näherung diese Typen behauptet:
• diese Verweise muß man richtig verwalten,
• das geht gar nicht, denn um einen Schlüssel zu
verringern, muß man wissen, wo er steht — man kann
ihn aber nicht suchen (weil der Heap kein Suchbaum ist)
• Lösung: ein zusätzliches Array R, Zähler t
– insert : (K × N) × PQ(K) → PQ(K)
– decrease : (K × N) × PQ(K) → PQ(K)
denn durch Operationen wie A[parent(i)] ↔ A[i] werden
Plätze getauscht.
• Lösung: das Einfügen liefert einen Verweis in den Heap,
der beim Verringern benutzt wird:
– insert : (K × N) × PQ(K) → (Ref(K) × PQ(K))
– decrease : (Ref(K) × N) × PQ(K) → PQ(K)
– Typeset by FoilTEX –
– bei jedem insert: t := t + 1; R[t] = n + 1
(dort beginnt die Bahn des eingefügten Elements,
t ist der Verweis-Rückgabewert des insert)
– bei jedem A[i] ↔ A[j]: auch R[i] ↔ R[j]
– decrease(t, v) bezieht sich dann auf A[R[t]].
Details, Beispiele: siehe [WW]
226
– Typeset by FoilTEX –
Ausblick: schnellere Heaps
Anwendung binärer Heaps: Heapsort
• das ist ein Sortierverfahren:
– Eingabe in A[1 . . . n] schreiben
– Heap-Ordnung herstellen (Komplexität Θ(n))
– fortgesetztes extractMin (Komplexität Θ(n log n))
liefert Elemente in aufsteigender Reihenfolge
• wenn man dafür Max-Heap (statt Min-Heap) benutzt,
kann man Heap und Ausgabe im gleichen Array
abspeichern
• ergibt asymptotisch optimales Sortierverfahren mit wenig
(d.h. konstantem) zusätzlichen Platzbedarf
(vgl. merge-sort)
– Typeset by FoilTEX –
227
• hier gezeigte binäre Heaps realisieren
insert, decrease, extractMin jeweils in O(log n)
• das kann ein balancierter Suchbaum auch
• es gibt Heaps (z.B. Fibonacci heaps, Quake heaps)
für die decrease schneller geht (in O(1))
und die anderen Op. immer noch in O(log n).
(decrease ist häufigste Operation im später betrachteten
Algorithmus von Dijkstra zum Bestimmen kürzester
Wege)
• dafür sind fortgeschrittene Analyse-Techniken nötig
• T. M. Chan: Quake Heaps, 2013, http://link.springer.com/
chapter/10.1007/978-3-642-40273-9_3
228
– Typeset by FoilTEX –
229
Aufgabe 10.1 (Binäre Heaps)
Übungsserie 10 für KW 24
• (3 P) Repräsentiert das Array einen Heap? Wenn nein,
repräsentiert es einen Zwischenzustand bei der
Ausführung von insert? von extractMin?
Aufgabe 10.A (autotool)
• insert, decrease, extractMin für binäre Heaps
– [2, 11, 3, 7, 6, 4, 8, 12, 10]
– [2, 5, 3, 8, 6, 7, 4]
– [1, 6, 3, 7, 5, 2, 8, 9]
• (2 P) Eine Folge von Operationen, die dann vom
Übungsleiter vorgegeben wird, an der Tafel vorrechnen
(ohne Hilfsmittel).
Beispiele: Für den durch das Array [1, 2, . . . , 7] implizit
repräsentierten Heap:
– Typeset by FoilTEX –
230
– Typeset by FoilTEX –
231
Aufgabe 10.2 (Kombination Suchbaum und
Heap)
– solange extractMin, bis der Heap leer ist.
– für k von 1 bis 7: die Priorität von k auf −k verringern.
Wir betrachten binäre Bäume, deren Schlüssel
Zahlenpaare sind, so daß für die ersten Komponenten die
Heap-Eigenschaft und für die zweiten Komponenten die
Suchbaum-Eigenschaft gilt. (Es wird keine
Balance-Eigenschaft gefordert.)
• (1 P) Geben Sie einen solchen Baum t mit folgender
Schlüsselmenge an:
{(5, 1), (4, 3), (7, 4), (3, 0), (1, 5), (6, 7)}
• (2 P) Beweisen Sie: für jede Schlüsselmenge M ⊆ N × N,
deren ersten Komponenten paarweise verschieden sind
– Typeset by FoilTEX –
232
und deren zweiten Komponenten paarweise verschieden
sind, gibt es genau solchen Baum t mit keys(t) = M .
– Typeset by FoilTEX –
233
Aufgabe 10.3 (Young-Tableaux)
(4 P) [CLRS] Aufgabe 6-3 a,c,d,e.
Hinweis: Induktion nach der Größe von M .
• (2 P) Geben Sie ein Verfahren zum Einfügen an.
Hinweis: Rotationen. Fügen Sie (2, 2) in t ein.
– Typeset by FoilTEX –
234
Direkter Zugriff (Hashing und
Anwend.)
• Aufgabe: sortiere eine Folge von 1.000.000 Zahlen.
Lösung: Merge-, Heap-, Quick-, Bubble-Sort usw.
[WW] 9, [CLRS] 11
• Aufgabe: sortiere eine Folge von 1.000.000 natürlichen
Zahlen aus dem Intervall [0 . . . 1000]
• Counting-Sort,
Lösung: . . .
• Hash-Tabellen
• Hinweis:
• Radix-Sort, Tries
Aufgabe: sortiere eine Folge von 1.000.000 Bits
236
– Typeset by FoilTEX –
237
Hashing zur Implementierung des ADT Menge
Sortieren durch Zählen
• Aufgabe: sortiere eine Folge a von n natürlichen Zahlen
aus dem Intervall [0 . . . B]
• Lösung: benutze Array c[0 . . . B], initialisiert mit [0, . . . , 0]
– für i von 1 bis n: { k := a[i]; c[k] := c[k] + 1 }
Invariante: ∀k : c[k] = #{j | 1 ≤ j < i ∧ a[j] = k}
– für k von 0 bis B: drucke c[k] mal k
• Laufzeit ist n + B, also für festes B: Sortieren in O(n)?
• Ja. Das ist kein Widerspruch zu Schranke Ω(n log n),
denn diese gilt nur für vergleichsbasierte Verfahren
• Spezifikation:
– empty, contains, insert : K × Set(K) → Set(K), delete
– Semantik: dynamisch (ephemer, mutable)
Operationen zerstören vorige Werte
• Plan zur Implementierung:
– benutze Array a[0..m − 1] von Wahrheitswerten
– Funktion (hash) h : K → [0..m − 1]
– contains(x, S) ⇐⇒ a[h(x)]
• dazu müssen diese Fragen geklärt werden:
– welcher Wert für m (Kapazität)?
– welche Funktion h?
– was passiert bei Kollision x 6= y ∧ h(x) = h(y)?
• Algorithmus Sortieren durch Zählen“ (counting sort)
”
benutzt direkten Zugriff (Zahlenwerte der Eingabe)
– Typeset by FoilTEX –
235
Motivation
Übersicht
– Typeset by FoilTEX –
– Typeset by FoilTEX –
238
– Typeset by FoilTEX –
239
Hashfunktionen (1)
Hashfunktionen (2)
• Ziel h : N → [0..m − 1]
• Ziel: Funktion (hash) h : K → [0..m − 1]
– h soll Wertebereich möglichst gleichmäßig ausnutzen
– Wert h(x) sollte von allen Bits von x abhängen
• Realisierung in zwei Schritten:
– von K zu N
– von N zu [0..m − 1]
• Divisionsmethode: h(x) = mod(x, m)
– m sollte nicht von der Form 2e sein
– Ü: m sollte nicht 2e − 1 sein
• Schritt 1 ist grundsätzlich deswegen möglich,
weil alle Daten binär im (Haupt)speicher stehen
und jede Bitfolge eine natürliche Zahl beschreibt.
• Multiplikationsmethode: h(x) = bm · mod(q · x, 1)c
√
– für eine irrationale Zahl q, z.B. ( 5 + 1)/2
– dabei bedeutet mod(·, 1) : R → R : z 7→ z − bzc
– Ü: kann mit Ganzzahl-Arithmetik implementiert werden,
benutze q ≈ Q/2e für passendes Q ∈ N und m = 2e.
• wir nehmen deswegen an, daß K = N
– Typeset by FoilTEX –
240
– Typeset by FoilTEX –
241
Hashing mit offener Adressierung
Hashing mit Verkettung (Chaining)
• das Kollisions-Problem: falls x 6= y ∧ h(x) = h(y):
S0 = empty; S1 = insert(x, S0); contains(y, S1) =?
• Motivation: Vermeidung des Aufwandes (Zeit und Platz)
für die Verwaltung der Mengen (z.B. Zeiger für Listen)
• Lösung (Plan)
– Element-Typ des Arrays ist nicht B, sondern Set(K)
– meist repräsentiert durch einfach verkettet Liste
• Tabellen-Einträge sind K ∪ {⊥}, bei Konflikt zw. x und y
wird y an einer anderen Stelle in der Tabelle gespeichert.
• Beispiel (lineares Sondieren)
– insert(x, S): für p von h(x) bis mod(h(x) + m − 1, m):
falls a[p] = ⊥, dann a[p] := x und fertig,
falls a[p] = x, dann fertig
– contains(x, S): für p von h(x) bis mod(h(x) + m − 1, m):
falls a[p] = ⊥, dann false
falls a[p] = x, dann true
– delete(x, S)? Vorsicht!
• Lösung (Realisierung)
– contains(x, S) = contains(x, a[h(x)]).
– insert(x, S) : a[h(x)] := insert(x, a[h(x)])
– delete(x, S) entsprechend
• Laufzeit: 1 + ((maximale) Größe der Mengen h(x))
bei gleichmäßigem Hashing: 1 + size(S)/m = 1 + α
– Typeset by FoilTEX –
242
Offene Adressierung und Delete
– Typeset by FoilTEX –
243
Lineares Sondieren und Haufen (Clustering)
• naives Löschverfahren a[h(x)] = ⊥ ist nicht korrekt
• Laufzeit von contains und insert ist
O((maximale) Länge eines belegten Abschnitts)
• gelöschte Einträge müssen gesondert markiert werden
• selbst bei gleichmäßiger Hashfunktion
wächst diese Größe stärker als size(S)/m,
denn die Wahrscheinlichkeit dafür, daß ein neuer Eintrag
in ein Intervall I fällt, ist |I|/m.
⇒ es ist zu erwarten, daß große Haufen (cluster) noch
größer werden.
• die so markierten Stellen können beim Einfügen wieder
benutzt werden
• zum Vergleich: bei Chaining: die Wsk, daß ein neuer
Eintrag in eine bestimme Menge fällt, ist 1/m.
⇒ es ist zu erwarten, daß alle Mengen ähnlich groß sind.
– Typeset by FoilTEX –
244
245
Erwartete Laufzeit f. doppeltes Hashing
Offene Adr. mit doppeltem Hashing
• Plan: bei Kollision von x mit y ⇒ verschiedene
Sondierungs-Folgen für x und y ⇒ keine Haufen-Bildung
• Realisierung:
– (linear: für p in [h(x), h(x) + 1, h(x) + 2, . . . ] . . . )
– doppeltes Hashing:
benutze zwei Hashfunktionen h1, h2 und
für p in [h1(x), h1(x) + h2(x), h1(x) + 2h2(x), . . . ] . . .
• unter der Annahme, daß alle Werte von
mod(h1(x) + i · h2(x), m) gleich wahrscheinlich sind,
bestimmen wir die erwartete Laufzeit für eine erfolglose
Suche (oder das Einfügen eines neuen Elementes)
• Kollision für i = 0 mit Wsk 1/α
unter dieser Voraussetzung:
Kollision für i = 1 mit Wsk. 1/α, gesamt Wsk.: 1/α2
P
erwartete Schrittzahl insg. ≤ k≥0(1/α)k = 1/(1 − α)
• damit durch mod(h1(x) + i · h2(x), m) alle Werte in
[0..m − 1] erreicht werden, muß gcd(h2(x), m) = 1 sein.
• zur Erinnerung: Chaining: 1 + α.
zum Beispiel: m prim und 0 < h2(x) < m
Vergleiche Zahlenwerte für α = 1/2, α = 2/3
oder m = 2e und h2(x) ungerade
– Typeset by FoilTEX –
– Typeset by FoilTEX –
246
– Typeset by FoilTEX –
247
Amortisierte Komplexität
Eine Variante des doppelten Hashing
• insert(x, S), beim Sondieren mit p = h1(x) + i · h2(x):
Übersicht
falls a[p] = y mit y 6= ⊥ und y 6= x:
[CLRS] Kapitel 17.4
– bisher: bestimme nächste Sondierungs-Adresse für x
– alternativ (Brent, 1973)
∗ bestimme Ersatz-Adresse q = p + h2(y) für y,
∗ falls a[q] frei ist: a[p] := x; a[q] := y
∗ sonst weiter sondieren für x.
• Motivation
• Definition
• Beispiel: Vergrößerung von Hashtabellen
• Beispiel: Quake Heaps
• vgl. [WW] Algorithmus 9.10 oder [OW] Abschnitt 4.3.4
• Erweiterung dieser Idee: Kuckucks-Hashing (evtl. Ü)
– Typeset by FoilTEX –
248
Motivation
• anzustreben ist α = 1/2 (oder ähnlich, je nach Verfahren)
• # keys(S) vorher unbekannt, α wird überschritten:
re-hashing (alle Elemente in eine Tabelle doppelter
Größe übertragen, mit neuer Hashfunktion)
• Komplexität: 1. das ist teuer, 2. das geschieht selten
250
Die Potential-Methode
• Ziel: Beschreibung der Gesamtkosten einer Folge von
Operationen im schlechtesten Fall.
• Def: Operationen o ∈ O mit tatsächlichen Kosten c(o)
haben amortisierte Kosten ca(o),
P
P
falls ∀s ∈ O∗ : o∈s c(o) ≤ o∈s ca(o)
• Bsp: die amortisierten Kosten für insert mit re-hashing
sind O(1) für jede Folge, die mit leerer Tabelle beginnt.
• tatsächliche Kosten für insert (re-hash bei α > 1/2)
1, 2, 3, 1, 5, 1, 1, 1, 9, 1, 1, 1, 1, 1, 1, 1, 17, 1, . . .
die Partialsummen pi dieser Folge:
1, 3, 6, 7, 12, 13, 14, 15, 24, 25, 26, . . . , 31, 48, 49, . . .
es gilt pi ≤ 3 · i (d.h.: kleiner als die P.S. von 3, 3, 3, . . . )
– Typeset by FoilTEX –
• Ziel: Prioritätswarteschlange mit amortisierten Kosten
insert : O(1), decrease : O(1), extractMin : O(log n)
• Realisierung:
– Liste von vollständig höhen-balancierten Bäumen
mit binären und unären Knoten
– tatsächliche Kosten:
insert : O(1), decrease : O(1), extractMin : O(n)
– Beweis der amortisierten Kosten durch geeignetes
Potential (im wesentlichen: Anzahl der unären Knoten)
• T. M. Chan: Quake Heaps, 2013, http://link.springer.com/
Bsp: P (T ) = 2 · Anzahl der insert seit letztem re-hash
• amortisierte Kosten von Operation o (bzgl. P ):
ca(o) = c(o) + P (nach o) − P (vor o)
P
P
• denn o∈s ca(o) = o∈s c(o) + P (nach s) − P (vor s)
P
P
wenn P (Anfang) = 0, dann o∈s c(o) ≤ o∈s ca(o)
• Bsp: Hashing. P (leer) = 0 und
chapter/10.1007/978-3-642-40273-9_3
– ca(insert) ohne re-hash: 1 + 2(e + 1) − 2e = 3
– ca(insert) mit re-hash: (2e + 1) + 2 · 1 − 2e = 3
W. Mulzer: Erdbebenhaufen, https:
//page.mi.fu-berlin.de/mulzer/notes/ha/quake.pdf
252
– Typeset by FoilTEX –
Strukturelle Invarianten von Quake Heaps
253
extractMin für Quake Heaps
• Q-Heap ist Liste von Bäumen mit Eigenschaften:
– innere Knoten binär oder unär, Schlüssel in Blättern
– alle Blätter gleich tief
– jeder inn. Knoten i hat Verweis auf kleinstes Blatt m(i)
– jedes Blatt b hat Verw. h(b) auf höchstes i mit m(i) = b
• insert(x, S) in O(1):
ein neuer Baum (Blatt) mit Schlüssel x der Höhe 0
• extractMin(S):
– bestimme Wurzel w, für die m(w) minimal ist
Kosten: O(Anzahl Bäume)
– lösche Knoten auf Pfad von w zu m(w),
dadurch entstehen neue Bäume,
Kosten: O(Höhe).
– Operat. zum Reduzieren der Baum-Anzahl u. -Höhe
• Reduktion der Anzahl: solange es zwei Bäume gleicher
Höhe h gibt: fasse diese zu einem Baum (mit binärer
Wurzel) der Höhe h + 1 zusammen
Kosten: O(Anzahl Bäume vorher),
Resultat: O(Höhe + log n) Bäume
• decrease(x, v, S) in O(1) (mit x in Blatt b):
– Eintrag in b wird auf v verringert
– falls h(b) keine Wurzel ist: h(b) wird aus seinem
Vorgänger entfernt (dieser ist binär, wird unär)
dadurch entsteht neuer Baum mit h(b) als Wurzel
– Typeset by FoilTEX –
251
Amortisierte Analyse von Quake Heaps
• Potentialfunktion P : Datenstrukur → N
– Typeset by FoilTEX –
249
Def. und Bsp.: Amortisierte Komplexität
• wie wählt man die Größe einer Hashtabelle?
– Größe muß vor erster Operation fixiert werden,
kann danach nicht geändert werden
– zu klein ⇒ hoher Belegungs-Faktor α, hohe Laufzeiten
(viele Kollisionen), Überlauf (keine freien Plätze)
– zu groß ⇒ Speicher verschenkt (viele freie Plätze)
– Typeset by FoilTEX –
– Typeset by FoilTEX –
254
– Typeset by FoilTEX –
255
Potential für Quake Heaps
Logarithmische Höhe und Erdbeben
• P (H) = K + 2 · B + 4 · U mit
• mit ni = Anzahl der Knoten aller Bäume in Höhe i
(n0 = Anzahl der Blätter = Anzahl der Schlüssel)
soll immer gelten: ∀i : ni+1 ≤ 3/4 · ni.
– B = Anzahl der Bäume,
– K = Anzahl aller Knoten, U = . . . der unären Knoten
• ⇒ die Höhe jedes Baumes ist dann ≤ log4/3 n ∈ O(log n)
• Erdbeben“ (quake): falls ∃i : ni+1 > 3/4 · ni,
”
dann i0 := das kleinste solche i,
lösche alle Knoten der Höhe > i0.
Kosten: Anzahl dieser Knoten (= D)
• insgesamt: c(insert) = O(log n + Anzahl Bäume + D)
was ist die passende Potentialfunktion, für die
ca(insert) = O(log n) und ca(insert), ca(decrease) ∈ O(1)?
– Typeset by FoilTEX –
256
– insert: c = 1, ∆(K) = 1, ∆(B) = 1, ∆(U ) = 0,ca = 4
– decrease: . . .
– extractMin: c = O(log n + B0 + D), ca = O(log n)
∗ Pfad löschen: ∆(K + B) < 0, ∆(U ) ≤ 0
∗ Bäume zusammenfassen:
∆(B) = log n − B0, ∆(K) = −∆(B), ∆(U ) = 0
∗ Erdbeben: ∆(K) ≤ 0, ∆(B) ≤ ni, ∆(U ) ≤ −ni/2
– Typeset by FoilTEX –
257
Aufgabe 11.1 (Hashing)
Übungsserie 11 für KW 25
Für
Aufgabe 11.A (autotool: Hashing)
• (1 P) Hashing mit linearem Sondieren,
• Hashing mit Verkettung
• (1 P) doppeltes Hashing,
• Hashing mit linearem Sondieren
• (2 P) doppeltes Hashing in der Variante von Brent (siehe
Skript bzw. dort angegebene Literatur)
• doppeltes Hashing
– Typeset by FoilTEX –
• ca(o) so festlegen, daß ca(o) ≥ c(o) + ∆(P ) für
den Algorithmus an einem Beispiel an der Tafel vorführen.
258
Aufgabe 11.2 (Kuckucks-Hashing)
– Typeset by FoilTEX –
259
Aufgabe 11.3 (Amortisierte Analyse)
engl. cuckoo hashing
Wiederholung (1. Semester):
• (1 P) Zitieren Sie die wissenschaftliche Primär-Quelle
(die referierte Publikation der Erfinder) für diesen
Algorithmus (Autor, Titel, Jahr, Ort (Konferenz))
• Schlange und Keller sind Listen mit beschränktem Zugriff:
• Ein Keller (stack) hat die Operationen push (Einfügen)
und pop (Extrahieren, beides am linken Ende).
• (1 P) Geben Sie die Invariante des Verfahrens an.
Welche Laufzeit der Operationen (contains, insert) ergibt
sich daraus?
Wo ist der Laufzeit-Unterschied zu den in der VL
betrachteten Verfahren?
Die Schlange S soll durch zwei Keller L, R implementiert
werden.
• (2 P) Führen Sie den Algorithmus an einem Beispiel an
der Tafel vor.
– Typeset by FoilTEX –
• Die Warteschlange (queue) (ohne Prioritäten) hat die
Operationen enqueue (Einfügen am rechten Ende) und
dequeue (Extrahieren am linken Ende)
• Invariante: der Inhalt von s ist append(L, reverse(R)).
260
• leere Schlange: L = R = leerer Keller.
– Typeset by FoilTEX –
261
• (2 P) Geben Sie eine Potentialfunktion P an, bezüglich
derer die amortisierten Kosten von enqueue und
dequeue O(1) sind.
• enqueue(x, S) = push(x, R)
• dequeue(S) =
1. falls L leer, dann: solange R nicht leer: push(pop(R), L)
2. pop(L)
Geben sie P (S0), P (S1), . . . für die o.g. Operationsfolge
an.
Aufgaben:
• (1 P) Führen Sie
S1 = enqueue(3, S0), S2 = enqueue(4, S1), S3 =
dequeue(S2), S4 = enqueue(5, S3), S5 = dequeue(S4) vor.
• (1 P) welches sind die tatsächlichen Kosten von enqueue
und dequeue (als Funktion von |L| und |R|)? Die Kosten
von push und pop sind 1.
– Typeset by FoilTEX –
262
– Typeset by FoilTEX –
263
Graphen: Eigenschaften, einfache
Algorithmen
Aufgabe 11.4 (Zusatz) (Quake Heaps)
• (2 P) beschreiben Sie das Verhalten von QH für:
Einfügen mehrerer Schlüssel, dann wiederholtes
extractMin, bis der Heap leer ist.
Überblick
Welche Komplexität hat dieses Sortierverfahren?
Geben Sie den Verlauf des Potentials an.
• (2 P) Geben Sie eine Operationsfolge an, die mit leerem
Heap beginnt und ein Erdbeben enthält.
Geben Sie den Verlauf des Potentials an.
• (2 P) Das Potential im Skript (übernommen aus zit. Skript
von Mulzer) ist anders als das im Artikel von Chan. Ist der
Unterschied wesentlich?
– Typeset by FoilTEX –
264
Motivation, Definition, Beispiele
• G = (V, E), (ungerichtet) E ⊆
V
2
, (gerichtet) E ⊆ V
Andreas Brandstädt: Graphen und Algorithmen, Teubner
1994, https://link.springer.com/book/10.1007/
978-3-322-94689-8
Hansjoachim Walther, Günther Nägler: Graphen —
Algorithmen — Programme, Fachbuchverlag Leipzig 1987
• Bezeichnungen, Eigenschaften
• Datenstrukturen zur Repräsentation von Graphen
• Tiefensuche, Breitensuche
• topologisches Sortieren, Zusammenhangskomponenten
– Typeset by FoilTEX –
265
Spezielle Graphen, Graph-Operationen
2
• Graph = zweistellige Relation (ungerichtet: symmetrisch)
• Relationen (und damit auch Graphen) sind fundamental
für Prädikatenlogik, Modellierung, Informatik.
• Graphen, mit denen derzeit viel Geld verdient wird:
– das WWW (Knoten: URLs; Kanten: Verweise)
– das sogenannte soziale Netzwerk
(Knoten: Personen, genauer: Werbe-Ziele;
Kanten: sogenannte Freundschaften)
• Graphentheorie: Eulerkreise (1736), Landkartenfärbung
(Kempe 1879) . . .
• Graph-Algorithmen: Anwendung von Datenstrukturen
– Typeset by FoilTEX –
266
• Spezielle Graphen:
– unabhängiger Graph In (n Knoten, keine Kanten)
– vollständiger Graph (Clique) Kn (n Knoten, alle Kanten)
– Pfad Pn (n Knoten, n − 1 Kanten)
– für n ≥ 3: Kreis Cn (n Knoten, n Kanten)
• Operationen:
– Komplement c(V, E) = (V, E) = (V, V2 \ E)
– disjunkte Summe (V1, E1) ∪ (V2, E2) = (V1 ∪ V2, E1 ∪ E2)
– Verkettung (join) G1 + G2 = c(c(G1) ∪ c(G2))
• weitere spezielle Graphen:
– vollständig bipartit Ka,b = Ia + Ib,
– Stern K1,b, Rad K1 + Cn
– Typeset by FoilTEX –
Eigenschaften von Graphen
267
Verbindungen, Abstände
• u ∼G v: u und v sind verbunden in G,
falls es in G einen Pfad u → . . . → v gibt
– G ungerichtet: ∼G ist eine Äquivalenzrelation auf V .
– Die Äquivalenzklassen V /∼G heißen
Zusammenhangskomponenten
– G heißt zusammenhängend, wenn |V / ∼G | = 1
• Knotenzahl: |V (G)|, n; Kantenzahl: |E(G)|, m
• G ungerichtet: Nachbarn G(u) := {v | {u, v} ∈ E(G)}
mit verkürzter Notation für Kanten: {v | uv ∈ E(G)}
• G gerichtet: Nachfolger G(u) := {v | (u, v) ∈ E(G)}
Vorgänger: G−(u), mit Spiegelbild G− := (V, E −).
• Grad eines Knotens degG(u) = #G(u)
Minimalgrad: δ(G) = min{degG(u) | u ∈ V }
Maximalgrad: ∆(G) = max{degG(u) | u ∈ V }
• G ist r-regulär, falls ∀u ∈ V : degG(u) = r
• Bsp: Petersen-Graph ( 52 , {uv | u ∩ v = ∅}) ist 3-regulär.
(Das kann man ohne Zeichnung nachprüfen.)
• distG(u, v) := die Länge (d.h. Anzahl der Kanten)
eines kürzesten Pfades in G von u nach v.
(+∞, falls es keinen solchen gibt)
– diese Def. gilt für ungerichtete und für gerichtete G
– Durchmesser diam(G) := maxu,v∈V distG(u, v)
– Radius rad(G) := minu∈V maxv∈V distG(u, v)
– Typeset by FoilTEX –
– Typeset by FoilTEX –
268
Die Größe spezieller Teilgraphen
Repräsentationen von Graphen
• Unabhängigkeitszahl α(G):
die maximale Größe der unabhängigen Teilmengen in G
• Annahme: direkter Zugriff für Knoten: V = [1, 2, . . . , n]
• Aufgabe: (effiziente) Repräsentation von E
– schneller Zugriff: Adjazenz-Matrix
a : V 2 → B mit uv ∈ E ⇐⇒ a[u, v] = true
– wenig Platz: Adjanzenz-Listen:
für jeden u ∈ V : die Menge G(u) repräsentiert als
(einfach verkettete) Liste
• Cliquenzahl ω(G):
die maximale Größe der vollständigen Teilmengen in G
• Taillenweite (girth) g(G):
die minimale Größe der Kreise in G.
• wir verwenden grundsätzlich die AL-Darstellung,
• Übungsaufgaben: bestimme alle im Skript gennanten
Parameter für alle im Skript genannten Graphen.
wenigstens zur Repräsentation der Eingabe von
Graphalgorithmen
g(Petersen), χ(Petersen), ω(K3,3), rad(C5), α(C7), . . .
– Typeset by FoilTEX –
269
(intern könnten diese andere Datenstrukturen benutzen)
270
– Typeset by FoilTEX –
271
Das Durchlaufen von Graphen (Schema)
Breitensuche (breadth first search, BFS)
• – Eingabe: Graph G = (V, E)
– Ausgabe: Folge von Knoten s ∈ V ∗, Relation p auf V
• done := ∅; todo := {v0}; p[v0] = ⊥; while todo 6= ∅
wähle v ∈ todo (z.B. den ältesten oder den neuesten)
todo := todo \ {v}; done := done ∪ {v}
für alle u ∈ G(v) \ done : todo := todo ∪ {u}; p[u] := v
• v ∈ done ⇐⇒ c[v] = schwarz, (todo: grau, sonst: weiß)
• Invarianten/Eigenschaften:
– p ist die Vorgänger-Relation eines Baumes
– jedes x ∈ todo ∪ done ist von v0 aus erreichbar
durch Weg P (x) : v0 → . . . → p[p[x]] → p[x] → x
– jeder Nachbar von x ∈ done ist schwarz oder grau
– schließlich: done = die von v0 erreichbaren Knoten,
– Typeset by FoilTEX –
272
Tiefensuche (depth first search, DFS)
• Bezeichnung d(x) := |P (x)| oder +∞, falls x weiß
Satz: ∀x : d(x) = distG(v0, x)
• Beweis:
Inv.: distG(v0, x) ≤ d(x), weil P (x) ein Weg v0 →∗ x ist.
Inv.: todo = [x1, . . . , xk ] ⇒ d(x1) ≤ . . . ≤ d(xk ) ≤ d(x1) + 1.
Zeige Satz durch Induktion über distG(v0, x)
• Laufzeit von BFS(G) ist O(n + m) = O(|V | + |E|).
Beweis: für jeden Knoten und für jede Kante O(1).
– Typeset by FoilTEX –
• ordne F = DFS(G) durch zeitliche Reihenfolge der
Bäume sowie in jedem Knoten zeitliche R. der Kinder
F = [t1, . . . , tk ] mit ti ∈ (V )
• alternative Formulierung mit Rekursion: DFS1(x) :=
Tree(V ) = {Branch(v, [t1, . . . , tk ]) | v ∈ V, ti ∈ Tree(V )}
c[x] := grau;
for y ∈ G(x): if y ∈ weiß then {p[y] := x; DFS1(y); }
c[x] := schwarz
• die DFS-Reihenfolge von G
• Erweiterung gegenüber Schema: besuche alle Knoten
DFS(G) : while (weiß 6= ∅) { wähle v0 ∈ weiß; DFS1(v0) }
• DFS(G) = (V, {(p[x], x) | x ∈ V, p[x] 6= ⊥})
ist der DFS-Wald von G
(eine disjunkte Vereinigung von Bäumen)
ist die Preorder-Reihenfolge von F , Notation <pre(F )
(Reihenfolge der Entdeckung = der Graufärbung)
• in Anwendungen wird auch die Postorder-Reihenfolge
von F benutzt, Notation <post(F )
(Reihenfolge der Erledigung = der Schwarzfärbung)
274
– Typeset by FoilTEX –
DFS-Klassifikation der Kanten
• Bezeichnungen:
{u, v} ist ungerichtete Baum-, Rückwärts-, Querkante
⇐⇒ (u, v) oder (v, u) ist Baum-, . . . -kante.
Baum-Kante, falls x →F y
Rückwärts-Kante, falls y →∗F x
Vorwärts-Kante, falls x →≥2
F y
Quer-Kante, sonst.
• Satz: für ungerichtete Graphen G = (V, E):
jedes e ∈ E ist Baum-Kante oder Rückwärts-Kante
• Satz: Mit F = DFS(G) gilt: (x, y) ∈ E(G) ist
bezüglich F = DFS(G).
– Baum- oder Vorwärtskante, falls x <pre(F ) y ∧ y <post(F ) x
– Rückwärtskante, falls y <pre(F ) x ∧ x <post(F ) y
– Querkante, falls y <pre(F ) x ∧ y <post(F ) x
(Der Fall x <pre(F ) y ∧ x <post(F ) y kommt nicht vor.)
– Typeset by FoilTEX –
(d.h., es gibt keine Querkanten)
• Beweis: falls xy Querkante, (x, y) gerichtete Querkante,
dann nach Def. y <post(F ) x,
aber Kante (y, x) verlangt x <post(F ) y, Widerspruch.
276
– Typeset by FoilTEX –
Gerichtete kreisfreie Graphen (DAG)
277
Topologisches Ordnen
• Bezeichnung: DAG (directed acyclic graph):
• Def: eine totale Ordnung (V, ≤) heißt topologische
Ordnung für gerichteten Graph G = (V, E),
falls ∀(x, y) ∈ E : x < y.
gerichteter Graph ohne gerichteten Kreis
• Satz: Für jeden gerichteten Graphen G:
G ist DAG ⇐⇒ DFS(G) erzeugt keine Rückwärtskanten
• Beweis:
• Anwendung: V : Aufgaben, E: Abhängigkeiten,
(<): Ausführungsreihenfolge
• Satz: G besitzt topologische Ordnung ⇐⇒ G ist DAG.
⇒“: (indirekt)
”
falls (x, y) Rückwärtskante, dann Kreis y →∗F x → y
• Beweis:
⇒“: (indirekt) betrachte Kreis C in G und (V (C), ≤)
”
⇐“: (direkt) mit F = DFS(G) ist >post(F ) eine
”
topologische Ordnung.
⇐“: (indirekt) falls Kreis C in G,
”
y ∈ V (C) mit y minimal bzgl. <pre(F ) und (x, y) ∈ E(C).
Dann y →∗T x und (x, y) wird Rückwärtskante
– Typeset by FoilTEX –
275
DFS für ungerichtete Graphen
• Def.: Mit F = DFS(G): (x, y) ∈ E(G) heißt
–
–
–
–
273
Bezeichnungen für DFS-Bäume und -Ordnung
• implementiere todo als Keller (stack):
– Extrahieren und Einfügen am linken Ende
– Typeset by FoilTEX –
• implementiere todo als Warteschlange (queue):
– Extrahieren von v am linken Ende,
– Einfügen aller u ∈ G(v) am rechten Ende.
278
– Typeset by FoilTEX –
279
Minimal-Gerüste
Definition Minimalgerüst
Überblick
• Def. Ein Baum T heißt Gerüst von G, falls V (T ) = V (G).
• Satz: G ist zusammenhängend ⇐⇒ G besitzt Gerüst.
• Def. Minimalgerüst,
• Def. ein (kanten-)gewichteter Graph
• Algorithmus von Kruskal
• ADT Mengensystem
• Implementierung Mengensystem durch disjoint-set-forest
ist ein Paar (G, w) mit w : E(G) → R
P
• Def. für H ⊆ G: w(H) = {w(e) | e ∈ E(H)}
• Def. T ist ein Minimalgerüst (MST) für (G, w),
falls w(T ) = min{w(T 0) | T 0 ist Gerüst für G}
• Motivation: Verbindungen von Bestandteilen technischer
Systeme (Rohrleitungen, Straßen, Leiterbahnen,. . . )
– Typeset by FoilTEX –
280
– Typeset by FoilTEX –
281
Algorithmus (Eigenschaften, Realisierungen)
Algorithmus (Schema)
• schrittweise Konstruktion eines MST durch Hinzufügen
von sicheren Kanten (die die Invariante nicht verletzen)
• in jedem Fall gilt
– Anfang: (V, A) hat |V | Komponenten der Größe 1
– Schluß: (V, A) ist eine Komponente der Größe |V |.
• // Invariante: ∃T : (V, A) ⊆ T und T ist MST für G
A := ∅ ; while A ist kein Gerüst
wähle sichere Kante e ∈ E(G); A := A ∪ {e} • Algorithmus von Kruskal:
C: eine beliebige Komponente
• Satz: A erfüllt Invariante,
C eine Zsgh-Komponenten von (V, A),
• Algorithmus von Prim:
e eine leichteste Kante zw. C und V \ C.
zusätzliche Invariante: Kanten von A bilden einen Baum.
Dann ist e sicher.
C: die Knotenmenge dieses Baums
Beweis: in T gibt es eine Kante f zw. C und V \ C.
Dann ist T \ {f } ∪ {e} auch ein MST für G.
– Typeset by FoilTEX –
282
– Typeset by FoilTEX –
Algorithmus von Kruskal (1956)
Union-Find-Strukturen
• Plan: e := eine leichteste Kante, die eine beliebige
Komponente C von A mit V \ C verbindet
• [OW] Kapitel 6.2, [CLR] Kapitel 21
• abstrakter Datentyp zur dynamischen Repräsentation
von Äquivalenzklassen einer Relation R
– Union(x, y): R := R ∪ {(x, y)}
– equiv(x, y): gilt x ∼R y mit (∼R) = (R ∪ R−)∗ ?
• Realisierung:
– E 0 := sortiere E nach aufsteigendem Gewicht
– für xy aus E 0: falls x 6∼A y, dann A := A ∪ {xy}.
• Realisierung mittels
– find(x): kanonischer Repräsentant von [x]∼R ,
so daß ∀x, y : equiv(x, y) ⇐⇒ find(x) = find(y)
• Kosten:
– Θ(m log m) für Sortieren von E
– m mal feststellen, ob x ∼A y
für einen solchen Test haben wir O(log n) Zeit,
ohne die Laufzeit asymptotisch zu erhöhen.
(beachte: n − 1 ≤ m wg. Zusammenhang von G)
– Typeset by FoilTEX –
283
• Beispiel für kanonische Repräsentation:
– Menge N × (N>0),
Äq.-Relation (x1, y1) ∼ (x2, y2) ⇐⇒ x1 · y2 = x2 · y1,
Repr. von [(x, y)]∼ ist (x/g, y/g) mit g = gcd(x, y)
284
Mengensysteme (DSF, disjoint set forest)
– Typeset by FoilTEX –
285
Effiziente Implementierung von Union in DSF
• zur Implementierung von Union / find
• Basis: Union(x, y) :
– find(x): die Wurzel des Baumes, der x enthält.
– Union(x, y): find(x) wird Kind von find(y).
s := find(x); t := find(y); if s 6= t then p[s] := t
• Realisierung des Baumes durch Rückwärts-Zeiger (jeder
Knoten auf Vorgänger) in Array p : V → V ∪ {⊥}
find(x) : if p[x] = ⊥ then x else find(p[x])
Satz: ∀x : find(x) ist eine Wurzel
• Verbesserung:
. . . if height(s) < height(t) then p[s] := t else p[t] := s
• dann gilt ∀x : height(x) ≤ log(size(x))
• height(x) in Array H : V → N abspeichern.
• Union(x, y) :
Aktualisieren: p[t] := s; H[s] := max{H[s], 1 + H[t]}
s := find(x); t := find(y); if s 6= t then p[s] := t
korrekt, aber es können unbalancierte Bäume entstehen.
– Typeset by FoilTEX –
286
– Typeset by FoilTEX –
287
Effiziente Implementierung von find in DSF
Zusammenf./Ausblick: MST-Algorithmen
• Basis: find(x) : if p[x] = ⊥ then x else find(p[x])
• Algorithmus von Kruskal (1956) Laufzeit
O(m log m) ⊆ O(m log n)
• Verbesserung: Pfad-Kompression:
• Der Algorithmus von Prim (1957) (und Jarnik, 1930) zur
Bestimmung eines MST
– Wurzel s für x bestimmen wie bisher
– für jeden Knoten y auf Pfad von x zu s: p[y] := s
– ist ähnlich zu später behandeltem Algorithmus von
Dijkstra zur Bestimmung kürzester Pfadlängen,
– wird deswegen danach und nur kurz (oder als
Übungsaufgabe) behandelt.
– hat Laufzeit O(n log n + m)
• Berechnung von H[] wird nicht geändert
– Bestimmung der tatsächlichen Höhe ist zu teuer
– Pfadverkürzungen wirken sich nicht auf H aus
– es gilt ∀x : height(x) ≤ H[x]
• insgesamt wird Laufzeit deutlich verbessert
(auf o(log∗(n)) ⊂ o(log n), Details siehe Literatur.)
– Typeset by FoilTEX –
288
– Typeset by FoilTEX –
289
Aufgabe 12.1 (vorrechnen)
Übungsserie 12 für KW 26
Algorithmen an der Tafel ausführen, ggf. auch als Teil der
Diskussion einer der folgenden Aufgaben.
Aufgabe 12.A (autotool)
• Breitensuche
• (1 P) Breitensuche
• Tiefensuche
• (1 P) Tiefensuche
• Minimalgerüst
• (1 P) Algorithmus von Kruskal zur Bestimmung eines
Minimalgerüstes
• (1 P) Union/Find-Operationen in Disjoint Set Forest
– Typeset by FoilTEX –
290
– Typeset by FoilTEX –
291
Aufgabe 12.3 (Tiefensuche)
Aufgabe 12.2 (Graph-Eigenschaften)
• (2 P) Sei DFS(G) = [. . . , t1, . . . , t2, . . . ] der
Tiefensuchwald eines gerichteten Graphen G (d.h., der
Baum t1 wird vor dem Baum t2 durchlaufen).
• (1 P) Bestimmen Sie Durchmesser und Radius des
Petersen-Graphen.
• (1 P) Geben Sie Algorithmen zur Bestimmung von
Durchmesser und Radius von Graphen an (= Aufgabe
[WW] 4.15).
Geben Sie ein Beispiel an, bei dem G eine Kante von t2
nach t1 enthält.
• (2 P) Wenn rad(G) = r bekannt ist, z.B. r = 3, welches
sind der minimale und der maximale Wert von diam(G)?
Geben Sie Graphen an, die diese Werte erreichen.
Begründen Sie, daß G niemals eine Kante von t1 nach t2
enthält.
• (2 P) Seien t ∈ DFS(G), Branch(x, [. . . , s1, . . . , s2, . . . ])
Teilbaum von t und Knoten y ∈ s1, z ∈ s2.
Begründen Sie: falls y →∗G z, dann y →∗G x.
Hinweis: benutzen Sie <post(F )
– Typeset by FoilTEX –
292
– Typeset by FoilTEX –
293
Kürzeste Wege
Aufgabe 12.4 (Minimalgerüste)
• (1 P) Lösen Sie Ihre Instanz der autotool-Aufgabe
Minimalgerüst durch den Algorithmus von Kruskal.
Überblick
WW 10
• (3 P) [CLR] Problem 23-4 (Alternative Algorithmen . . . )
• von einem Knoten: Algorithmus von Dijkstra WW 5.3
• zwischen allen Knoten: Algorithmus von Floyd und
Warshall
– Typeset by FoilTEX –
294
– Typeset by FoilTEX –
295
Definitionen
Algorithmus von Dijkstra
• Plan: Anpassung der Breitensuche
– Spezifikation: Länge → Gewicht, |P | → w(P )
– Implementierung: Warteschlange (queue) →
Prioritätswarteschlange (heap)
• Spezifikation: kürzeste Wege von einem Knoten
zu allen anderen (single source shortest paths)
– Eingabe:
∗ kantengewichteter Graph (G, w), Gewichte ≥ 0,
∗ Knoten s ∈ V (G)
– Ausgabe: Funktion (Array)
d : V → R ∪ {∞} mit d[t] = dist(G,w)(s, t)
• c[·] := weiß; d[·] := ∞; H := {(s, 0)}; c[s] := grau; d[s] := 0
while grau 6= ∅
x := extractMin(H); c[x] := schwarz
for y ∈ G(x) \ schwarz
d[y] := min{d[y], d[x] + w(x, y)}
if c[y] = weiß then {insert(y, d[y], H); c[y] := grau}
else if c[y] = grau then decrease(y, d[y], H)
• Bezeichnungen:
– dist(G,w)(s, t) := min{w(P ) | P ist Pfad von s nach t}
P
– w(P ) = {w(e) | e ∈ P } (wurde schon definiert)
– das ist sinnvolle Verallgemeinerung von distG(s, t)
– Typeset by FoilTEX –
• Inv: ∀v : dist(s, v) ≤ d[v], ∀v ∈ schwarz : dist(s, v) = d[v]
296
Algorithmus von Dijkstra: Korrektheit
– Typeset by FoilTEX –
297
Algorithmus von Dijkstra: Laufzeit
• Kosten für die Bestandteile des Algorithmus:
• ∀v : dist(s, v) ≤ d[v]:
wenn d[y] := d[x] + w(x, y), dann gibt es nach Induktion
einen Weg mit diesen Kosten von s zu y (über x).
– Verwaltung der Knotenfarben (schwarz, grau, weiß)
durch direkten Zugriff (Array) in O(1)
– effiziente Prioritätswarteschlange (z.B. Quake Heap)
∗ n mal extractMin, jeweils O(log n)
∗ m mal insert oder decrease, jeweils O(1)
• ∀v ∈ schwarz : dist(s, v) = d[v]
Beweis indirekt: betrachte erstes v, für das direkt vor
Schwarz-Färbung gilt dist(s, v) < d[v].
dann gibt es Pfad P : s →∗ v mit Kosten < d[v].
b := der erste nicht schwarze Knoten auf P ,
a := Vorgänger von b (a ∈ schwarz, b ∈ grau)
nach Induktion d[a] = dist(s, a)
nach Konstruktion w(P ) ≥ d[b] ≥ d[v], Widerspruch.
• Gesamtkosten: O(n log n + m)
• Bemerkung: hier wurde ∀e : w(e) ≥ 0 benutzt.
– Typeset by FoilTEX –
298
Algorithmus von Dijkstra: über den Autor
299
Kürzeste Wege für alle Knotenpaare
• Edsger W. Dijkstra, 1930–2002
• ACM Turing Award 1972, http://amturing.acm.
org/award_winners/dijkstra_1053701.cfm
• Manuskripte:
http://www.cs.utexas.edu/users/EWD/
Lesetipp: EWD 1305 Answers to questions from students
of Software Engineering
– Typeset by FoilTEX –
– Typeset by FoilTEX –
300
• [CLR] Kapitel 25, [OW] 9.5.3, [WW] 8.2
• Spezifikation: (all pairs shortest paths)
– Eingabe:
kantengewichteter Graph (G, w), Gewichte ≥ 0,
– Ausgabe: Funktion (Array)
d : V 2 → R ∪ {∞} mit d[s, t] = dist(G,w)(s, t)
• mögliche Implementierung:
for s ∈ V : Algorithmus von Dijkstra mit Start s
Kostet O(n2 log n + nm),
erfordert schnelle (komplizierte) PQ-Implementierung
• betrachten hier einfache Algorithmen in O(n3)
• auch als Wiederholung zu dynamischer Programmierung
– Typeset by FoilTEX –
301
Der tropische Halbring
Matrizen über Halbringen
• auf der Menge T = R ∪ {+∞} definieren die Operationen
– ⊕: Minimum (neutrales Element +∞)
– ⊗: Addition (neutrales Element 0)
einen Halbring (Monoid (T, ⊕, +∞), Monoid (R, ⊗, 0),
Distributivgesetz)
• Bezeichnung: Matn(S): Menge der n × n-Matrizen über S
• T = tropischer Halbring, zu Ehren des brasilianischen
Mathematikers Imre Simon (1943–2009)
• dieser Halbring paßt zu Minimierung von Wegen, denn
– ⊗: Reihenschaltung, Addition entlang eines Weges
– ⊕: Parallelschaltung, Auswahl eines kürzesten
– ∞: kein Weg; 0: ein Weg der Länge 0
– Typeset by FoilTEX –
302
• Satz: S ist Halbring ⇒ Matn(S) ist Halbring, mit
– ⊕Mat(S) ist die übliche Matrixaddition
(A ⊕Mat(S) B)i,j = Ai,j ⊕S Bi,j , neutral: Null-Matrix
– ⊗Mat(S) ist übliche Matrixmultiplikation
(A ⊗Mat(S) B)i,j = (Ai,1 ⊗S B1,j ) ⊕S · · · ⊕S (Ai,n ⊗S Bn,j )
neutral: Einheitsmatrix
∞ ∞
0 ∞
• Bsp. in Mat2(T): 0 =
,1=
,
∞ ∞
∞ 0
2 ∞
1 3
2 ∞
1 3
⊕
= ...,
⊗
= ...
3 0
2 ∞
3 0
2 ∞
– Typeset by FoilTEX –
303
Matrizen von Weg-Kosten
Berechnung von Matrix-Potenzen
• gewichteter Graph (G, w) mit V (G) = {1, . . . , n}
ist eine tropische Matrix W
mit Wx,y = if (x, y) ∈ E then w(x, y) else ∞
• Berechnung von M n für M ∈ Matn(S) durch
R := 1; for k ∈ [1, . . . , n] {R := R ⊗ M }
• für die Potenzen von W gilt:
(W k )x,y = min. Kosten aller Wege der Länge k von x zu y
• die all-pairs-shortest-paths-Matrix zu W ist demnach
W ∗ = 1 ⊕ W ⊕ W 2 ⊕ . . . (unendl. Summe in Matn(T))
• Berechnung durch
R := M ; for k ∈ [1, . . . , dlog2 ne] {R := R ⊗ R}
kostet log n · n3 Operationen.
• mittels dynamischer Programmierung ist O(n3) erreichbar
• alle Kosten ≥ 0 ⇒ kürzeste Wege haben < n Kanten
W ∗ = 1 ⊕ W ⊕ W 2 ⊕ · · · ⊕ W n−1 (endliche Summe)
= (1 ⊕ W )n−1 (Addition ist komm. und idempotent)
– Typeset by FoilTEX –
kostet n · n3 Operationen.
304
Algorithmus von Floyd und Warshall
– Typeset by FoilTEX –
305
Übungsserie 13 für KW 27
• Eingabe: Kostenmatrix W ∈ Matn(T), Elemente ≥ 0
Ausgabe: Matrix der kürzesten Wege W ∗ = (1 ⊕ W )n−1
Allgemeines
• Mo. 7:30 N001 Vorlesung (= Zusammenfassung)
• Implementierung: berechne Folge M0, . . . , Mn−1 = W ∗
mit Mh[x, y] := minimale Kosten aller Wege
x = p0 → p1 → · · · → pk = y mit p1, . . . , pk−1 ∈ {1, . . . , h}
• Mo. 12:00 G119 Hörsaal-Übung
(Serie 13 sowie ggf. frühere Zusatzaufgaben)
– h ist Parameter der dynamischen Programmierung
– M0 := 1 ⊕ W (Wege haben Länge 0 oder 1)
– Mh+1[x, y] := Mh[x, y] ⊕ Mh[x, h + 1] ⊗ Mh[h + 1, y]
(Fallunterscheidung: Weg von x nach y benutzt h + 1,
dann höchstens einmal, oder gar nicht)
• Do. oder Fr. (online-Stundenplan beachten!)
Hörsaal-Übung (Prüfungsvorbereitung) (Hr. Wenzel)
Fragen, die dann diskutiert werden sollen, sind Herrn
Wenzel vorher per Mail mitzuteilen.
• Kosten: O(n )
3
• R. Floyd, CACM 5(6) 1962; S. Warshall, JACM 9(1) 1962
– Typeset by FoilTEX –
306
Aufgaben 13.A (autotool)
– Typeset by FoilTEX –
307
Aufgabe 13.1 (Algorithmus von Prim)
Der Algorithmus von Prim zur Bestimmung eines
Minimalgerüstes entsteht aus dem Algorithmus von Dijkstra
zur Bestimmung kürzester Pfade, indem die Anweisung
d[y] := min{d[y], d[x] + w(x, y)} durch die Anweisung
d[y] := min{d[y], w(x, y)} ersetzt wird.
Jedesmal, wenn dort w(x, y) < d[y], notieren wir x als
Vorgänger von y (in einem Array p durch die Zuweisung
p[y] := x). Diese Vorgänger-Zuordnung kann wechseln,
solange y grau ist.
Die Vorgängerkanten bilden am Ende des Algorithmus
einen Baum, der ein Minimalgerüst für (G, w) ist.
zu Algorithmen von
• Dijkstra,
• Prim,
• Floyd und Warshall
Das sind dann nicht unbedingt Pflicht-Aufgaben. Nutzen
Sie trotzdem diese Gelegenheit, sich diese Algorithmen
vom autotool vorführen zu lassen.
• (1 P) Führen Sie den Algorithmus von Prim für Ihre
Instanz der autotool-Aufgabe Minimalgerüst durch.
– Typeset by FoilTEX –
308
• (2 P) Begründen Sie: jedesmal, wenn ein x als Minimum
extrahiert wird, dann ist die Kante {x, p[x]} eine sichere
Kante für den Schnitt zwischen C = schwarz und V \ C.
(Das ist [WW] Aufgabe 5.6)
– Typeset by FoilTEX –
309
Aufgabe 13.2 (Algorithmus von Dijkstra)
• (2 P) Wie unterscheidet sich asymptotisch die
Komplexität einer Implementierung des Algorithmus von
Dijkstra mit fast vollständig balancierten binären Heaps
von einer Implementierung mit Quake Heaps
– für Graphen mit |E| ∈ Θ(|V |2) (sogenannte dichte
Graphen)?
– für Graphen mit |E| ∈ Θ(|V |) (sogenannte dünne
Graphen)?
• (2 P) [CLR] Übung 24.3–8. Was passiert für W = 1? Für
W = 2? Zusatz : 24.3–9.
– Typeset by FoilTEX –
310
– Typeset by FoilTEX –
311
Aufgabe 13.3 (all pairs shortest paths)
• (2 P) Für jede der drei im Skript angegebenen Variante
der Berechnung der Matrix W ∗: kann die Rechnung
abgekürzt (d.h., die Komplexität verringert) werden, falls
die kürzesten Pfade nur von einem Knoten aus zu
bestimmen sind?
• (2 P) Welche Information über G enthält die Matrix A∗,
wenn A die Adjazenzmatrix des Graphen G ist und der
zugrundeliegende Halbring B (Wahrheitswerte) mit den
Operationen ⊕ = ∨ und ⊗ = ∧?
– Typeset by FoilTEX –
Weitere Beispiele zu Graphen und
-Algorithmen
Färbungen (Definition, Beispiele)
• eine (konfliktfreie) c-Färbung von G
ist Abb. f : V → {1, . . . , c} mit ∀uv ∈ E : f (u) 6= f (v)
• chromatische Zahl χ(G) = min{c | G hat eine c-Färbung}
• Bsp: χ von: P5, C5, I5, K5, K3,3, Petersen.
312
– Typeset by FoilTEX –
313
Chromatische Zahl und Maximalgrad
Färbungen (Geschichte)
• Satz: χ(G) ≤ ∆(G) + 1
• Der Vierfarbensatz: G ist planar (besitzt kreuzungsfreie
ebene Zeichnung) ⇒ χ(G) ≤ 4
• Beweis: Konstruktion einer Färbung durch den folgenden
(offensichtlichen) Greedy-Algorithmus:
• Diese Vermutung (Guthrie 1852, Cayley 1878)
und ihre Beweisversuche (Kempe 1879, Tait 1880)
sind ein Ursprung der modernen Graphentheorie.
Für eine beliebige Reihenfolge [v1, . . . , vn] der Knoten:
• Beweis (mit Computerhilfe) durch Appel und Haken 1977
c(vi) := mex M mit M = {c(vj ) | j < i ∧ vj vi ∈ E},
mex M := min(N>0 \ M )
• vereinfacht durch Robertson, Saunders, Seymour,
Thomas 1995
• Bsp: ein G und eine Knotenreihenfolge, so daß die vom
Algorithmus berechnete Färbung nicht minimal ist.
• maschinell verifizierter Beweis durch Gonthier 2005,
siehe http://www.ams.org/notices/200811/
• Beweis: folgt aus c(vi) ≤ |M | + 1 und |M | ≤ |G(vi)|
– Typeset by FoilTEX –
• Aufgabe: für welche Graphen gilt χ(G) = ∆(G) + 1?
314
315
Hohe chromatische Zahl ohne Dreiecke
Der Satz von Brooks
• Brooks 1941: G zusammenhängend und G nicht
vollständig und G kein ungerader Kreis ⇒ χ(G) ≤ ∆(G).
• Beweis: (nach Cor Hurkens,
https://www.win.tue.nl/˜wscor/OW/CO1b/)
• Def: ω(G) := max{n : Kn ⊆ G} (größte Clique in G)
• Satz: χ(Kn) = n, Satz: ω(G) ≤ χ(G).
• Satz: ∀c : ∃Gc : ω(G) = 2 ∧ χ(G) = c
Bsp: G2 = P2, G3 = C5, G4 = . . .
• Beweis (Mycielski, 1955)
– Konstruktion von M (G) für G = (V, E) als
∗ Knoten: V ∪ V 0 ∪ {0} mit V 0 = disjunkte Kopie von V
∗ Kanten: E ∪ {xy 0 | xy ∈ E} ∪ {x00 | x ∈ V }
– Eigenschaften:
∗ G ohne Dreieck ⇒ M (G) ohne Dreieck
∗ χ(M (G)) = χ(G) + 1
– x mit Grad ∆(G), hat Nachbarn y, z mit xy ∈
/ E.
– wenn G0 = G \ {y, z} zshg., dann T = BFS(G0, x).
Knotenreihenfolge: y, z, dann <post(F ) (endet mit x)
es ist immer eine Farbe aus {1, . . . , ∆(G)} frei.
– wenn G0 nicht zshg., dann einfachere Fälle, siehe
Quelle.
• Anwendung: χ(Petersen) ≤ 3
– Typeset by FoilTEX –
– Typeset by FoilTEX –
• Bsp: C5 = M (P2). Def: Grötzsch-Graph := M (C5)
316
– Typeset by FoilTEX –
Effizientes Färben
317
Komplexitätstheorie
• die Spezifikation
• . . . untersucht Schwierigkeiten von Problemen
gewünschtes Resultat: P ist schwer“,
”
d.h., besitzt keinen Polynomialzeit-Algorithmus
– Eingabe G,
– Ausgabe: konfliktfreie Färbung c : V (G) → 2, falls
existiert, NEIN sonst
hat effizienten Algorithmus:
BFS, Schichten abwechselnd färben, auf Konflikte prüfen.
• für Eingabe G, Ausgabe: . . . c : V (G) → 3,. . .“
”
ist kein Polynomialzeit-Algorithmus bekannt.
• das ist aber sehr schwer nachzuweisen,
?
vgl. auch die Million-Dollar-Frage“ P = NP
”
http://www.claymath.org/
millennium-problems/p-vs-np-problem
– P: Menge der in Polynomialzeit lösbaren Probleme
– NP: Menge der durch Suchbäume polynomieller Tiefe
lösbaren Probleme
2-Färbung ∈ P, 3-Färbung ∈ NP, offen: 3-Färbung ∈ P
– Typeset by FoilTEX –
318
– Typeset by FoilTEX –
319
Zusammenfassung
Reduktionen
• wenn man für A ∈ NP nicht zeigen kann, daß A ∈
/ P,
• dann zeigt man ersatzweise A gehört zu den schwersten
”
Problemen in NP“,
Def: falls jedes B ∈ NP sich auf A reduzieren läßt:
• B ≤P A, A wenigstens so schwer wie B“
”
• . . . durch Angabe von Polynomialzeitverfahren für
f : Eingabe für B → Eingabe für A mit
∀x : x ∈ B ⇐⇒ f (x) ∈ A
• Ideen — z.B.: Balance
• Sätze — zeigen die Nützlichkeit der Ideen
z.B.: t ist AVL-balanciert ⇒ height(t) ≤ log1.6 size(t)
• Methoden — sind Quellen für Ideen
z.B.: Induktion über die Höhe von Bäumen
• Bsp: ∀B ∈ NP : B ≤P Halteproblem für NP ≤P SAT
SAT = erfüllbare aussagenlogische Formeln ≤P 3COL =
3-färbbare Graphen (⇒ SAT und 3COL gleich schwer)
– Typeset by FoilTEX –
Übersicht
was haben wir hier eigentlich gelernt?
320
und warum?
• Methoden sind universell (⇒ wiederverwendbar )
– Typeset by FoilTEX –
Datenstrukturen
Algorithmen
• (Entwurf ⇒) Spezifikation ⇒ Algorithmus (⇒ Programm)
• wesentliche Eigenschaften von Algorithmen:
• konkrete Repräsentation (z.B.: Baum, Hash-Tabelle)
eines abstrakten (mathemat.) Begriffs (z.B.: Menge)
• die Axiome des abstrakten Datentyps sind die
Spezifikation für die Operationen des konkreten
Datentyps
– Korrektheit (bzgl. Spezifikation)
– Komplexität (bzgl. Kostenmodell)
• Methoden für Korrektheitsbeweise
• die Idee hinter jeder Datenstruktur besteht aus:
⇒ Methoden zum Algorithmenentwurf
– Invariante (Baum ist Suchbaum, ist AVL-balanciert,
x ∈ T ⇐⇒ T1(h1(x)) = x ∨ T2(h2(x)) = x,. . . )
– effizienten Algorithmen zum Erhalt der Invariante
(Rotation, Insert mit Verdrängen alter Einträge,. . . )
– Induktion (von n − 1 auf n)
⇒ lineare Rekursion (Iteration)
– Induktion (von mehreren ni < n auf n)
⇒ baum-artige Rekursion (divide and conquer)
– Typeset by FoilTEX –
322
– Typeset by FoilTEX –
• untere Schranke (Entscheidungsbäume): Ω(n log n)
• Komplexität eines Algorithmus A ist Funktion
cA : Eingabegröße s 7→ maximale Laufzeit von A auf
Eingaben der Größe ≤ s
• asymptotischer Vergleich von Komplexitäten cA ∈ O(cB )
(unabh. von Hardware, Programm, Sprache, Compiler)
• Komplexität cS einer Aufgabe (einer Spezifikation S):
beste Komplexität aller Algor., die S implementieren
– obere Schranke für cS : Angabe eines Algorithmus,
– untere Schranke: direkter Unmöglichkeitsbeweis
(Bsp: Entscheidungsbäume f. Sortierverfahren) oder
Reduktion von anderer Spezifikation bekannter
Komplexität (PQ mit insert und extractMin in O(1)?)
• These: S effizient lösbar ⇐⇒ cS ∈ Polynome
• Verfahren und ihre Eigenschaften:
–
–
–
–
–
naiv: durch Einfügen, durch Auswählen: O(n2)
verbessert: Shell-Sort: O(n3/2)
optimal: Merge-Sort
im Mittel optimal: Quick-Sort
optimal: Quicksort mit Median in O(n)
• Datenstrukt., mit denen man auch optimal sortieren kann:
– balancierter Suchbaum (alle einfügen, dann Inorder)
– Prioritätswarteschlange (Heap erzeugen, z.B. durch
Einfügen, dann extractMin bis leer)
324
– Typeset by FoilTEX –
Sortieren (Einschätzung)
325
Suchbäume und Heaps
dieses Semester:
• Gemeinsamkeit: balancierte Binärbäume, mit Schlüsseln
• diese Algorithmen, ihre Eigenschaften, deren Beweise:
• Unterschied:
wurde gelehrt und geübt, wird geprüft.
• Implementierung von Algorithmen: VLn Programmierung
ab 3. Semester:
• wer Sortier-Algorithmen tatsächlich selbst implementiert,
macht es falsch — es gibt Bibliotheken
• wer mittels Bibliotheksfunktion sortiert, macht es sehr
wahrscheinlich auch falsch — denn er benutzt eine Liste,
meint aber eine Menge, für die gibt es deutlich bessere
Implementierungen
– Typeset by FoilTEX –
323
Sortieren (Technik)
Komplexität, Effizienz
– Typeset by FoilTEX –
321
326
– Suchbaum: implementiert Menge
hat Operation contains
– heap-geordneter Baum: impl. Prioritätswarteschlange
hat Operation extractMin (und kein contains)
• Diskussion:
– man kann jeden Suchbaum als PQ verwenden,
– aber dann sind insert und decrease zu teuer,
– ⇒ schlechtere Laufzeit für Dijkstra auf dichten Graphen
– Typeset by FoilTEX –
327
Wie weiter?
Wie weiter? (Werbung für meine Vorlesungen)
Bachelor
• 3./4. Sem.: Softwaretechnik/Softwareprojekt
Entwurf von Softwaresystemen, d.h. Spezifikation ihrer
Komponenten, so daß Anwendungsaufgabe gelöst wird
Implementierung der Komponenten:
Auswahl passender Datenstrukturen und Algorithmen
• 4. Sem: fortgeschrittene Programmierung (u.a.
generische Polymorphie, Funktionen höherer Ordnung)
• 5. Sem: Sprachkonzepte der parallelen Programmierung
• in jeder Informatik-Vorlesung werden fachspezifische
Algorithmen und Datenstrukturen untersucht
(z.B. Bildverarbeitung: Quad-Trees, Künstliche Intelligenz:
heuristische Suche, Theoretische Inf.: CYK-Parser)
• und dabei die hier gezeigten Entwurfs- und
Analyse-Methoden angewendet
(z.B. divide and conquer, dynamische Prog., O-Notation)
– Typeset by FoilTEX –
328
Eine Aufgabe für die Semesterpause
• 1. Sem: Prinzipien von Programmiersprachen
(Syntax, Semantik (statische, dynamische), Pragmatik)
• – Compilerbau (a.k.a. praktische Semantik)
– Constraint-Programmierung
– Symbolisches Rechnen
– Typeset by FoilTEX –
329
Plan der Vorlesungen/Übungen
• Def: c : V → {0, 1, . . . , |E|} heißt graceful, wenn
– c injektiv
– und {|c(x) − c(y)| : xy ∈ E} = {1, . . . , |E|}.
• Def: G = (V, E) heißt graceful,
wenn für G eine graceful Färbung existiert.
• Bsp: wer ist graceful: K4, K5, C6, C7, P8, P9, K1,4,
vollst. Binärbaum der Höhe 2, 3 (autotool), . . . , n
• Aufgabe: jeder Baum ist graceful. (Geben Sie einen
Algorithmus an, der jeden Baum graceful färbt.)
• zum Üben: 1. Pfade, 2. Raupen (= Löschen der Blätter
ergibt Pfad), 3. Hummer (= Löschen . . . Raupe)
Übersicht nach Kalenderwochen
• KW 14: 2 VL:
– 1. Einführung
– 2. Komplexität von Algorithmen und Problemen
• KW 15: Übungen Serie 1 (zu VL 1,2) — 2 VL:
– 3. Asymptotischer Vergleich von Funktionen
– 4. Einfache Algorithmen (1) Schleifen
• KW 16: Übungen Serie 2 (zu VL 3) — 1 VL:
– 5. Einfache Algorithmen (2) Rekursion
Vorsicht! nicht zuviel Zeit investieren!
– Typeset by FoilTEX –
Master
330
– Typeset by FoilTEX –
331
• KW 17: Übungen Serie 3 (zu VL 4,5) — 2 VL:
• KW 21: keine Übungen — 1 VL (Mo.):
• KW 18: Übungen Serie 4 (zu VL 6) — 1 VL (Fr.):
• KW 22: Übungen Serie 8 (zu VL 12) — 2 VL:
– Hörsaal-Übung Serie 7 (zu VL 10, 11) sowie
Zusatz-Aufgaben
– 6. Sortieren (1) (Schranke, Inversionen, Shell-Sort)
– 7. Sortieren (2) (Merge-Sort)
– 13. Bäume (2) Balance, AVL
– 14. Prioritätswarteschlangen, heap-geordnete Bäume
– 8. Analyse rekursiver Algorithmen
• KW 19: Übungen Serie 5 (zu VL 7) — 2 VL:
• KW 23: Übungen Serie 9 (zu VL 13) — 1 VL (Do.):
– 9. Quick-Sort, Median
– 10. Dynamische Programmierung
– 15. Direkter Zugriff (1) Counting-Sort, Hashing
• KW 24: Übungen Serie 10 (zu VL 14) — 2 VL:
• KW 20: Übungen Serie 6 (zu VL 8,9) — 2 VL:
– 16. amortisierte Analyse
– 17. Graphen: Eigenschaften, einfache Algorithmen
– 11. greedy Algorithmen
– 12. Bäume (1) Suchbäume
– Typeset by FoilTEX –
332
333
Wörter, die es nicht gibt
• KW 25: Übungen Serie 11 (zu VL 15,16) — 2 VL (beide
Mo.):
Häufige Übersetzungsfehler in der Informatik
– 18. Minimalgerüste, Mengensysteme
– 19. kürzeste Wege (single source)
• merge — mischen? richtig: zusammenfügen, einordnen,
verzahnen, verschränken
• KW 26: Übungen Serie 12 (zu VL 17,18) — 2 VL:
http://www.roadtrafficsigns.com/merge-signs
– 20. kürzeste Wege (all pairs)
– 21. weitere Algorithmen auf Graphen
thru traffic merge left: Durchgangsverkehr links mischen?
• (minimal) spanning tree — (kleinster) Spannbaum?
• KW 27: Übungen Serie 13 (zu VL 19,20) — 2 VL (beide
Mo.):
wenn schon, dann aufspannender Baum“, aber die
”
empfohlene deutsche Bezeichnung (z.B. [Brandstädt],
[Walther/Nägler] ist (Minimal)gerüst.
– 23. Zusammenfassung, Ausblick
– Hörsaal-Übung (Zusatz-Aufgaben, Fragen)
– Typeset by FoilTEX –
– Typeset by FoilTEX –
• side effect — Seiteneffekt? richtig: Nebenwirkung.
334
– Typeset by FoilTEX –
335
• control flow — Kontrollfluß?
richtig: Programmablauf(steuerung)
(to control — kontrollieren? richtig: steuern)
• problem — Problem? besser: Aufgabe
sowohl bei Hausaufgaben als auch in der
Komplexitätstheorie: die Aufgabe (nicht: das Problem)
der 3-Färbung.
[CLR] (engl.) verwendet exercise (einfache
Übungsaufgabe) und problem (umfangreiche
Hausaufgabe)
– Typeset by FoilTEX –
336
Herunterladen