Universitat Konstanz
Skript zu Informatik II im Sommersemester 1999
Karsten Weihe
Konstanzer Schriften in Mathematik und Informatik Nr. 94, Juli 1999 ISSN 1430{3558
c Fakultat fur Mathematik und Informatik
Universitat Konstanz Fach D 188, 78457 Konstanz, Germany Email:
[email protected]{konstanz.de WWW: http://www.informatik.uni{konstanz.de/Schriften
Informatik II
Generalthema:
Algorithmen und Datenstrukturen
Eine beispielorientierte Einfuhrung in Algorithmen und Datenstrukturen (mit Java)
Algorithmus: Vorgehensweise zur Erzielung eines
Ergebnisses, ohne dabei nachdenken zu mussen ("Kochrezept\). ;! Auch durch Computer ausfuhrbar.
Datenstruktur: Speicher fur die von
Algorithmen zu bearbeitenden bzw. fur zusatzlich dafur verwendete Daten.
Wichtigste zu betrachtende Aspekte:
Sommersemester 1999 Universitat Konstanz
Karsten Weihe
Informatik II { Sommersemester 1999
1
Modellbildung, Korrektheit der Losungen, Ezienz (Laufzeit), Speicherplatzverbrauch.
Informatik II { Sommersemester 1999
2
Thema 1: Algorithmische Problemstellung Fallbeispiel: "passendste\ interpolierende nichtverti-
Oene Frage: Was heit eigentlich "passendst\?
Eingabe: n Mepunkte (x1; y1); : : : ; (xn; yn). Ausgabe: Steigung der Geraden und ihr Schnittpunkt mit der y-Achse.
Problem: Bei steilem Anstieg ware eher die horizontale
Informatik II { Sommersemester 1999
Informatik II { Sommersemester 1999
kale Gerade fur Mewerte
3
1. Ansatz fur "passendst\: Summe der vertikalen Abstande minimal.
Abweichung signi kant.
;! Keine gute Modellbildung. 4
2. Ansatz fur "passendst\: Summe der lotrechten Abstande minimal
Wichtigster Ansatz in der Praxis: Methode der kleinsten Quadrate. Auch Regressionsanalyse genannt (;! Statistik). Summe der Quadrate der vertikalen Abstande soll minimiert werden.
;! Schon recht genau das, was man will. Wirklich die "beste\ De nition?
Gibt es uberhaupt die "beste\ De nition!? Informatik II { Sommersemester 1999
5
Problem:
"Ausreier\ (d.h. ernsthafte Mefehler) haben uber-
proportionalen Ein u auf das Ergebnis. Falls Ausreier durch einseitigen Mefehler erzeugt werden: ;! Systematische Verfalschung des Ergebnisses wird noch verstarkt!
Informatik II { Sommersemester 1999
6
Frage:
Warum wird dennoch ausgerechnet diese De nition gewahlt?
Pragmatische Antwort:
Diese De nition ist mathematisch (und somit algorithmisch) vergleichsweise einfach handhabbar!
Moglicher Ausweg: "Ausreier\ aus der Betrachtung herausnehmen.
Beispiel fur eine exakte De nition des Auswegs:
Finde die Gerade, die "am passendsten\ ist, wenn nur die 90% Mepunkte, die am nachsten an dieser Gerade liegen, in die Summe der quadrierten Abstande eingehen. Informatik II { Sommersemester 1999
7
Informatik II { Sommersemester 1999
8
U ber-/Unterspezi kation
Merke:
Uberspezi kation: Exakte Problemde nition ist ein-
Zur automatisierten Bearbeitung eines algorith-
schrankender formuliert als eigentlich beabsichtigt. Unterspezi kation: Exakte Problemde nition enthalt nicht alle eigentlich beabsichtigten Einschrankungen.
mischen Problems braucht man eine exakte Problemde nition. Zu spezi zieren sind die zulassigen Eingaben und das gewunschte Ergebnis, das fur eine zulassige Eingabe berechnet werden soll. Alltagsformulierungen\ sind typischerweise "nicht exakt genug. Die exakte De nition zu einer Alltagsformulierung gibt es nicht unbedingt. ;! Freiheitsgrade bei der Umsetzung. Diese Freiheit kann man nutzen, um zu einer moglichst gut algorithmisch handhabbaren Problemde nition zu kommen.
Informatik II { Sommersemester 1999
Achtung: U berspezi kation kann leicht durch Verwirrung von algorithmischer Problemstellung und algorithmischer Vorgehensweise passieren!
Beispiel: Ausreier bei der Bestimmung der "passendsten\ Megerade eliminieren.
Falle: Die 90% "am besten passenden\ Mepunkte werden schon in der Problemstellung spezi ziert.
9
Konkretes Beispiel: Die 10% Mepunkte mit den
Winkeln vom Nullpunkt aus gesehen "exzentrischsten\ sollen aus der Berechnung der Summe der Abstandsquadrate herausfallen.
Informatik II { Sommersemester 1999
10
Merke:
U berspezi kationen passieren leicht dadurch, da man dem Algorithmus unbeabsichtigt "Arbeit abnimmt\. Dadurch ist der Algorithmus in seinen Moglichkeiten unnotig (und vielleicht entscheidend!) eingeschrankt. Also: Algorithmische Problemstellung und algorithmische Vorgehensweise beim Nachdenken konsequent auseinanderhalten.
Logische Inkorrektheit: Die 10% Mepunkte sollten
nicht a priori gegeben sein, sondern sich eigentlich erst aus dem Ergebnis des Algorithmus ergeben. Informatik II { Sommersemester 1999
11
Informatik II { Sommersemester 1999
12
Noch einmal zuruck zum Thema algorithmisch gut handhabbare Problemstellungen\ " Extremfall: algorithmenorientierte statt problemorien-
tierte Spezi kation der algorithmischen Problemstellung.
Newton{Verfahren:
xn+1 := xn ; ff0((xxn))
(n 0)
n
Beispiel:
Eingabe: Funktion f : R ;! R , Ableitungsfunktion f 0 sowie ein x0 2 R . Ausgabe: Nullstelle von f . Zulassige Eingaben: f konvex und streng monoton zwischen x0 und Nullstelle. ;! Newton{Verfahren zur Nullstellenberechnung liefert beweisbar eine korrekte Losung.
x3 x 2
x1
x0
Frage: Wozu sind solche algorithmen- statt problemorientierte Spezi kationen gut?
Informatik II { Sommersemester 1999
13
Wozu algorithmenorientierte Spezi kationen?
Informatik II { Sommersemester 1999
14
Veranschaulichung Quadratwurzelberechnung
Antwort: Als "gemeinsamer Nenner\ fur diverse Spe-
per Newton{Verfahren:
zialfalle, die durch denselben schnellen, aber nicht allgemein anwendbaren Algorithmus gelost werden konnen.
Beispiel fur solche Spezialfalle: Quadratwurzelberechnung.
Zulassige Eingabe: y 2 R , y 0. Gewunschte Ausgabe: py. Losungsidee: Finde nichtnegative Nullstelle der Funktion f : R ;! R mit f (x) = x2 ; y. Startlosung: x0 := maxf1; yg. ;! x0 py garantiert.
Informatik II { Sommersemester 1999
- y
15
Informatik II { Sommersemester 1999
-y
y
max{1,y }
16
Variationen vs. Spezialfalle von algorithmischen Problemstellungen Zuruck zum Thema Megerade ...
Beispiele fur Variationen:
Die Gerade soll nicht durch Steigung und Schnitt
Beispiele fur Spezialfalle:
Alle Mepunkte haben ganzzahlige Werte. Es gibt niemals mehr als 100 Mepunkte. Keine zwei Mepunkte haben dieselbe x{Koordinate.
Informatik II { Sommersemester 1999
17
Beliebter Denkfehler: Manche Variation sieht wie Spezialfall aus ;! scheint einfacher (ezienter) losbar zu sein. Beispiel: Gerade soll ganzzahlige Steigung haben.
Kein Spezialfall, sondern nur\ eine Variation (und tatsachlich auch wesentlich"aufwendiger zu losen!).
Informatik II { Sommersemester 1999
19
punkt mit der y-Achse, sondern durch zwei Punkte auf der Geraden ausgegeben werden. Die Gerade mu durch den Nullpunkt gehen. Die Steigung soll ganzzahlig sein. Vertikale Geraden sind zugelassen. Allgemeinere Kurven anstelle von Geraden. Dreidimensionale Variante des Problems.
Informatik II { Sommersemester 1999
18
Merke:
Ein Spezialfall liegt vor, wenn die zulassigen
Eingaben fur den Algorithmus eingeschrankt werden. Alles andere sind Variationen. Insbesondere: Einschrankungen bei der Ausgabe konstituieren keinen Spezialfall, sondern eine Variation! Nur wenn A ein wirklicher Spezialfall von B ist, kann man logisch folgern, da A mindestens genauso ezient losbar ist wie B . Ist A nur eine Variation von B , lat sich ohne weiteres Wissen uber A und B gar nichts folgern.
Informatik II { Sommersemester 1999
20
Fallbeispiel aus der Praxis:
Vereinfachtes Beispiel fur Ablaufplane:
Auftragsplanung im Stahlwerk (stark vereinfacht!)
Jeder Kundenauftrag spezi ziert
Metallschmelze
{ spatesten Liefertermin, { Art des Produkts
Warmwalzen Abkühlen
(z.B. Draht, Blech, Trager...), { Abmessungen (z.B. Drahtdurchmesser/-lange, Blechstarke/-breite/-lange), { Material und Legierung, { Sonderbehandlungen (z.B. Farbung, Beizung...). Kundenauftrag wird in Ablaufplan umgesetzt. Ablaufplan: Folge von Operationen auf verschiedenen Maschinen, um das Endprodukt aus einer Schmelze herzustellen. Informatik II { Sommersemester 1999
Transport zum Kaltwalzwerk Kaltwalzen Transport Drahtziehen Transport Färben Lagerung zum Trocknen Transport ins Endlager Endprodukt
21
Algorithmisches Ziel: Zeitliche Einplanung
22
Was soll passieren, wenn der Algorithmus keine
aller Operationen, so da alle Nebenbedingungen erfullt sind:
Losung ndet?
Jede Operation hat ihre spezi sche Bearbeitungs-
zeit. Jede Maschine bearbeitet zu jedem Zeitpunkt maximal eine Operation. Minimale und maximale Ubergangszeiten zwischen zwei aufeinanderfolgenden Operationen eines Auftragsplans mussen eingehalten werden.
Beobachtungen:
Die Nebenbedingungen konnen das
Problem unlosbar machen. Falls uberhaupt losbar, kann es mehrere Losungen geben. Informatik II { Sommersemester 1999
Informatik II { Sommersemester 1999
23
Mogliche, sinnvolle Antworten:
Er soll eine "moglichst wenig inkorrekte\ Losung liefern. ;! Einige der "harten\ Nebenbedingungen
mussen zu "weichen\ Zielsetzungen werden (z.B. Einhaltung aller Liefertermine). Er soll eine Diagnostik liefern, z.B. { welche Maschinen wann jeweils der "Flaschenhals\ sind, { welche Liefertermine unmoglich einzuhalten sind. ;! Hilfreiche Information, damit Druck durch geeignete betriebliche Manahmen abgefangen werden kann (z.B. zusatzliche Arbeitsschichten). Zur Diagnostik konnen auch konkrete Vorschlage fur solche betrieblichen Manahmen gehoren. Informatik II { Sommersemester 1999
24
Allgemein beliebte Falle: Vergessen von
Merke:
"simplen\ Randfallen Beispiel: Maschine im Stahlwerk kann uber den gesamten betrachteten Zeitraum hinweg auer Betrieb sein.
Ein algorithmisches Problem kann mehrere
Losungen haben. Oder auch gar keine. Exakte De nition der algorithmischen Problemstellung mu ggf. auch das Ergebnis "keine Losung\ zulassen. Insbesondere bedeutet Ergebnis "keine Losung\ nicht unbedingt Fehlverhalten des Algorithmus. Typische Variationen zur Behandlung dieser Aspekte sind: { Forderung nach mehreren alternativen Losungen zum Auswahlen, { diagnostische Zusatzausgaben, { Eingrenzung der Losungsmenge anstelle von konkreten Losungen.
Informatik II { Sommersemester 1999
Beispiel fur Konsequenzen: Algorithmus darf nir-
gendwo einfach durch die Gesamtbetriebszeit einer Maschine dividieren!
Problem konnte im Prinzip dadurch gelost werden, da eine solche Maschine aus der Betrachtung genommen wird. Aber: Konnte potentiell zu umstandlich sein.
Also: Damit keine Zweifel aufkommen, sollte die Spezi kation der algorithmischen Problemstellung ausdrucklich den Fall Gesamtbetriebszeit 0 einschlieen.
25
26
Thema 2: Generische Problemstellungen
Merke:
Wieder zuruck zum Beispiel \`interpolierende Megerade\...
Bei der genauen Spezi kation einer algorith-
mischen Problemstellung mu immer besonderes Augenmerk auf die "Randfalle\ gelegt werden. Da ein Randfall "prinzipiell vermeidbar\ ware, bedeutet nicht unbedingt, da er in der Praxis auch wirklich unter allen Umstanden vermieden wird. Oft ist es namlich einfach zu umstandlich, den Randfall vorab abzufangen.
Informatik II { Sommersemester 1999
Informatik II { Sommersemester 1999
Beobachtung:
Der genaue Zahlentyp spielt fur die algorithmische Problemstellung keine Rolle.
Allgemein:
Jeder Zahlentyp, auf dem der Abstand zwischen Punkten (x1; y1) und (x2; y2) de niert ist, kann in die Problemstellung eingesetzt werden.
27
Naturliche Zahlen Ganze Zahlen Rationale Zahlen Reelle Zahlen ...
Informatik II { Sommersemester 1999
28
Fortsetzung Generizitat
Intuition hinter "Manhattan{Distanz\:
Weitere Beobachtung: Verschiedene Abstandsde -
nitionen (Metriken) konnen auf demselben Zahlentyp de niert sein.
Beispiele:
Normaler (Euklidischer) Abstand: Lange der Verbindungsstrecke
p
(x1 ; x2)2 + (y1 ; y2)2
(Mathematischer Begri: 2{Metrik) Manhattan-Distanz:
jx1 ; x2j + jy1 ; y2j (Fahrdistanz in Manhattan{artig angelegten Stadten; mathematisch: 1{Metrik) Informatik II { Sommersemester 1999
29
"Esoterische\ Beobachtung:
Informatik II { Sommersemester 1999
30
Standardbeispiel fur Generizitat: Sortieren
Man braucht sich eigentlich gar nicht auf Zahlentypen zu beschranken.
Jede Menge mit einem Abstandsbegri ist moglich. Beispiel: Strings der Lange m mit Hamming-Abstand
Gegeben: Sequenz (a1; : : : ; an) von zu
sortierenden Werten. Gesucht: Permutation der Sequenz, so da gilt: (a1) (a2) (an)
Einfaches Zahlenbeispiel:
Abstand zweier Strings =
17 21 41 67 12 41 15 23 88 9
Anzahl der ungleichen Zeichen 9 12 15 17 21 23 41 41 67 88
Informatik II { Sommersemester 1999
31
Informatik II { Sommersemester 1999
32
Generische Freiheitsgrade: Datentyp fur die Werte a1; : : : ; an,
Konkretes Beispiel: Datensatze fur immatrikulierte
De nition von "\, Datentyp fur die Sequenz (z.B. Array).
Vorgri: Fur die meisten in dieser Vorlesung behan-
delten Sortieralgorithmen ist die Festlegung dieser drei Freiheitsgrade unerheblich!
Studierende. Enthalten als Daten z.B. Vorname, Nachname, Fachrichtung, Matrikelnummer. Sinnvolle De nitionen von "\: { "Telefonbuchordnung\ auf den Namen (Fachbegri: lexikographisch) ;! Reihenfolge nicht eindeutig. { Nach Matrikelnummern ;! Reihenfolge eindeutig. { Nach Geburtsdaten ;! Reihenfolge wieder nicht eindeutig.
;! Spater mehr zum Thema Sortieren.
Informatik II { Sommersemester 1999
33
Mathematische Exkursion: abstrakte
Informatik II { Sommersemester 1999
34
Technische Exkursion: potentielles Zusammenfallen
Datentypen
von Ein- und Ausgabe
Beispiel: wieder Immatrikulationsdaten
Datentyp = Menge von moglichen Werten + Operationen + axiomatische Regeln fur die Operationen
StudentIn[]
sort (StudentIn[] A)
Erlauterung:
Beispiel: Mathematische Gruppe.
Eingabe: Parameter A. Ausgabe: Ruckgabewert von sort.
tion. Rationale und reelle Zahlen (ohne 0) jeweils mit Multiplikation.
Alternative:
Generischer Algorithmus Algorithmus auf abstrakten Datentypen.
A
Ganze, rationale und reelle Zahlen jeweils mit Addi-
Informatik II { Sommersemester 1999
{ ... }
void
sort (StudentIn[] A)
{ ... }
ist nun Ein- und Ausgabe ;! eine Kopieraktion eingespart. 35
Informatik II { Sommersemester 1999
36
Weiteres Beispiel fur generische algorithmische Pro-
Schnellste Fahrverbindung mit dem Zug:
blemstellungen: Optimale Verbindungen in Netzwerken Generische Problemstellung
Kürzeste Autoverbindung
Schnellste Bahnverbindung
Billigste Flugverbindung
Preis\ einer Verbindung von A nach B (vereinfacht): "Summe der Einzelpreise fur die elementaren Fahrten.
;! Problemstellung benotigt zwei Operationen auf dem Datentyp fur Preise: Addition und Minimumsbildung.
Informatik II { Sommersemester 1999
37
Sinnvolles Beispiel fur generisches Oenhalten des
Zahlentyps: "Preis\ einer elementaren Fahrverbindung: Paar (a; b) von Zahlen. Addition: (a; b) + (c; d) = (a + c; b + d). Minimum von (a; b) und (c; d): = (a; b) falls a < c, = (a; b) falls a = c und b < d, = (c; d) sonst.
Sinn des Ganzen:
38
Zunachst obskur erscheinende generische Variation: Ersetze Addition durch Multiplikation und Minimum durch Maximum. DM ÖS
SFr US $
;! "Kurzeste\ Verbindung von Wahrung A
nach Wahrung B mit Umtauschkurs als "Preis\ ergibt gunstigste Umtauschkette. ;! Auch dieses Problem ist im Prinzip mit demselben Algorithmus fur "kurzeste Wege\ losbar!
1. Zahl: Fahrpreis. 2. Zahl: Fahrzeit. ;! Optimaler Pfad mit diesem "Zahlentyp\
und dieser De nition von Addition und Minimumsbildung ist die schnellste Verbindung unter allen billigsten!
Informatik II { Sommersemester 1999
Informatik II { Sommersemester 1999
39
Informatik II { Sommersemester 1999
40
Unerwartetes Beispiel fur
kurzeste Wege: Blockformatierung von Texten in Textverarbeitungssystemen
Knotenpunkte: alle Silben sowie "{ Ende {\.
Verbindung: Von jeder Silbe zu jeder nachfolgenden.
"Preis\ einer Verbindung:
der zu"Haolichkeitsgrad\ geh rigen Zeile.
Formatierung
Pfad von erster Silbe bis "{ Ende {\.
Un er war te tes Bei spiel für kür ze ste We ge: Block for ma tierung von Tex ten in Text ver ar bei tungs sy ste men -Ende -
Informatik II { Sommersemester 1999
Merke:
In vielen Problemstellungen kann der zu-
grundeliegende Datentyp in gewissen Grenzen oengelassen werden, und Losungsalgorithmen werden mit den sich ergebenden Variationsmoglichkeiten trotzdem fertig. Fur den Datentyp mussen nur gewisse Operationen de niert sein, die fur die Problemstellung wesentlich sind. Weiterer Freiheitsgrad: Diese Operationen konnen unterschiedlich de niert sein (auch in ungewohnlicher, unerwarteter Weise).
41
Technische Exkursion: Wie kann man die Implemen-
tation eines Algorithmus in Java so generisch wie den Algorithmus selbst halten?
Informatik II { Sommersemester 1999
42
Ergebnis: void sort (Object[] A, Comparator cmp) { ...
Idee:
Konkreten Datentyp durch den "allumfassenden\ Typ comp.lang.Object ersetzen. Operation "\ durch einen weiteren Parameter von einem neuen Typ Comparator\ reprasentieren. "
// Beispielhafte Anwendung von "isLessThan": if ( cmp.isLessThan(A[i],A[j]) ) ... }
"Comparator\ hat Methode boolean isLessThan (Object obj1, Object obj2)
zum Vergleich zweier Werte des Datentyps.
Informatik II { Sommersemester 1999
43
Informatik II { Sommersemester 1999
44
Implementation von "isLessThan\ Beispiel: fur Datentyp int und gewohnliche Ordnungsrelation auf ganzen Zahlen.
Kurzer Ausblick:
Java{Erweiterung GJ (Generic Java) Implementation von isLessThan: boolean isLessThan (Integer int1, Integer int2) { int i1 = int1.intValue(); int i2 = int2.intValue(); return i1 < i2; }
boolean isLessThan (Object obj1, Object obj2) { Integer int1 = (Integer)obj1; Integer int2 = (Integer)obj2; int i1 = int1.intValue(); int i2 = int2.intValue(); return i1 < i2; }
Nun sort selbst: void sort (T[] A, Comparator cmp) { ...
Achtung: void sort (Object[] A, Comparator cmp)
Paar (A,cmp) ist nur dann eine zulassige Eingabe, wenn alle Komponenten von A den Datentyp haben, der von cmp.isLessThan erwartet wird. Informatik II { Sommersemester 1999
45
void sort (T[] A, Comparator cmp)
sort
Bemerkung: Generische Typen und Prozeduren gibt es in verschiedenen Programmiersprachen (z.B. Ada, C++, Eiel, Haskell, ML), aber eben (noch?) nicht in Java.
Informatik II { Sommersemester 1999
}
Informatik II { Sommersemester 1999
46
Merke:
Erlauterung: Datentyp ist jetzt explizit, aber immer noch generisch (d.h. durch einen "Platzhalter\, im
Beispiel durch "T\) in der Implementation von formuliert. ;! Beim U bersetzen wird schon automatisch getestet, ob A und cmp zusammenpassen. ;! Die "Zeitbombe\ ist "entscharft\.
// Beispielhafte Anwendung von "isLessThan": if ( cmp.isLessThan(A[i],A[j]) ) ...
47
Im Prinzip lassen sich generische Algorithmen
in Java auch entsprechend generisch implementieren. Allerdings mu beim Programmieren "per Hand\ darauf geachtet werden, da die Datentypen der Eingabeparameter zusammenpassen. In groeren Programmen kann man leicht die U bersicht verlieren und Fehler einbauen, die dann oftmals muhselig und langwierig durch Testlaufe zuruckverfolgt werden mussen. In anderen Programmiersprachen gibt es sogenannte generische Sprachkonstrukte (auch Templates genannt), die dafur sorgen, da der Compiler jeden solchen Fehler anzeigt. Informatik II { Sommersemester 1999
48
Thema 3: Korrektheit von Algorithmen Wiederholung aus Thema 1: Spezi kation einer algorithmischen Problemstellung gibt die zulassigen Eingaben an und beschreibt das gewunschte Ergebnis fur eine zulassige Eingabe in allgemeiner Form. De nition: Ein Algorithmus heit korrekt bzgl. ei-
ner (exakt spezi zierten!) algorithmischen Problemstellung, wenn er bei einer zulassigen Eingabe nur wohlde nierte Schritte macht, terminiert (d.h. in keine Endlosschleife lauft) sowie bei Termination das laut Spezi kation gewunschte Ergebnis liefert.
Informatik II { Sommersemester 1999
49
Achtung:
Wohlde nierte Schritte... Beispiele fur nicht wohlde nierte Schritte: Division durch 0,
Operationen mit arithmetischem U berlauf, Zugri auf Arraykomponente auerhalb des Indexbereichs,
Zugri auf nichtinitialisierte Variable. Beachte: Nicht wohlde nierte Schritte fuhren zu unde niertem Verhalten des Programms im weiteren: Programmabsturz, Endlosschleife, Rechnerstillstand, Termination mit inkorrekten Ergebnissen Termination mit korrekten Ergebnissen ...
Informatik II { Sommersemester 1999
50
Merke:
Arithmetischer U berlauf kann manchmal uberraschend schnell passieren!
Beispiel: Binomialkoezient berechnen mittels Fakultat m! = 1 2 3 (m ; 1) m.
n
n! k := k! (n ; k)!
Korrektheit eines Algorithmus ist nicht abso-
lut, sondern immer nur relativ zur zugrundeliegenden Spezi kation der algorithmischen Problemstellung zu verstehen. Zur Korrektheit gehoren als Grundvoraussetzungen Wohlde niertheit und Termination.
int binomcoeff (int n, int k) { return faculty(n) / (faculty(k) * faculty(n-k)); }
Problem: Java{Datentyp int kann nur Zahlen bis 231 ; 1 = 2:147:483:647 darstellen. ;! Arithmetischer U berlauf schon fur n 13. Informatik II { Sommersemester 1999
51
Informatik II { Sommersemester 1999
52
Korrektheit unter numerischer Unsicherheit Beispiel: Quadratwurzelberechnung Problem: Die meisten Quadratwurzeln sind irrationale Zahlen. ;! Problem ist prinzipiell nicht exakt losbar.
Wichtigste Beispiele fur Abstandsfunktionen in der Praxis:
Absoluter Fehler: x x0, wenn jx ; x0j " ist. Relativer Fehler: x x0, wenn gilt: jx ; x0j " maxfx; x0g.
Grundidee:
Approximative Losung x fur die eigentliche Losung x0 wird als korrekt gewertet, wenn x x0. x x0 ist auf Basis einer Abstandsfunktion und eines festen Schwellwerts " > 0 de niert: x x0,
Unterschied: Aussagekraft des relativen Fehlers hangt
Informatik II { Sommersemester 1999
Informatik II { Sommersemester 1999
wenn der Abstand zwischen x und x0 den Schwellwert " nicht uberschreitet.
53
nicht von der Groenordnung der (willkurlich gewahlten) Konstante " im Verhaltnis zu x und x0 ab.
54
Beispiel: Konkrete Idee fur Quadratwurzelberechnung mittels Newton
Merke:
Es gibt algorithmische Probleme, die prinzipi-
ell nicht exakt losbar sind. Ursache: Diskrepanz zwischen mathematischen Zahlen mit unendlicher Genauigkeit und Maschinenzahlen mit endlicher Stellenzahl. In einem solchen Fall mu die gesuchte Losung approximiert werden. Besonders bewahrt in der Praxis: relativer Fehler als Ma fur die Gute einer approximativen Losung.
Informatik II { Sommersemester 1999
- y
-y
y
max{1,y }
Sei z 2 (0; py ] beliebig
;! f 0(x) = 2x 2z = f 0(z) fur x py ;! f (x) g(x) := 2z (x ; py) fur x py.
55
Informatik II { Sommersemester 1999
56
Veranschaulichung:
Merke:
Da der Zielwert nicht bekannt ist, mu der
f
Test, ob die Fehlerschranke schon unterschritten wurde, hau g indirekt mittels Berechnung anderer Werte arbeiten. Es gibt keine allgemeine Methode, geeignete Tests fur beliebige Algorithmen zu konstruieren, sondern wie bei Algorithmen selbst ist jedesmal von Neuem Kreativitat gefragt.
g
z
y
x
;! Sobald f (x) " 2z gilt, ist x ; py " erreicht.
Genaueres zum Thema Behandlung numerischer Fehler: Veranstaltungen zur Numerischen Mathematik.
Informatik II { Sommersemester 1999
57
Fallbeispiel aus der Praxis: Rekonstruktion fehler-
hafter Nachbarschaften zwischen Flachenelementen im CAD
Informatik II { Sommersemester 1999
58
Fehler in den Daten: Fehlerhafte Spalte zwischen Flachenelementen
CAD{Modell einer Pumpe:
Informatik II { Sommersemester 1999
59
Informatik II { Sommersemester 1999
60
Extrembeispiel fur Datenfehler (gefunden im Innern der Pumpe):
Algorithmische Problemstellung: Fehlerhafte Spalte von beabsichtigten O nungen unterscheiden.
Einsicht:
Es kommen zwar sehr viele fehlerhafte Spalte vor,
aber die meisten sind eher schmal (uberwiegend auf den Bildern nicht einmal sichtbar). O nungen hingegen sind eher breit.
;! Idee: Abstandsfunktion fur Paare von Flachenelementen de nieren.
Schwellwert " > 0 unterscheidet fehlerhafte Spal-
te zwischen Flachenelementen von beabsichtigten O nungen. 111 000 111 111 000 000
111 000 111 000 111 000 000 111
Informatik II { Sommersemester 1999
61
Beispiele fur sinnvolle Abstandsfunktionen zwischen Flachenelementen: Minimaler Abstand von irgendeinem Punkt auf einem Element zu irgendeinem Punkt auf dem anderen Element. Durchschnittlicher Abstand von einander "gegenuberliegenden\ Randpunkten. Flache in der Lucke zwischen den einander gegenuberliegenden Randsegmenten. ;! Alles Mae fur den absoluten Fehler.
Informatik II { Sommersemester 1999
62
Bonbon\ zum Abschlu: Visualisierung des Ergeb"nisses durch Einfarben von Randern gema Anzahl der anliegenden Flachenelemente
Relativer Fehler: " multipliziert mit einem Ma fur die Groe der Flachenelemente (z.B. Flacheninhalt, Durchmesser, Umfang). Unterschied: Relativer Fehler ist von der Skalierung des Modells unabhangig.
Informatik II { Sommersemester 1999
63
Informatik II { Sommersemester 1999
64
Erinnerung: Ein Algorithmus heit korrekt ... wenn er bei einer zulassigen Eingabe ... Beachte: Es wird nichts uber das Verhalten des Algorithmus bei nichtzulassigen Eingaben ausgesagt! Konkret: Algorithmus ist auch dann korrekt, wenn er
Merke:
Informell bedeuten absoluter bzw. relativer
Fehler: Die Diskrepanz zwischen Ziel und Ergebnis wird ohne bzw. mit Berucksichtigung der Groe der auftretenden Objekte berechnet. Falls diese Objekte in beliebiger Skalierung auftreten konnen, ist der absolute Fehler kein adaquater Mastab, nur der relative.
Informatik II { Sommersemester 1999
bei nichtzulassigen Eingaben absturzt, in Endlosschleife lauft oder sonstigen Blodsinn macht! Prinzip Design{by{Contract: Spezi kation ist "Vertrag\ zwischen dem Algorithmus und seinem "Kunden\. Kunde erfullt den Vertrag, wenn er nur zulassige Eingaben macht. Dann (und nur dann!) ist der Algorithmus "vertraglich\ verp ichtet, korrekt zu laufen und die korrekte Ausgabe zu liefern.
65
Einfaches Beispiel Design{by{Contract: Mogliche Eingaben: ganze Zahlen n
66
Warum Design{by{Contract? Konkret: Warum nicht einfach im Algorithmus fur n! die Bedingung n > 0 abtesten und im Fall n 0 eine
(z.B. Java{Datentyp int). Zulassige Eingaben: n > 0. Gewunschte Ausgabe: n!, d.h. 1 2 3 (n ; 1) n.
Fehlermeldung liefern?
Mogliche Formen fur Fehlermeldung:
Gefahr: "Kunde\ kann leicht seinen Teil des Vertrags
vergessen bzw. in komplexeren Fallen unsachgema oder nur unzureichend erfullen.
;! Potentiell unde niertes Programmverhal-
"Unmoglicher\ Wert anstelle von n! (z.B. ;1). int faculty (int n) // Liefert n!, falls n>0, sonst -1
Zusatzlicher Boolescher Parameter, der angibt, ob
ten sowohl im Algorithmus als auch (falls es uberhaupt soweit kommt) nach Termination des Algorithmus im weiteren Programmverlauf.
Ergebnis korrekt ist:
int faculty (int n, Boolean resultIsCorrect) // Ergebnis ist n!, falls
Oene Frage: Wenn Design{by{Contract so gefahrlich ist | warum dann uberhaupt? Informatik II { Sommersemester 1999
Informatik II { Sommersemester 1999
67
// resultIsCorrect.valueOf() == true
Informatik II { Sommersemester 1999
68
Also: Warum nun Design{by{Contract? 1. Antwort: Wenn Kunde kein Problem hat, den
Vertrag zu erfullen, kostet das zusatzliche Abtesten unnotig Laufzeit.
Beispiel fur signi kanten Ezienzverlust:
Eingaben: Liste von Personendaten fur Studierende
sowie eine Zahl n. Zulassige Eingaben: Alle Matrikelnummern mussen verschieden voneinander sein. Gewunschte Ausgabe: Der/die Studierende mit Matrikelnummer n (bzw. Meldung "existiert nicht\). Vorgri auf spateren Abschnitt der Vorlesung: Suchen einer Matrikelnummer geht um Groenordnungen schneller als der Test, da alle Matrikelnummern verschieden sind.
;! Design{by{Contract reduziert hier die
nur schwierig oder sogar unmoglich zu testen.
Beispiel: wieder algorithmenorientierte Problemstellung fur das Newton{Verfahren.
Zur Erinnerung:
x3 x 2
x1
x0
Bedingungen an die Funktion f : Monotonie und Konvexitat.
Laufzeit um Groenordnungen.
Informatik II { Sommersemester 1999
Fortsetzung warum Design{by{Contract 2. Antwort: Zulassigkeit der Eingabe ist manchmal
69
Technische Exkursion: Wie eine Funktion wie f an
einen Algorithmus wie "Newton\ ubergeben?
Idee: ahnlich wie bei der generischen Implementation von sort zuvor.
Interface Function de nieren: interface Function { double value (double x); }
Informatik II { Sommersemester 1999
70
Nun der Newton{Algorithmus selbst: double findZeroUsingNewton (Function f, Function fDerived, NumericErrorChecker checker, double start) {
Bei der Gelegenheit ... auch den Test auf "Nullstelle
double x = start; while ( ! checker.closeToSomeZero(f,x) ) x = x - f.value(x) / fDerived.value(x); }
genau genug erreicht\ durch zusatzlichen Parameter
exibel halten: interface NumericErrorChecker { boolean closeToSomeZero (Function f, double x); }
Erlauterung: Ruckgabe ist true genau dann, wenn x Nullstelle. Informatik II { Sommersemester 1999
71
Informatik II { Sommersemester 1999
72
Zuruck zum Ausgangspunkt: 2. Antwort auf "warum
Fortsetzung warum Design{by{Contract
Erinnerung: Behauptung ist, da Zulassigkeit der Eingabe manchmal nur schwierig oder sogar unmoglich zu testen ist.
3. Antwort: Die Menge der zulassigen Eingaben ist
Design{by{Contract?\
Konkretes Problem: Wie sollen Monotonie und Kon-
vexitat eines Function{Objekts eigentlich gepruft werden?
Wenn Funktion nur Methode value bietet, gibt es
nicht unbedingt formal fabar.
Wieder Beispiel Newton{Verfahren:
Verfahren funktioniert auch auf Funktionen f , die
nicht die oben formulierten strengen Bedingungen an Monotonie und Konvexitat erfullen.
nur eine Moglichkeit: die Funktionswerte fur alle x berechnen. ;! Unrealistisch. "Strohhalm\: Weitere Methoden fur Function, die den Test auf Monotonie und Konvexitat unterstutzen. Leider: keine allgemein anwendbare Idee fur solche Methoden in Sicht.
Problem: "Grenzlinie\ zwischen geeigneten und ungeeigneten Funktionen ist weitgehend unbekannt. ;! Jeder Test auf Zulassigkeit der Eingabe
Informatik II { Sommersemester 1999
Informatik II { Sommersemester 1999
73
weist entweder geeignete Funktionen ab oder lat ungeeignete Funktionen durch.
74
Thema 4: Korrekte Algorithmen Einfuhrendes Beispiel: Bisektionsverfahren zur Be-
Merke:
rechnung einer Nullstelle. Zulassige Eingabe: Stetige Funktion f : R ;! R , reelle Zahlen a < b, so da entweder f (a) < 0 und f (b) > 0 oder f (a) > 0 und f (b) < 0 ist. Gewunschte Ausgabe: Approximation des x{Wertes einer Nullstelle von f im Intervall [a; b].
Die Einschrankung der Korrektheit auf zulassige Eingaben (Design{by{Contract) ist potentiell gefahrlich.
Aus verschiedenen Grunden mu Design{by{
Contract dennoch hau g angewandt werden: { algorithmische Ezienz, { Test auf Zulassigkeit der Eingabe potentiell unmoglich, { potentiell uberhaupt keine befriedigende Spezi kation zum Abtesten der Zulassigkeit von Eingaben verfugbar.
f(a) b a f(b)
Informatik II { Sommersemester 1999
75
Informatik II { Sommersemester 1999
76
Vorarbeit zur Vereinfachung:
Funktion differentSign testet ab, ob zwei reelle Zahlen x und y unterschiedliches Vorzeichen haben.
Algorithmischer Ansatz
(der Einfachheit halber nur mit absolutem Fehler): double left_end = a; double right_end = b; while ( left_end + 2*epsilon < right_end ) { double middle = ( left_end + right_end ) / 2; if ( differentSign ( f(left_end), f(middle) ) ) right_end = middle; else left_end = middle; } return ( left_end + right_end ) / 2;
boolean differentSign ( double x, double y ) { if ( x > 0 && y < 0 ) return true; if ( x < 0 && y > 0 ) return true; return false; }
Informatik II { Sommersemester 1999
77
Informatik II { Sommersemester 1999
Veranschaulichung:
a
1
3 42
78
... while ( left_end + 2*epsilon < right_end ) { double middle = ( left_end + right_end ) / 2; if ( differentSign ( f(left_end), f(middle) ) ) right_end = middle; else left_end = middle; } ...
b
Schleifeninvarianten: Am Anfang und Ende jedes Schleifendurchlaufs gilt
left_end < right_end differentSign(f(left_end),f(right_end)) == true
Konsequenz daraus (zusammen mit der Stetigkeit von f ): Am Anfang und Ende jedes Schleifendurchlaufs liegt mindestens eine Nullstelle von f im momentanen Intervall [left Informatik II { Sommersemester 1999
79
end,right end].
Informatik II { Sommersemester 1999
80
Schleifenvariante: Nach k Durchlaufen der
Merke:
Schleife gilt (Rundungsfehler vernachlassigt): right end
; left
end
Ein nichttrivialer Algorithmus besteht "im we-
= b 2;k a
Konsequenz: Programm terminiert, sobald b;a 2" 2k
;! Programm terminiert nach
b ; a
log2 2 "
Durchlaufen durch die Schleife.
Informatik II { Sommersemester 1999
81
Wichtige Einsicht: Korrektheit des Algorithmus ist
nun beweisbar.
Erinnerung: Ein Algorithmus heit korrekt bzgl. einer
Spezi kation einer algorithmischen Problemstellung, wenn er bei einer nach dieser Spezi kation zulassigen Eingabe
nur wohlde nierte Schritte macht, terminiert und ein gema Spezi kation korrektes Ergebnis liefert.
sentlichen\ aus einer oder mehreren Schleifen (die auch ineinandergeschachtelt sein konnen). Ausnahme: rekursive Algorithmen (spater). Eine Schleifeninvariante ist eine Aussage uber die Werte von Variablen, die in jedem Durchlauf gultig ist. Eine Schleifenvariante ist eine Aussage uber die A nderung von Variablenwerten von Durchlauf zu Durchlauf. Zur Formulierung einer Invariante oder Variante gehort unbedingt dazu, an welcher Stelle der Schleife genau sie gultig sein soll (meist Anfang/Ende).
Informatik II { Sommersemester 1999
82
Nun konkreter Korrektheitsbeweis fur das Bisektionsverfahren:
Oensichtlich keine unde nierten Schritte. Erinnerung: Schleife terminiert nach maximal dlog2( b2;"a )e Durchlaufen. ;! Algorithmus als Ganzes terminiert. Schleifeninvariante ;! Auch bei Termination liegt immer noch eine Nullstelle zwischen left end und right end.
;! Ruckgabewert der Bisektionsfunktion
ist hochstens " von irgendeiner Nullstelle entfernt. ;! Ruckgabewert ist korrekt gema absolutem Fehlerma. Informatik II { Sommersemester 1999
83
Informatik II { Sommersemester 1999
84
Weiteres Beispiel: Fibonacci{Zahlen fib(1) = fib(2) = 1, fib(n) = fib(n ; 1) + fib(n ; 2) fur n > 2.
Notation: xi, yi und zi seien die Werte von x, y und z unmittelbar nach der Addition "z = x + y\ im Durchlauf Nr. i durch die Schleife. Drei Schleifeninvarianten: xi = fib(i ; 2), yi = fib(i ; 1), zi = fib(i). ;! Es gilt z = fib(n) nach dem allerletzten
;! 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, ... Algorithmus in Java: int fibonacci ( int n ) // Voraussetzung nach // "Design-by-Contract": n > 0. { if ( n 1.
Iterative De nition implementieren:
Insbesondere hat man dabei den Korrektheits-
int faculty ( int n ) { int result = 1; for ( int i = 2; i 0 x2N 1 1 175
Informatik II { Sommersemester 1999
176
Gesamtlaufzeit gema Modellannahmen = 1{mal beschrankte Laufzeit fur "int sum=0\ + 1{mal beschrankte Laufzeit fur den Initialisierungs-
Einfaches, kunstliches Beispiel: int sum = 0; for ( int i = 0; i < m; i++ ) { int k = i * i; for ( int j = 0; j < n; j++ ) sum += k * j; }
+ + + + + + +
Informatik II { Sommersemester 1999
177
Zusammenfassung: Die Gesamtlaufzeit jedes dieser
neun Summanden ist
teil der aueren Schleife m{mal beschrankte Laufzeit fur Fortsetzungsbedingung und Fortschaltung in der aueren Schleife 1{mal Laufzeit fur die interne Organisation der aueren Schleife ( m) m{mal beschrankte Laufzeit fur "int k=i*i\ m{mal beschrankte Laufzeit fur den Initialisierungsteil der inneren Schleife m n{mal beschrankte Laufzeit fur Fortsetzungsbedingung und Fortschaltung in der inneren Schleife m{mal Laufzeit fur die Organisation der inneren Schleife (jeweils n) (m n){mal beschrankte Laufzeit fur "sum+=k*j\.
Informatik II { Sommersemester 1999
178
A hnliches Beispiel: Selection{Sort Erinnerung: int indexOfMin (Object[] A, int first_index, Comparator cmp) { int index = first_index; for ( int i=first_index+1; i 0 mit " < a ; 1 wurde dann ebenfalls n! 2 O((a ; ")n) gelten. Wegen (a ; ")n 2 o(an) und Transitivitat wurde somit n! 2 o(an) gelten.
Beweisidee zu an 2 O(n!):
p8
Beliebig, aber fest gegeben: a > 1. Gesucht: na 2 N und ca > 0, so da n! ca an fur n na ist.
p13 p15
p12
Vermutung: n! wachst so schnell, da sogar an 2 o(n!) fur alle a > 1 gilt. Beobachtung: Es reicht an 2 O(n!) fur alle a > 1 zu
Anzahl Rundtouren: (n ; 1)! Frage: Wie schlecht ist systematisches
Beweis: Nachste zwei Folien.
Ausprobieren hier also mindestens? Informatik II { Sommersemester 1999
201
Ansatz: Logarithmisierung und Anwendung der Logarithmengesetze
n! ca an () log2
()
n X i=1
n ! Y
i=1
i log2 (ca an)
() ; log2 (ca) n log2(a) ;
() log2 c1 a
n X i=1
i=1
i=1
1
log2 c da () c1 2da a a () ca 21da
log2(i)
Konsequenz: Mit na := dae und ca := gewunscht n! ca an fur alle n na.
(log2(a) ; log2(i))
Fur n dae ist der rechte Ausdruck dae X
202
Wichtig: da ist eine Konstante und damit insbesondere unabhangig von n. Auswertung:
log2(i) log2(ca) + n log2(a) n X
Informatik II { Sommersemester 1999
1 2da
gilt wie
;! Beweis fertig.
(log2(a) ; log2(i)) =: da
Informatik II { Sommersemester 1999
203
Informatik II { Sommersemester 1999
204
Fibonacci{Reihe
Genauere Asymptotik von fib: Durch Anwendung der "Schullosung\ fur quadratische Gleichungen r
Einkreisung: "fib\ wachst ...
... hochstens so schnell wie 2n: Falls fib(k) c 2k fur alle k auch
< n ist, dann gilt
fib(n) = fib(n ; 1) + fib(n ; 2)
c (2n;1 + 2n;2) = c 2n;2 3 c 2n : p ... mindestens so schnell p k wie ( 2)n: Falls fib(k) c ( 2) fur alle k < n ist, dann gilt auch
fib(n) = fib(n ; 1) + fib(n ; 2)
p p c ( 2)n;1 + ( 2)n;2 p p = c ( 2)n;2 2 + 1 p p c ( 2)n;2 2 = c ( 2)n :
Informatik II { Sommersemester 1999
Idee: Gesucht ist a > 1 mit an = an;1 + an;2
() a2 = a + 1 () a2 ; a ; 1 = 0
r
() a = 21 14 + 1 Resultat: "fib\ ist asymptotisch aquivalent zu p !n
1+ 5 2 205
(1; 618)n
Informatik II { Sommersemester 1999
206
Thema 9: Asymptotik und Kodierungslange
Merke:
Fallbeispiel: Wie so oft Sortieren
Algorithmen mit exponentieller Laufzeit sind
im Grunde "jenseits von gut und bose\. Exponentielle Laufzeit wachst sogar so schnell, da multiplikative Verbesserungen der Rechenpower sich nur noch additiv auf die Groe der Eingaben, die in fester Zeit bearbeitet werden konnen, auswirken. Die Fibonacci{Reihe wachst so schnell wie eine Exponentialfunktion mit Basis 1; 618. Die Fakultatsfunktion wachst sogar noch schneller als alle Exponentialfunktionen.
Informatik II { Sommersemester 1999
2 x2 + px + q = 0 () x = ; p2 p4 ; q
Erinnerung: Bisheriger "Rekord\ ist (n log n). Aber: Dieses Resultat beruhte auf stillschweigenden Voraussetzungen.
Konkret: Die Operationen auf dem Datentyp der zu sortierenden Elemente wurden implizit als (1) angenommen.
Welche Operationen sind das: { Zuweisung einer Variable zu einer anderen, { Vergleich zweier Variablen.
207
Informatik II { Sommersemester 1999
208
Zuweisung: Kann in Java grundsatzlich als (1) an-
genommen werden (nur Referenz kopiert bei Klassentypen).
Also zu betrachten:
Beispiele:
java.lang.BigNumber
Zahlen.
fur beliebig groe ganze
Datentyp String zu sortieren nach Telefonbuchord-
Vergleich zweier Elemente
nung (lexikographisch).
In vielen Anwendungsfallen des Sortierproblems
reicht ein groenbeschrankter Datentyp wie int oder double aus, um auch die allergroten auftretenden Zahlen zu kodieren. ;! Annahme (1) Laufzeit pro Vergleich entspricht der empirischen Beobachtung der "Wachstumskurve\. Ansonsten fuhrt die Annahme (1) aber zu einer systematischen Unterschatzung der empirischen "Wachstumskurve\!
Lexikographisch zwei Strings S1 und S2
Informatik II { Sommersemester 1999
Informatik II { Sommersemester 1999
209
Algorithmus fur lexikographischen
Zeichen.
210
Lexikographischer Vergleich zweier Strings ist im allgemeinen nicht in O(1) Laufzeit moglich, sondern kann proportional zur Maximallange k0 der
public class LexStringComparator implements Comparator { public boolean isLessThan ( Object o1, Object o2 ) { String str1 = (String)o1; String str2 = (String)o2;
Strings werden.
Konsequenz: (n log n) als Gesamtlaufzeit fur Mergesort ist hier
for ( int i = 0; ; i++ ) if ( i == str2.length ) return false; else if ( i == str1.length ) return true; else if ( str1[i] < str2[i] ) return true; else if ( str1[i] > str2[i] ) return false;
nicht korrekt, sondern im Worst Case (k0 n log n).
Problem: Wenn sich die Strings im wesentlichen nur
} }
Invariante: Falls der Algorithmus bis zum Ende des i{ten Durchlaufs nicht abgebrochen wur-
de, gilt str1.length>=i, str2.length>=i sowie str1[j]==str2[j] f ur alle 0 1 am Informatik II { Sommersemester 1999
Falls S1 ein Pra x von S2 ist: S1 < S2. Falls S1 = S2 oder S2 ein Pra x von S1 ist: S1 6< S2. Ansonsten entscheidet das erste ungleiche
Beobachtung:
Stringvergleich:
Ende des i{ten Durchlaufs.
vergleichen:
j 2 f ;:::;i ; g
211
in den letzten Zeichen unterscheiden, mu jeder String mindestens einmal durchlaufen werden. ;! Es geht im Worst Case grundsatzlich nicht asymptotisch schneller als (K ), K Summe aller Stringlangen.
Frage: Geht es in (K ) Laufzeit? Informatik II { Sommersemester 1999
212
Antwort: Es geht in (K ) Laufzeit mit
Idee fur Umsetzung:
einem Algorithmus namens Bucketsort.
Ideen:
Sei k0 weiterhin die maximale Lange unter den zu
sortierenden Strings. Die einzelnen Strings kommen gema ihrer Lange erst nach und nach "ins Spiel\. Schleifeninvarianten: Nach i Durchlaufen sind { alle Strings mit Lange k0 ; i + 1 im Spiel und { untereinander nach den Zeichen mit den Indizes k0 ; i + 1; k0 ; i + 2; ::: lexikographisch sortiert.
Konsequenz: Nach k0 Durchlaufen sind alle Strings
im Spiel und lexikographisch untereinander sortiert.
Informatik II { Sommersemester 1999
213
Beispiel:
Ein "Korbchen\ (Bucket) fur jeden Buchstaben des Alphabets. Im Durchlauf Nr. i wird jeder String str, der mindestens k0 ; i + 1 Zeichen hat, in das Bucket fur Zeichen str[k0 ; i + 1] gesteckt. Die Strings mit mehr als k0 ; i + 1 Zeichen werden in der Reihenfolge ihrer bisherigen Sortierung auf die Buckets verteilt. ;! Unter Strings mit gleichem Zeichen am Index k0 ;i+1 wird die Reihenfolge aus den vorhergehenden Runden bewahrt.
Die neuen Strings (also die mit genau k0 ; i + 1
Zeichen) werden schon vor den langeren Strings auf die Buckets verteilt. ;! Pra xe werden richtig eingeordnet.
Informatik II { Sommersemester 1999
214
1. Runde: String Lange Antonio 7 Thomas 6 Andrea 6 Sabine 6 7 Eusebia Anton 5 Gerda 5 Tobias 6 7 Antonia 7 Andreas Ibrahim 7
a
Eusebia
Antonia
b c
m n o
Ibrahim
s
Andreas
Antonio
z
Informatik II { Sommersemester 1999
215
Informatik II { Sommersemester 1999
216
2. Runde: a
e
i
s
3. Runde:
Andrea
a
Andreas
b
Gerda Thomas Eusebia
e
Andrea
h
Ibrahim
n
Anton
Tobias
Sabine
Eusebia
Antonia
Thomas
Ibrahim
Andreas
Antonio
Tobias
Sabine
Antonia
Antonio
z
z
Informatik II { Sommersemester 1999
4. Runde:
a
217
Gerda Eusebia
i
Tobias
m n o
5. Runde:
Ibrahim
d e
Informatik II { Sommersemester 1999
Sabine
a b c
Tobias
d
Andrea
o
Thomas
Sabine Andreas
Thomas Anton
Antonia
r s
Antonio
t r
218
Andrea
Ibrahim
Gerda
Eusebia Anton Antonia
Antonio
Andreas
z z
Informatik II { Sommersemester 1999
219
Informatik II { Sommersemester 1999
220
6. Runde:
7. Runde:
a
Sabine
b
Ibrahim
e
Gerda
h
n o
u
Thomas
Andrea Tobias
Andreas
Anton
Antonia
a
Andrea
e
Eusebia
f g
Gerda
h i
Ibrahim
s
Sabine
t
Thomas
Andreas
Anton
Antonia
Antonio
Antonio
Eusebia
Tobias
z
z Informatik II { Sommersemester 1999
221
Implementation von Bucketsort in Java: se java.util.Vector ist im Prinzip ein Array, bei dem Elemente eingefugt und geloscht werden konnen.
Jeder Bucket kann als ein Vector{Objekt realisiert werden.
Die Buckets bilden also einen Array vom Typ mit 26 Elementen.
Arrayindex fur das Zeichen, das in der char{Variable c
gespeichert ist:
(int)(Character.toLowerCase(c)-'a')
Informatik II { Sommersemester 1999
222
Fortsetzung Implementation von Bucketsort in Java
Erinnerung: Ein Objekt der vorde nierten Klas-
Vector[]
Informatik II { Sommersemester 1999
Alle Strings werden vor der ersten "Runde\ des Kernalgorithmus durch einen Durchlauf von Bucketsort mit Buckets 1; : : : ; k0 nach Lange sortiert: 1 2 3 4 5 6 7
Anton Thomas Antonio
Gerda Andrea Eusebia
Sabine Tobias Antonia Andreas
Ibrahim
Nach jeder "Runde\ des Kernalgorithmus werden die einzelnen Buckets "von 'a' bis 'z'\ in einen separaten Vector A kopiert und von dort in der nachsten Runde wieder verteilt.
223
Informatik II { Sommersemester 1999
224
Asymptotische Laufzeit von Bucketsort:
Intuition zur letzten Gleichung:
Vorab die n Strings nach ihrer Lange sortieren: 2 O(n + k0 + K ) = O(K ).
i =
n i=
Sei ni die Anzahl der Strings mit mindestens i Zeichen.
Aufwand fur Runde Nr. i: 2 (n k ;i ). ;! Gesamtaufwand fur alle Runden: ( 0
+1)
0k 1 0k 1 X X 2 @ n k ;i A = @ niA = (K ) : 0
i=1
0
( 0
+1)
225
7 5
A n t o n T h o m a
i s
o
A n d r S a b i
a e i
e n
E u
s
e b
A n G e
t r
o d
a
n a s
A n d
r
e a
o s
I
a
h
m
b r
i i
Informatik II { Sommersemester 1999
226
Thema 10: Untere asymptotische Schranken
Merke:
Erinnerung:
Bei der Berechnung der asymptotischen Lauf-
Mergesort lost das generische Sortierproblem in (n log n T ) Zeit (T der durchschnittliche Auf-
zeit eines generischen Algorithmus (z.B. Sortieralgorithmen wie Mergesort) mu immer mitberucksichtigt werden, da die Basisoperationen auf unterschiedlichen Datentypen unterschiedliche asymptotische Laufzeit haben konnen. Fur den wichtigen Spezialfall des allgemeinen Sortierproblems, da Strings lexikographisch zu sortieren sind, erreicht Bucketsort im Gegensatz zu Mergesort optimale asymptotische Laufzeit im Worst Case (namlich asymptotisch aquivalent zur Gesamtsumme aller Stringlangen).
Informatik II { Sommersemester 1999
6 9
T o b i a A n t o n
i=1
Informatik II { Sommersemester 1999
1 2 3 4 5 11 11 11 11 11
wand pro Vergleichsoperation). Bucketsort ist mit (K ) asymptotisch optimal fur die lexikographische Sortierung von Strings.
Beobachtung: Mit Bucketsort lassen sich z.B. auch ganze Zahlen sortieren: als "Strings\ von Ziern.
Interessante Fragen: Ist (n log n T ) allgemein das letzte Wort?
Kann man diesen "Rekord\ mit Bucketsort zumin-
dest fur gewisse Datentypen und Sortierordnungen unterbieten?
227
Informatik II { Sommersemester 1999
228
Grundsatzliche Grenze: Um n unterschiedliche Werte eines beliebigen Datentyps als Strings mit k verschiedenen Zeichen zu kodieren, werden mindestens blogk nc Zeichen pro String im Durchschnitt benotigt.
;! In Bitdarstellung also mindestens blog2 nc.
Idee zum Beweis der grundsatzlichen Grenze: Alle
Strings lassen sich zusammen zu einem Digitalbaum mit n Endknoten "%\ verschmelzen.
Beispiel aus der Behandlung von Bucketsort:
Konsequenzen: aus dieser grundsatzlichen Grenze: Besser als (n log n) kann Bucketsort im Worst
Case selbst bei optimaler Kodierung der zu sortierenden Daten nicht werden. Auch kein anderer Algorithmus, weil im Worst Case sicher alle (n log n) Bits mindestens einmal angeschaut werden mussen. Aber immerhin: Mergesort konnte bei lexikographischer Sortierung von Strings nicht einmal besser als (n log2 n) werden.
Informatik II { Sommersemester 1999
229
A
E
G
I
S
n
u
e
b
a
s
r
r
b
o
b
o
e
d
a
i
m
i
n
b
a
h
n
a
a
i
%
i
e
s
s
%
%
t
d r e a s %
i %
%
a
o
a
m
%
%
%
%
T h
Informatik II { Sommersemester 1999
o
%
230
Beispiel zur hilfreichen Beobachtung (k = 2):
Grundsatzliche Grenze folgt nun aus folgender
Hilfsbehauptung: Bei einem Baum mit n Endknoten (Blattern) und maximal k Nachfolgern pro Knoten ist
die durchschnittliche Hohe aller Endknoten mindestens blogk nc.
Hilfreiche Beobachtung: Durch Balancierung des Baumes kann die durchschnittliche Hohe der Endknoten nur besser werden.
Informatik II { Sommersemester 1999
231
!
Informatik II { Sommersemester 1999
232
Weiter: in einem optimal balancierten Baum mit m = k` Endknoten hat jeder Endknoten Hohe ` = logk(m).
Zusammenfassung: Wegen (log n) oder mehr pro Vergleich ist nichts Besseres als (n log n) beim Sortieren im Worst Case drin.
Anschlufrage: Kann unter der idealisierten Annahme, da ein Vergleich zweier Elemente nur (1) Zeit kostet, besser als in (n log n) Laufzeit sortiert werden?
;! In einem optimal balancierten Baum mit m Endknoten, k`;1 < m k`, hat jeder Endknoten Hohe ` ; 1 = blogk (m)c oder ` = dlogk (m)e:
Methodisches Problem:
Die Anschlufrage bezieht sich nicht auf einen kon-
kreten Algorithmus, sondern auf die (unendlich groe!) Menge aller uberhaupt nur denkbaren Sortieralgorithmen. Kann man daruber uberhaupt irgendwelche Aussagen treen?
;! Hilfsbehauptung bewiesen. Informatik II { Sommersemester 1999
233
Konkretisierung der Fragestellung:
Erinnerung: Im generischen Sortierproblem (Vorle-
sungsthema 2) war nichts uber den Elementtyp bekannt abgesehen von der Vergleichsoperation "\. Dies scheint auch der einzige gemeinsame Nenner aller moglichen De nitionen von Datentyp und "\ zu sein.
Ein wahrhaft generischer Sortieralgorithmus hat also
keine Information uber die zu sortierenden Elemente abgesehen von der Antwort true/false durch Anwendung von "\ auf Paare von Elementen. Und das auch nur als "Black Box\, d.h. ohne Einsicht in das Wesen von "\ Im Gegensatz etwa zur Ausnutzung des Wesens von lexikographischer Reihenfolge im nichtgenerischen Algorithmus Bucketsort.
Konkretisierte Frage: Kann ein Algorithmus, der nur
Informatik II { Sommersemester 1999
234
Antwort: Wenn Datentyp T unendlich gro ist, ist im Worst Case nichts Besseres als (n log n) moglich. Beweisidee:
Seien a1; : : : ; an 2 T paarweise verschieden mit a1 a2 an. Fur jede Permutation (a(1); : : : ; a(n)) von
(a1; : : : ; an) als Eingabe durchlauft der Algorithmus eine charakteristische Folge von Anwendungen von "\.
Fur je zwei Permutationen mussen diese Folgen irgendwo auseinanderlaufen. ;! Binare Baumstruktur (Vergleichsbaum).
auf paarweisen Vergleichen (also Anwendungen von beruht, mit weniger als (n log n) Vergleichen "\) im Worst Case auskommen? Informatik II { Sommersemester 1999
235
Informatik II { Sommersemester 1999
236
Beispiel: Ausschnitt aus dem Vergleichsbaum fur Mergesort auf vier Elementen.
Fortsetzung Beispiel: Durchlauf durch einen einzelnen Zweig des Vergleichsbaums 2 4
1
3
a1 a2 a3 a4 2
4
1
3
a 1 < a2 ? nein
ja
2
ja
ja
nein
a1 < a3? ja
1
3
nein
1
2
2
3 4
a1 < a4 ? nein
a2 < a3?
ja
4
1
3
2< 4 ? nein
1. Stufe links
ja
a1 < a4 ? nein
ja
a2 < a4 ?
a2 < a4 ?
ja
4
a3 < a4 ?
a3 < a4 ?
1 0, so da c1 n Tn c2 n fur alle n 2 N gilt. Frage: Geht es besser? Informatik II { Sommersemester 1999
263
Informatik II { Sommersemester 1999
264
Erlauterung: Ein Objekt dieser Klasse garan-
Ansatz:
Die Arrays sind sortiert nach den Schlusselwerten. Voraussetzung: Irgendeine Sortierreihenfolge ist auf
den Schlusselwerten de niert. Realisierung: Wie ublich mit Implementationen von Interface Comparator.
cmp.isLessThan(theKeys[i-1],theKeys[i])==true
get geht nun in (log n) Zeit im Worst Case mit binarer Suche.
Vorteil: Methode
public Object get ( Object key ) { if ( theKeys == null ) return null; int first = 0; int afterLast = theKeys.length; while ( afterLast - first > 1 ) { int median = ( afterLast - first ) / 2; if ( cmp.isLessThan(key,theKeys[median]) ) afterLast = median; else first = median; } if ( theKeys[first] == key ) return theInfos[first]; else return null; }
Realisierung: public class SortedArrayDictionary extends Dictionary { private Object[] theKeys; private Object[] theInfos; private Comparator cmp; public SortedArrayDictionary ( Comparator cmp ) { this.cmp = cmp; } ... }
Informatik II { Sommersemester 1999
tiert als zusatzliche Konsistenzbedingung gegenuber ArrayDictionary, da f ur alle i==1...theKeys.length-1 gilt:
265
Analyse der binaren Suche:
Informatik II { Sommersemester 1999
266
Weitere Methoden von SortedArrayDictionary:
Schleifeninvariante: Vor und nach jedem Durchlauf (auch dem letzten!) gilt: { afterLast > first. { Wenn key uberhaupt in theKeys gespeichert ist, dann an einem der Indizes first...afterLast-1.
Methode put darf das neue Element nicht einfach ans Ende hangen, sondern mu es an der richtigen Position im Array einfugen:
Schleifenvariante: Die Dierenz afterLast - first
wird in jedem Durchlauf ungefahr\ halbiert (genaues "Erbsenzahlen\ "ausgelassen).
Alle anderen Methoden konnen unmittelbar von ArrayDictionary
;! Ungefahr log2 n Durchlaufe im Worst Case.
ebenso die Enumerationsklasse ArrayEnumeration.
;! (log n) Laufzeit im Worst Case. Informatik II { Sommersemester 1999
ubernommen werden,
267
Informatik II { Sommersemester 1999
268
Bemerkung:
Alternative: Verzeigerungsstrukturen
Hier behandelte Variante erreicht auch im Best Case
Motivation: SortedArrayDictionary braucht wie ArrayContainer (n) Laufzeit f ur's Einfugen und
nichts Besseres als (log n) Laufzeit.
Einfache Variation erreicht (1) im Best Case: Prufe einfach nach jeder Berechnung von median, ob median nicht schon das gesuchte Element ist.
Ware vorteilhaft, falls die 50%, 25%, 75%{Quantile etc. besonders hau g auftreten. ;! Nicht sehr realistisch.
Fur eigentlich jede realistische De nition der Hau g-
keitsverteilung ist der Average Case aber auch mit dieser Modi kation nicht besser als (log n).
Loschen eines Elements.
In Anwendungen, in denen die Schlusselmenge im wesentlichen konstant bleibt und nur andauernd get aufgerufen wird, ist das eigentlich kein Problem.
Fur andere Anwendungen mu man aber noch mehr tun.
Konkrete technische Hurde:
Arrays konnen nicht beliebig wachsen oder schrumpfen.
Auch Verwendung von java.util.Vector lost das
Problem nicht: Methoden wie addElement haben intern mehr Aufwand als man denkt!
Informatik II { Sommersemester 1999
269
Andere Idee:
270
Idee: Je eine verzeigerte Liste fur Schlusselwerte und Informationen.
Die einzelnen Schlussel (bzw. Infos) sind
nicht mehr Komponenten von Arrays, sondern eigenstandige, "freischwebende\ Objekte und untereinander durch "Querreferenzen\ verzeigert.
Konsistenzbedingungen:
Beide Listen sind gleich lang. Der Schlusselwert und die Information eines Paares
sind in theKeys bzw. theInfos an der gleichen Position gespeichert. Das letzte Listenelement verweist auf null anstelle eines nachsten Elements.
Vorbetrachtung: Lineare Verzeigerung.
value
Hilfsmittel: class Item { public Item public Object }
Informatik II { Sommersemester 1999
null
theKeys next next; value;
value
Java{Package!
Informatik II { Sommersemester 1999
null
theInfos
Beachte: Zugri reduziert auf's eigene
next 271
Informatik II { Sommersemester 1999
272
In Java:
Intuition zu get: Situation nach zwei Durchlaufen durch die Schleife.
public class LinearLinkedDictionary { private Item theKeys; private Item theInfos;
currentKey
public Object get ( Object key ) { Item currentKey = theKeys; Item currentInfo = theInfos; while ( true ) { if ( currentKey == null ) return null; if ( currentKey.value == key ) return currentInfo.value; currentKey = currentKey.next; currentInfo = currentInfo.next; } }
null
theKeys
currentInfo theInfos
null
... }
Informatik II { Sommersemester 1999
273
Informatik II { Sommersemester 1999
274
Realisierung von LinearLinkedDictionary.put: Ideen fur LinearLinkedDictionary.put:
Beide Listen werden wie in get schrittweise simultan
durchlaufen. Falls key dabei gefunden: Wie ublich Information uberschreiben und alte Information zuruckliefern. Ansonsten wird ein neues Paar (key,info) vorne an theKeys und theInfos angef ugt. Warum vorne und nicht hinten oder irgendwo mittendrin? Antwort: Technisch einfacher. Dadurch vermiedene Komplikationen: Kommen unmittelbar im Anschlu an die Behandlung von LinearLinkedDictionary in der Variation SortedLinearLinkedDictionary zum Vorschein.
Erinnerung:
Nach "new Item()\ gilt value==null und (der entscheidende Punkt:) next==null. Informatik II { Sommersemester 1999
275
public Object put ( Object key, Object info ) throws NullPointerException { if ( key == null || info == null ) throw new NullPointerException(); if ( theKeys == null ) { theKeys = new Item(); theKeys.value = key; theInfos = new Item(); theInfos.value = info; return null; } Item currentKey = theKeys; Item currentInfo = theInfos; while ( currentKey != null ) { if ( currentKey.value == key ) return currentInfo.value; currentKey = currentKey.next; currentInfo = currentInfo.next; } Item newKey = new Item(); // *** newKey.value = key; newKey.next = theKeys; theKeys = newKey; // +++ Item newInfo = new Item(); newInfo.value = info; newInfo.next = theInfos; theInfos = newInfo; return null; }
Informatik II { Sommersemester 1999
276
Ideen fur LinearLinkedDictionary.remove:
Intuition zu "***\ bis "+++\
Beide Listen werden wie in get schrittweise simultan
Ausgangsliste theKeys:
null
theKeys
Nach "newKey.next
= theKeys\:
newKey
null
theKeys
Nach "theKeys
= newKey\:
newKey
theKeys
Informatik II { Sommersemester 1999
null
277
Informatik II { Sommersemester 1999
278
Intuition:
Realisierung:
Fur den Fall "theKeys.value
public Object remove ( Object key ) { if ( theKeys == null ) return null; if ( theKeys.value == key ) { Item returnValue = theInfo.value; theKeys = theKeys.next; theInfos = theInfos.next; return returnValue; } Item keyBeforeCurrent = theKeys; Item infoBeforeCurrent = theInfos; while ( keyBeforeCurrent.next != null ) { if ( keyBeforeCurrent.next.value == key ) { Object returnValue = infoBeforeCurrent.next.value; keyBeforeCurrent.next = keyBeforeCurrent.next.next; infoBeforeCurrent.next = infoBeforeCurrent.next.next; return returnValue; } } return null; }
Informatik II { Sommersemester 1999
durchlaufen. Falls key dabei nicht gefunden: Wie ublich null zuruckliefern. Ansonsten: Das jeweils "richtige\ Element aus jeder der beiden Listen "ausklinken\. Das heit: { Falls das erste Element zu entfernen: Einfach theKeys auf theKeys.next bzw. theInfos auf theInfos.next umbiegen\. " { Falls ein anderes Element zu entfernen ist: Dieses Element in beiden Listen "uberbrucken\. ;! Ein Verweis zum vorhergehenden Element wird benotigt. ;! Beim Durchlauf durch die Liste mu man immer "einen Schritt zuruckbleiben\.
Nach "theKeys
== key\.
= theKeys.next\:
null
theKeys
Fur den Fall, da
keyBeforeCurrent.next.value == key\ "z.B. im ersten Durchlauf durch die while{Schleife schon erreicht wird. Konkret nach "keyBeforeCurrent.next = keyBeforeCurrent.next.next\: keyBeforeCurrent theKeys
279
Informatik II { Sommersemester 1999
null
280
Frage: Was passiert mit den "ausgeklinkten\ Elementen (den grauen auf der letzten Folie)?
Antwort:
Diese Objekte sind vom Programm aus nicht mehr
ansprechbar, da alle Verweise darauf "umgebogen\ wurden. Problem: Wenn laufend Elemente mit new neu erzeugt und wieder ausgeklinkt werden, besteht bald der gesamte verfugbare Speicherplatz aus solchen "Leichen\. ;! Nichts geht mehr. Losung in Java: Solche Objekte werden fruher oder spater durch einen sogenannten Garbage Collector aufgesammelt, und ihr Speicherplatz kann in new wiederverwendet werden. Garbage Collector: Unsichtbarer, unkontrollierbarer Zusatzthread, der von Zeit zu Zeit automatisch aufwacht und diese "Leichen\ einsammelt. Informatik II { Sommersemester 1999
281
Zugehorige Enumerationsklasse: public class LinearLinkedEnumeration implements Enumeration { private Item currentItem; public LinearLinkedEnumeration ( Item theItems ) { currentItem = theItems; } public bool hasMoreElements () { return currentItem != null; } public Object nextElement () throws NoSuchElementException { if ( ! hasMoreElements() ) throw new NoSuchElementException(); Object returnValue = currentItem.value; currentItem = currentItem.next; return returnValue; } }
Informatik II { Sommersemester 1999
282
Konsistenzbedingung:
Variation "sortierte Liste\
Verweis currentItem zeigt auf das erste noch nicht durch Methode nextElement zuruckgelieferte Element.
Notwendig ist wieder einmal eine Sortierreihenfolge
;! Konstrast zu ArrayEnumeration.currentIndex!
(Klasse SortedLinearLinkedDictionary): auf den Schlusselwerten. ;! Analog zu SortedArrayDictionary ein Comparator{Objekt cmp, das im Konstruktor von SortedLinearLinkedDictionary ubergeben wird. Weitere Konsistenzbedingung gegenuber LinearLinkedDictionary: theKeys ist nach der cmp{Reihenfolge aufsteigend sortiert.
Beobachtung: { Methoden
get und remove LinearLinkedDictionary
konnen sofort von ubernommen wer-
den, { ebenso LinearLinkedEnumeration, { nur Methode put mu neu implementiert werden. Informatik II { Sommersemester 1999
283
Informatik II { Sommersemester 1999
284
Ideen fur SortedLinearLinkedDictionary.put:
Realisierung mit Zusatzmethode
Falls das Dictionary momentan leer ist: Zu einer Liste mit einem einzelnen Element machen.
Falls ansonsten key kleiner als der kleinste momentan gespeicherte Schlussel ist: ;! Wieder vorne einfugen.
Ansonsten: Direkt hinter dem groten Schlussel, der kleiner als key ist. Das heit: Unmittelbar zwischen currentKey.next, falls
{
currentKey
und
cmp.isLessThan (currentKey.value, key) == true und
{ entweder currentKey.next
== null oder cmp.isLessThan (key, currentKey.next.value) == false.
Informatik II { Sommersemester 1999
285
Zusatzmethode
public Object put ( Object key, Object info ) throws NullPointerException { if ( key == null || info == null ) throw new NullPointerException(); if ( theKeys == null ) { // Wie in LinearLinkedDictionary.put // (einschl. return) } if ( cmp.isLessThan(key,theKeys.value) ) { // Vorne einfuegen wie in // LinearLinkedDictionary.put // und dann return } return insert ( key, info ); }
Informatik II { Sommersemester 1999
286
Intuition:
SortedLinearLinkedDictionary.insert:
Nach "newKey.next
public Object insert ( Object key, Object info ) { Item currentKey = theKeys; Item currentInfo = theInfos; while ( currentKey.next != null && cmp.isLessThan(key,currentKey.next.value) ) { currentKey = currentKey.next; currentInfo = currentInfo.next; } if ( currentKey.next != null && key == currentKey.next.value ) return currentInfo.next.value; Item newKey = new Item(); newKey.value = key; newKey.next = currentKey.next; currentKey.next = newKey; Item newInfo = new Item(); newInfo.value = info; newInfo.next = currentInfo.next; currentInfo.next = newInfo; }
Informatik II { Sommersemester 1999
SortedLinearLinkedDictionary.insert:
= currentKey.next\:
currentKey null
theKeys
newKey
Nach "currentKey.next
= newKey\:
currentKey null
theKeys
newKey
287
Informatik II { Sommersemester 1999
288
Thema 13: Baumartige Implementationen von Dictionaries ("Suchbaume\)
Merke:
Bei einer "naiven\ Implementation von Dic-
Hilfsmittel anstelle von Klasse Item:
tionaries durch Arrays ergibt sich (n) Aufwand fur Suchen im Worst Case und generell fur Einfugen und Loschen im Best und Worst Case. Bei sortierten Arrays kann der Aufwand speziell fur Suchen durch binare Suche auf (log n) im Worst Case reduziert werden. Bei einer Implementation mit linearen Listen ergibt sich (1) fur das Einfugen im Best und Worst Case, aber (n) im Worst Case fur Suchen und Loschen. Bei sortierten Listen ist sogar alles (n) im Worst Case.
Informatik II { Sommersemester 1999
class TreeNode { Object value; TreeNode left; TreeNode right; }
Idee: Jedes Element hat nun zwei unmittelbare Nachfolger. ;! Binarer Baum anstelle einer linearen Liste. Wieder Sortierreihenfolge vorausgesetzt!
289
Intuition:
Informatik II { Sommersemester 1999
290
Konsistenzbedingungen:
Es gibt einen einzigen "Einstiegsknoten\, die Wurzel (root) des Baumes.
value left right
value left right
Auf jeden Baumknoten auer der Wurzel gibt es genau einen Verweis Knoten des Baumes.
value left right
left
oder
right
von einem
Jeder Baumknoten ist von der Wurzel aus durch eine Sequenz von Schritten uber left- und right{ Verweise aus erreichbar.
Fur jeden Baumknoten
node haben alle Baumknoten im linken Nachfolgerbaum echt kleineren Schlusselwert als node.value und alle Baumknoten im rechten Nachfolgerbaum echt groeren Schlusselwert.
Informatik II { Sommersemester 1999
291
Informatik II { Sommersemester 1999
292
Konsequenz:
Methode get kann sich von oben nach unten von
Knoten zu Knoten "durchhangeln\. In jedem Baumknoten treeNode wird treeNode.value verglichen: { gleich ;! gefunden und stop, { kleiner ;! nach links weiter, { groer ;! nach rechts weiter.
key
mit
Java{Implementation: public class TreeDictionary { private TreeNode rootOfKeys; private TreeNode rootOfInfos; private Comparator cmp; public TreeDictionary ( Comparator cmp ) { this.cmp = cmp; } ...
Methode TreeDictionary.get: public Object get ( Object key ) { TreeNode currentKey = rootOfKeys; TreeNode currentInfo = rootOfInfos; while ( true ) { if ( currentKey == null ) return null; if ( currentKey.value == key ) return currentInfo.value; if ( cmp.isLessThan(key,currentKey.value) ) { currentKey = currentKey.left; currentInfo = currentInfo.left; } else { currentKey = currentKey.right; currentInfo = currentInfo.right; } } }
}
Informatik II { Sommersemester 1999
293
Idee fur TreeDictionary.put:
Wie in aus.
get
294
Realisierung mit Zusatzmethode
schrittweiser Abstieg von der Wurzel
Falls
key dabei gefunden: Wie u blich Information uberschreiben und alte Information zuruckliefern.
Vor dem Abstieg zum jeweils nachsten Baumknoten: { Prufen, ob dieser Baumknoten uberhaupt exi-
stiert. { Falls nicht: Genau an dieser Leerstelle den neuen Baumknoten einhangen.
Informatik II { Sommersemester 1999
Informatik II { Sommersemester 1999
295
TreeDictionary.insert:
public Object put ( Object key, Object info ) throws NullPointerException { if ( key == null || info == null ) throw new NullPointerException(); if ( rootOfKeys == null ) { // Wie bei LinearLinkedDictionary.put // (einschl. return-Anweisung) } return insert (key, info); }
Informatik II { Sommersemester 1999
296
Zusatzmethode TreeDictionary.insert: Idee fur TreeDictionary.remove:
public Object insert ( Object key, Object info ) { TreeNode currentKey = rootOfKeys; TreeNode currentInfo = rootOfInfos; while ( true ) { if ( cmp.isLessThan(key,currentKey.value) ) if ( currentKey.left == null ) { { currentKey.left = new TreeNode(); currentKey.left.value = key; currentInfo.left = new TreeNode(); currentInfo.left.value = key; return null; } else { currentKey = currentKey.left; currentInfo = currentInfo.left; } else if ( cmp.isLessThan(currentKey.value,key) ) // Analog else // d.h. falls key == currentKey.value { Object oldInfo = currentInfo.value; currentInfo.value = info; return oldInfo; } } }
Informatik II { Sommersemester 1999
Das zu loschende Paar (key,info) wieder schritt-
weise von oben nach unten in theKeys und theInfos simultan suchen. Wie bei Listen die Verweise currentKey und currentInfo immer einen Knoten zur uckhinken\ lassen, damit der Verweis auf den zu" entfernenden Baumknoten manipuliert werden kann. Falls nicht gefunden: Wie ublich ohne weitere Aktion null zur uckliefern. Sonst drei Falle fur die gefundenen Baumknoten currentKey und currentInfo separat betrachten: { keine unmittelbaren Nachfolgerknoten, { ein unmittelbarer Nachfolgerknoten, { zwei unmittelbare Nachfolgerknoten.
297
Fallbehandlung:
hat zwei unmittelbare Nachfolger.
;!
Knoten 2
null
A
A null
Beobachtung: Wenn ein Baumknoten einen rechten Nachfolger hat (z.B. Knoten 2), dann liegt der Baumknoten mit dem nachsthoheren Schlusselwert im rechten Nachfolgerbaum und hat selbst keinen linken Nachfolger (Knoten 5).
Knoten 1
Knoten 1
298
Noch zu behandeln: Der zu loschende Baumknoten
Keine unmittelbaren Nachfolgerknoten ;! umstandslos loschen. currentKey
Informatik II { Sommersemester 1999
null
Knoten 1
Genau ein unmittelbarer Nachfolgerknoten ;! wie bei Listen durch den Nachfolgerkno-
Knoten 2
E
ten ersetzen.
Knoten 4
Knoten 3 Knoten 1
Knoten 1
currentKey
Knoten 3
Knoten 2
C null
Knoten 3
C
;!
A
D
B Knoten 5
A
B null
A
C
B
Informatik II { Sommersemester 1999
299
Informatik II { Sommersemester 1999
300
Losung:
Weiteren Verweis beforeNextHigherKey bis zum
unmittelbaren Vorganger von Knoten 5 weiter absteigen lassen. Wert value von Knoten 2 wird mit dem Inhalt von Knoten 5 uberschrieben. Knoten 5 wird anstelle von Knoten 2 gema 2. Fall ausgeklinkt.
Konsequenzen:
Genau die richtigen Werte verbleiben im Baum. Die Konsistenzbedingungen fur die Baumstruktur und die Sortierreihenfolge werden aufrechterhalten.
Knoten 1
beforeCurrentKey
Knoten 2
E Knoten 4
Knoten 3
beforeNextHigherKey
A
D
B Knoten 6
Knoten 5
F null
C
Informatik II { Sommersemester 1999
301
Enumeration auf binaren Baumen: Durch Fadelung der Baumknoten.
Informatik II { Sommersemester 1999
302
Genauere Erlauterungen:
Jeder Baum hat eine weitere Objektvariable realRight
vom Typ boolean.
Bedeutung: realRight null
null
null
null
null
null
null
== true, falls right auf einen "richtigen\ Nachfolgerknoten zeigt oder right == null ist (durchgezogene Pfeile in der Zeichnung auf der letzten Folie).
null null
Es gilt right ten.
Erste Erlauterung:
Abgesehen vom Knoten mit dem allerhochsten
Schlusselwert zeigt Objektvariable right bei jedem Baumknoten auf einen anderen Baumknoten. Der Zielknoten eines right{Verweises hat immer hoheren Schlusselwert als der Knoten, von dem der right{Verweis ausgeht. Die neuen Ruckwartsverweise zeigen sogar immer auf den Baumknoten mit dem nachsthoheren Schlusselwert. Informatik II { Sommersemester 1999
303
== null
nur beim allerletzten Kno-
Suchen, Einfugen, Loschen: Verweis nicht weiter verfolgt, falls realRight
right wird == false.
Beim Einfugen und Loschen mu der betroe-
ne Baumknoten korrekt "ein-/ausgefadelt\ werden (hier nicht genauer behandelt).
Informatik II { Sommersemester 1999
304
Java{Implementation:
Enumeration in Sortierreihenfolge:
Allererster Baumknoten: Soweit wie moglich von der
Wurzel aus nach links absteigen. Jeweils nachster Baumknoten nach dem aktuellen Baumknoten currentNode: { Zuerst uber right einen Schritt weitergehen. { Falls das ein "echter\ Verweis auf einen Nachfolger war (durchgezogener Pfeil): Danach noch soweit wie moglich nach links weiter absteigen. Konsistenzbedingung: Wie bei LinearLinkedDictionary.
null
null
null
null
null
null
null
public class TreeEnumeration implements Enumeration { private TreeNode currentNode; public TreeEnumeration ( TreeNode rootOfTree ) { currentNode = rootOfTree; while ( currentNode.left != null ) currentNode = currentNode.left; } public boolean hasMoreElements () { return currentNode != null; } public Object nextElement () throws NoSuchElementException { if ( ! hasMoreElements() ) throw new NoSuchElementException(); Object returnValue = currentNode.value; boolean descendLeft = currentNode.realRight; currentNode = currentNode.right; if ( currentNode != null && descendLeft ) while ( currentNode.left != null ) currentNode = currentNode.left; return returnValue; }
null null
}
Informatik II { Sommersemester 1999
305
Frage: Was ist denn nun gewonnen durch U bergang von linearer zu binarer Struktur?
Antwort: Zunachst einmal noch gar nichts, weil der
Baum im Worst Case zu einer linearen Liste entarten kann.
Informatik II { Sommersemester 1999
306
Erinnerung: Ein balancierter Baum hat Hohe log2 n.
;! Eine einzelne Such-, Einfuge- oder Loschoperation kostet (log n) Zeit.
Knoten 1
null
Knoten 2
null
Knoten 3
null null null null null null null null null null null null null null null null
null
Aber: Jede Einfuge- oder Loschoperation kann den
Baum potentiell ein kleines Stuck weiter aus der Balance bringen. ;! Auf Dauer doch wieder (n) im Worst Case.
Knoten n
null
Informatik II { Sommersemester 1999
null
307
Informatik II { Sommersemester 1999
308
Idee: Wenn man es schaen wurde,
beim Einfugen und Loschen eine gewisse Balance zu
halten, so da der Zusatzaufwand fur dieses Balancehalten aber immer noch (log n) pro Einfuge-/Loschoperation bleibt, dann ist (log n) pro Such-/Einfuge-/Loschoperation bis in alle Ewigkeit garantiert (n die momentane Groe des Dictionaries zum Zeitpunkt der Operation).
Denkbare Kandidaten (inspiriert aus dem optimal
balancierten Fall): Fur jeden Baumknoten unterscheiden sich die Knotenzahlen im linken und rechten Nachfolgerbaum (A und B ) nicht sonderlich. Die Hohen von A und B unterscheiden sich nicht sonderlich.
Problem: Optimale Balance kann man anscheinend nicht durchhalten. ;! Gesucht ist eine schwachere De nition von Balance. Stark genug, um (log n) pro Operation zu garantieren.
Schwach genug, um mit (log n) Aufwand pro Operation aufrechterhalten zu werden.
Informatik II { Sommersemester 1999
A 309
Informatik II { Sommersemester 1999
B 310
Tiefe Einsicht: Die Eigenschaft, da sich fur jeden Baumknoten die Hohen der beiden Nachfolgerbaume im Betrag um maximal 1 unterscheiden, ist geeignet.
Vorabbetrachtung: In einem Baum mit n Knoten gibt
Stichwort in der Literatur: Ein Suchbaum mit dieser Eigenschaft ist ein AVL{Baum.
Beweis: Mit vollstandiger Induktion uber die Knotenzahl n 1.
Behauptung: Ein AVL{Baum mit n Knoten hat Hohe (log n).
n = 1: 1 Blatt, kein innerer Knoten. n > 1: Sowohl der linke als auch der rechte Teilbaum
Beweis: Nachste sechs Folien.
Informatik II { Sommersemester 1999
311
es mehr Blatter als innere Knoten (d.h. Knoten, die keine Blatter sind).
der Wurzel hat jeweils fur sich mehr Blatter als innere Knoten. ;! Fur beide Teilbaume zusammengezahlt ist die Blatterzahl um mindestens 2 hoher als die Anzahl innerer Knoten. ;! Zusammen mit der Wurzel immer noch mehr Blatter als innere Knoten.
Informatik II { Sommersemester 1999
312
Nun Beweisansatz fur die Behauptung, da AVL{
Baume logarithmische Hohe haben
Zunachst: Besser als O(log n) geht nicht, da ein optimal balancierter Baum mit n Knoten (vgl. Thema 10)
Hohe dlog2(n)e hat und kein anderer binarer Baum mit n Knoten geringere Hohe hat.
Fortsetzung Beweis: Zu gegebener Hohe h betrachte die AVL{Baume mit Hohe h, die minimale Knotenzahl
haben. ;! Heien in der Literatur Fibonacci{Baume. Beobachtung: Bei jedem Baumknoten unterscheiden sich in diesem Fall die Hohen beider Nachfolgerbaume im Betrag um genau 1. (Sonst konnte man noch einen geeignet gewahlten Knoten wegnehmen, ohne da sich die Gesamthohe h verringert oder die AVL{Eigenschaft verletzt wird.)
;! Es reicht, O(log n) anstelle von (log n) zu zeigen.
Informatik II { Sommersemester 1999
313
Konsequenz: Rekursionsformel fur die Knotenzahl n(h) eines Fibonacci{Baumes mit Hohe h.
81 < n(h) = : 2 1 + n(h ; 1) + n(h ; 2)
fur h = 0; fur h = 1; fur h > 1:
314
Zwischenstand: AVL{Baume mit Hohe h haben mindestens fib(h) Knoten. Aber: Eigentlich interessierte uns
nicht die Minimalknotenzahl in Abhangigkeit von
Hilfsbehauptung: Fur alle h 2 N gilt fib(h) n(h). Begrundung: Vergleich der beiden Rekursionsformeln fur n(h) bzw. fib(h). Bemerkung: Eine einfache vollstandige Induktion zeigt zudem n(h) 3 fib(h) ; 1.
;! Daher Begrisbildung Fibonacci{Baum. Informatik II { Sommersemester 1999
Informatik II { Sommersemester 1999
315
der Hohe, sondern umgekehrt die Maximalhohe in Abhangigkeit von der Knotenzahl.
Also: Umkehrabbildung betrachten.
Kleines technisches Problem: Es gibt nicht um-
gekehrt zu jeder Knotenzahl m eine Hohe h mit n(h) = m. Losung: Fur m 2 N sei H (m) die grote Zahl h mit n(h) = n(H (m)) m. ;! Die Hohe eines AVL{Baumes mit m Knoten ist hochstens H (m). Informatik II { Sommersemester 1999
316
Bisher erreicht: Abschatzung (log m) im Best und Worst Case fur die Hohe von AVL{Baumen mit m
Zwischenstand auf der letzten Folie besagte: n(h) fib(h).
Knoten.
Erinnerung: fib(k) 2 ((1:618:::)k).
Fehlt noch: Realisierungen von put und remove, die
;! Es gibt Konstanten m0 2 N und c > 0, so da fur alle m m0 gilt:
jeden AVL{Baum garantiert wieder in einen AVL{Baum uberfuhren.
m n(H (m)) fib(H (m)) c (1:618:::)H (m)
Beobachtung:
Wenn ein einziger Knoten eingefugt oder entfernt
;! H (m) log(1:618:::)( 1c m)
wird, kann die Hohendierenz von linkem und rechtem Teilbaum nirgendwo um mehr als 1 verletzt werden, und das auch nur entlang des Baumpfades von der Wurzel bis zum eingefugten bzw. geloschten Knoten.
;! H (m) 2 O(log m) ;! Beweis fertig.
Informatik II { Sommersemester 1999
317
Informatik II { Sommersemester 1999
318
Fall I: A ist mindestens so hoch wie B .
Basistechnik:
Rotation an einem einzelnen Baumknoten
;! Einfachrotation:
Annahmen
(ohne Beschrankung der Allgemeinheit): Die AVL{Eigenschaft ist fur alle Knoten in A, B und C erfullt. Der linke Nachfolgerbaum von Knoten 1 (also "Knoten 2\ + A + B ) hat eine um 2 groere Hohe als C .
Knoten 1
Knoten 2
Knoten 1
C A
Knoten 1
Knoten 2
B
A B
C
Ergebnis: Knoten 1 und alle seine unmittelbaren und mittelbaren Nachfolger erfullen die AVL{Eigenschaft.
Knoten 2
C A Informatik II { Sommersemester 1999
B 319
Informatik II { Sommersemester 1999
320
Fall II: ("Knoten 3\ + B + C ) ist um 1 hoher als A.
;! Doppelrotation:
AVL{Baumen:
Zuerst neues Element einfugen bzw. altes Element
Knoten 1
loschen wie bei TreeDictionary.
Knoten 3
Knoten 2
Danach jeweils AVL{Eigenschaft wieder an allen
Knoten 2
Knoten herstellen.
Knoten 1
Erinnerung: Nur die Knoten auf dem Baumpfad zum
D
eingefugten/geloschten Element sind betroen.
Knoten 3
A
A B
Anwendung beim Einfugen und Loschen in
B
C
D
{ Der Pfad wird von unten nach oben (also
C
"ruckwarts\) durchlaufen. { Jeder Knoten, an dem die AVL{Eigenschaft verletzt ist, wird durch Einfach- bzw. Doppelrotation wieder in Balance gebracht.
Ergebnis: Wieder AVL{Eigenschaft uberall
erfullt.
Informatik II { Sommersemester 1999
Konkrete Vorgehensweise:
321
Informatik II { Sommersemester 1999
322
Technisches Problem:
Beobachtung:
Woher sind bei einem Baumknoten die Hohen der
Bei einer Rotation andern sich diese Dierenzen
beiden Nachfolgerbaume bekannt?
Jeweils bei Bedarf berechnen wurde ja wohl alle Bemuhungen um etwas Besseres als (n) pro Operation zunichte machen.
Hilfreiche Einsicht:
Die Hohen werden eigentlich gar nicht gebraucht,
sondern nur die Dierenz von linkem und rechtem Nachfolgerbaum.
nur in den 2 bzw. 3 rotierten Knoten sowie in den unmittelbaren und mittelbaren Vorgangerknoten. Unter den rotierten Knoten sind die A nderungen nach einfachen Regeln und in (1) Zeit berechenbar. Die A nderungen bei den hoheren Knoten konnen aufgeschoben und beim Durchlaufen des Baumpfades von unten zur Wurzel "mitgeschleppt\ werden (Details hier nicht behandelt).
Diese Dierenz kann fur jeden Knoten einfach als zusatzliche Objektvariable gespeichert werden.
Informatik II { Sommersemester 1999
323
Informatik II { Sommersemester 1999
324
Beispiel fur die einfachen (1){ Regeln fur die Berechnung der Hohendierenz bei den rotierten Knoten: Einfachrotation mit Hohenverhaltnissen h(A) = h(B ) + 1 = h(C ) + 1. +2 +1
Knoten 1
Knoten 2
Knoten 2
A
B
A B
Bei einer "naiven\ Implementation von Dic-
tionaries durch binare Baume ergibt sich doch wieder (n) Aufwand fur Suchen, Einfugen und Loschen im Worst Case. Bei "halbwegs\ balancierten Baumen (z.B. AVL{Baumen) reduziert sich dieser Aufwand zu (log n). Bei AVL{Baumen kann die de nierende Balanceeigenschaft auch in (log n) Zeit pro Einfuge- und Loschoperation aufrechterhalten werden. Insgesamt kann man Dictionaries also in einer Form implementieren, so da Suchen, Einfugen und Loschen jeweils (log n) Zeit benotigt.
0 Knoten 1
C
Merke:
0
C
Andere Falle: Analog.
Informatik II { Sommersemester 1999
325
Informatik II { Sommersemester 1999
326
Thema 14: Vielwegbaume
Exkurs: Hintergrundspeicher
Interessierte Zusatzfrage:
Im eigentlichen Datenspeicher eines Computers
Bisher haben wir nur binare Baume betrachtet. Waren Baume mit potentiell mehr als 2 Nachfolgern pro Knoten nicht besser?
Antworten:
menfunktionen zu beliebigen Basen > 1 asymptotisch aquivalent sind (vgl. Thema 8). Auch bei den Proportionalitatsfaktoren ist nicht klar, welche Basis gunstig ist. (Suchschritt pro Baumknoten wird aufwendiger!)
Asymptotisch bringt es gar nichts, da alle Logarith-
Aber: Vielwegbaume sind interessant fur den Fall, da die Datenmenge zu gro fur den Hauptspeicher ist.
Informatik II { Sommersemester 1999
327
(Hauptspeicher) werden die Daten nur temporar gehalten. Spatestens, wenn der Computer heruntergefahren wird, ist der Inhalt des Hauptspeichers verloren. Fur permanente Datenhaltung sind Hintergrundspeicher zustandig. U bliches Medium: Festplatten. Entscheidender Punkt fur das Weitere: { Daten werden zwischen Haupt- und Hintergrundspeicher nicht Bit fur Bit oder Byte fur Byte transferiert, { sondern in groeren Blocken (Seiten). { Momentan ublich: 1.024, 2.048, 4.096 oder 8.192 Byte pro Seite.
Informatik II { Sommersemester 1999
328
Problem:
In diesem Abschnitt der Vorlesung (Thema 14):
Die Laufzeit fur Datentransfer von oder auf Hinter-
Behandlung der wichtigsten Datenstruktur fur dieses
Momentan typischerweise: Ungefahr
Bedeutung: B{Baume (bzw. Variationen von B{
Konsequenz:
Aber: Nur das abstrakte Prinzip von B{Baumen
grundspeicher ist um Groenordnungen groer als die Laufzeit fur interne Elementaroperationen.
Szenario: B{Baume.
Baumen) sind das Ruckgrat jedes ernstzunehmenden Datenbanksystems.
Faktor 10.000 | 1.000.000.
Minimierung der Zugrie auf den Hintergrundspeicher pro Such-, Einfuge und Loschoperation ist in diesem Szenario absolut vordringliches Optimierungsziel.
wird hier behandelt.
Warum: Die exakten Details sind zu umfangreich und komplex.
Die bisher betrachteten Elementaroperationen fallen im Vergleich nicht weiter ins Gewicht.
Informatik II { Sommersemester 1999
329
Idee:
Jeder Baumknoten kann bis zu k verschiedene Ele-
mente speichern. Die Anzahl der unmittelbaren Nachfolger ist um genau 1 groer als die Anzahl der gespeicherten Elemente. Die Konstante k wird so gewahlt, da k Elemente und k + 1 Verweise zusammen gerade noch auf eine Seite passen.
Informatik II { Sommersemester 1999
Konsistenzbedingungen (nur am Beispiel): Fur jeden Schlussel x aus A gilt x < a. Fur jeden Schlussel x aus B gilt a < x < b. Fur jeden Schlussel x aus C gilt b < x < c. ... Fur jeden Schlussel x aus F gilt e < x < f . Fur jeden Schlussel x aus G gilt f < x.
Illustration: Einzelner Baumknoten mit k = 9, Schlusselwerten a, b, c,: : :, f und Nachfolgerbaumen A; : : : ; G. a
b
c
d
e
330
a
b
c
d
e
f
null null null
f
A
B
C
D
E
F
G
null null null
A
B
C
D
Informatik II { Sommersemester 1999
E
F
G 331
Informatik II { Sommersemester 1999
332
Konsequenz aus den Konsistenzbedingungen:
Wie bei TreeDictionary konnen sich get, put und
von oben nach unten zur richtigen Stelle im Baum "durchhangeln\. In jedem Baumknoten mu der Suchschlussel mit bis zu k Schlusselwerten verglichen werden. Der "richtige\ unmittelbare Nachfolgerknoten kann allein durch Vergleich des Suchschlussels mit den Schlusselwerten des Baumknotens ermittelt werden (d.h. ohne Ansehen der Nachfolgerknoten). remove
Ergebnis:
Herausforderung: Gleichzeitig folgende Ziele errei-
chen... Alle Baumknoten ausreichend ausgelastet. Hohe wie bei AVL{Baumen logarithmisch beschrankt. Aufrechterhaltung dieser beiden Eigenschaften bei Einfugen und Loschen erfordert den Zugri auf moglichst wenige (und immer noch nur logarithmische viele) weitere Baumknoten.
Guter Kompromi: B{Baume
Die Anzahl der Zugrie auf den Hintergrundspeicher
De nition: Ein B{Baum der Ordnung k (k gerade) ist
Informatik II { Sommersemester 1999
Informatik II { Sommersemester 1999
kann sich in Abhangigkeit von k massiv reduzieren. Voraussetzung: Die einzelnen Baumknoten sind gut ausgelastet\, das heit enthalten nicht wesentlich "weniger als k Schlusselwerte.
333
ein Vielwegsuchbaum wie oben beschrieben, so da alle Blatter gleiche Hohe haben, jeder Baumknoten auer der Wurzel mindestens k=2 und hochstens k Schlusselwerte enthalt und die Wurzel mindestens einen und hochstens k Schlusselwerte enthalt. 334
Behauptung: Die Hohe eines B{Baumes der Ordnung k mit n gespeicherten Schlusselwerten ist in (log n).
Beweis der Hilfsbehauptung: Vollstandige Induktion uber h.
Notation: H (T ) bezeichnet die Hohe des Baumes T .
hochstens k Schlusselwerte in der Wurzel (Hohe 0). ;! Mindestens 2 = 2 (: : :)0 und hochstens k + 1 = (k + 1)1 Knoten auf Hohe 1.
Hilfsbehauptung: Fur h 2 f1; : : : ; H (T )g gibt es in einem B{Baum T der Ordnung k mindestens h ; 1 2 k2 + 1
Induktionsverankerung h = 1: Mindestens ein und
Induktionsschritt (h ; 1) ;! h > 1: Jeder Knoten auf Hohe h ; 1 > 0 hat mindestens k2 + 1 und hochstens k + 1 unmittelbare Nachfolger.
;! Mindestens
und hochstens (k + 1)h Knoten.
k
2
2 k h ; 23 k h ; 1 5 = 2 + 1 + 1 42 + 1 2
2
und hochstens (k + 1) (k + 1)h ; 1 = (k + 1)h Knoten auf Hohe h. Informatik II { Sommersemester 1999
335
Informatik II { Sommersemester 1999
336
Konsequenz: In einem B{Baum T der Ordnung k enthalt jede Hohenstufe h 2 f1; : : : ; H (T )g minde k h ; 1 stens k 2 +1 und jede Hohenstufe h 2 f0; : : : ; H (T )g hochstens k (k + 1)h Schlusselwerte. Begrundung: Obere und untere Abschatzung aus
der Hilfsbehauptung fur die Anzahl Baumknoten pro Hohenstufe mit den oberen und unteren Schranken (k=2 bzw. k) fur die Anzahl Schlusselwerte pro Baumknoten multiplizieren.
Nachstes Ziel:
Darauf aufbauend obere und untere Abschatzun-
gen fur die Gesamtzahl n(T ) von Schlusselwerten in einem B{Baum T der Ordnung k in Abhangigkeit von der Hohe berechnen. Durch Umstellung Abschatzungen fur die Hohe in Abhangigkeit von der Knotenzahl nden. Informatik II { Sommersemester 1999
337
HX (T ) h=0
k (k + 1)h = k
HX (T )
HX (T )
k +1 h;1
h=1 2 H (X T );1
= 1+k
k +1 h 2
h=0
(Formel fur geometrische Folgen:) ; k + 1H(T ) ; 1 = 1 + k 2; k 2 +1 ;1
= 1+2
"
# k + 1 H (T ); 1 2 H(T )
= 2 k2 + 1
;1
Informatik II { Sommersemester 1999
h=0
(k + 1)h
338
;1
;! H (T ) log( k +1)
n(T ) + 1
2
H (T )+1
= k (k +(k1)+ 1) ; 1; 1 = (k + 1)H (T )+1
H(T )
n(T ) 2 k2 + 1
(Formel fur geometrische Folgen:)
Informatik II { Sommersemester 1999
n(T ) 1 + k
Umgestellt jeweils nach der Hohe H (T ):
Obere Abschatzung:
n(T )
Untere Abschatzung:
2
n(T ) (k + 1)H (T )+1 ; 1 ;! H (T ) log(k+1) (n(T ) + 1) ; 1
;1
339
Informatik II { Sommersemester 1999
340
Stand soweit: H (T ) 2 (log n(T )). Umrechnung der Abschatzungskonstanten in den 2{
Logarithmus:
21 log(k+1) (n(T )) 1 2 log2(k + 1) log2(n(T ))
H (T ) log( k +1)
"
n(T ) + 1 2
2
2
log2
#
; 2 log 1(k + 1) log2(n(T )) log2 k2 + 1 2 ;1
Realistische Groenordnungen fur k: k = 100 ;! [:::] 10%. k = 1000 ;! [:::] 6%.
log( k +1)(n(T )) =
Erinnerung (Thema 10): Die kleinstmogliche Hohe eines binaren Baumes mit n Knoten tritt bei totaler Balancierung auf, namlich log2(n). Die grotmogliche Hohe eines B{Baumes unterscheidet sich davon etwa um Faktor 1= log2(k + 1). Die grot- und kleinstmogliche Hohe eines B{ Baumes unterscheiden sich maximal um den Faktor
H (T ) log(k+1) (n(T ) + 1) ; 1
=
Auswertung:
;1k + 1 log2(n(T )) 2
Informatik II { Sommersemester 1999
341
Ideen fur BTreeDictionary.put:
Informatik II { Sommersemester 1999
342
Intuition: "g\ in ein volles Blatt einfugen
Suche von der Wurzel aus das Blatt, in das der neue
(gestrichelter Pfeil: null{Verweis)
Schlusselwert hineingehoren wurde.
a
b c
p q
d
r
Falls weniger als k Werte momentan in diesem Blatt gespeichert sind: einfach einfugen und fertig.
e
f
h
j
i
k
l m n o
Ansonsten: Blatt in zwei Teile zerlegen und den Schlusselwert (Median) zum nachst"hmittleren\ oheren Baumknoten weiterreichen.
a
b c
d
j
p q
r
Falls der auch schon voll war: Rekursiv weiter hochsteigen im B{Baum.
Informatik II { Sommersemester 1999
e
343
f
g
h
i
Informatik II { Sommersemester 1999
k
l m n
o
344
Falls beim rekursiven Hochsteigen die Wurzel erreicht wird und die Wurzel ebenfalls voll ist:
Intuition: "d\ in die volle Wurzel einfugen
Wurzel wird ebenfalls in zwei Teile zerlegt. Neue Wurzel wird angelegt. Der mittlere Schlusselwert wird als einziger
a
Schlusselwert in der neuen Wurzel gespeichert.
b c
e
f
g
h
i
j
k
g
h
i
j
k
f
;! Daher die notwendige Ausnahme, da die Wurzel nicht mindestens k=2 Schlusselwerte enthalten mu.
a
b
c d
e
Beachte: Nur wenn entlang des Baumpfades von der Einfugestelle bis zur Wurzel alle Knoten (einschlielich Wurzel) voll sind, vergroert sich die Hohe des Baumes.
;! Also im Normalfall relativ selten. Informatik II { Sommersemester 1999
345
Ideen fur BTreeDictionary.remove:
Zu loschenden Schlusselwert wie ublich absteigend
von der Wurzel aus suchen und loschen. Falls danach noch mindestens k=2 Schlusselwerte im betroenen Knoten sind: Fertig. Ansonsten: Umkehrung der Zerlegungsoperation, d.h. Verschmelzung von "Geschwisterknoten\. Insbesondere: Ein Schlusselwert wird aus dem gemeinsamen unmittelbaren Vorganger heruntergezogen. Falls der unmittelbare Vorganger nur k=2 Schlusselwerte hatte: ;! Analog zum Einfugen soweit wie notig im Baum hochgehen und auf jeder Stufe eine solche Verschmelzung durchfuhren. Falls dabei die Wurzel leer wird: ;! Wurzel wird geloscht. ;! Einzige Situation, in der die Hohe des B{Baumes reduziert wird.
Informatik II { Sommersemester 1999
347
Informatik II { Sommersemester 1999
346
Intuition zum Verschmelzen: "m\ loschen a
e
f g
h
b
c d
j
i
a
e
b
f g
Informatik II { Sommersemester 1999
p
q r
k
l
c d
p
q
r
h
j
k
l
i
m n
n
o
o
348
Thema 15: Hash{Tabellen
Merke:
Bei der Verwaltung von Daten auf dem Hin-
Szenario:
tergrundspeicher ist nicht nur die Asymptotik praktisch von Bedeutung, sondern auch die genaue Zahl von Speicherzugrien. Aus diesem Grund sind hier Vielwegbaume interessant, in denen jeder Knoten eine Speicherseite ausmacht. B{Baume bieten eine Mindestgarantie fur die Auslastung jedes einzelnen Baumknotens (=Speicherseite). Daraus folgen im Verhaltnis zu binaren Baumen sehr gunstige Konstanten fur die logarithmische Asymptotik: Die maximale Hohe eines B{Baumes mit n Knoten ist immer noch um einen (von der Ordnung des B{Baumes abhangigen) Faktor kleiner als die minimale Hohe eines binaren Baumes. Informatik II { Sommersemester 1999
Nach dem Aufbau des Dictionaries sollen keine Elemente mehr eingefugt oder geloscht werden.
Vor Aufbau des Dictionaries ist schon die Gesamtzahl von zu speichernden Elementen bekannt.
;! Statisches Dictionary. Bisheriges Resultat:
(log n) pro Operation im Worst Case (Thema 13 und 14).
Keine Perspektive fur etwas Besseres als (log n)
im Average Case fur "realistische\ Hau gkeitsverteilungen.
349
In diesem Abschnitt:
Eine Datenstruktur auf Arraybasis, fur die im Worst
Informatik II { Sommersemester 1999
350
Fahrplan:
Case nur (n) Aufwand pro Einfugeoperation beim Aufbau bzw. pro Suchoperation garantiert werden kann. Durch eine "pseudozufallige\ Streuung (hashing) der Elemente uber das Array zeigt jede "nichtpathologische\ Hau gkeitsverteilung erfahrungsgema ungefahr dasselbe Laufzeitverhalten wie eine reine Zufallsverteilung. Konsequenz: { Man braucht sich im Average Case keine Gedanken um die genaue Hau gkeitsverteilung zu machen, { sondern kann der Analyse einfach den idealisierten Fall einer Zufallsverteilung zugrundelegen. Ergebnis wird sein: In diesem speziellen Fall von Average Case gilt (1).
Zuerst das Grundkonzept auf abstrakter Ebene be-
Informatik II { Sommersemester 1999
Informatik II { Sommersemester 1999
351
trachten (Durststrecke!).
Dann Zielvorstellungen uberlegen, wie dieses Grundkonzept sinnvoll mit Leben zu fullen ist.
Schlielich konkrete Beispiele zum Thema "mit Leben fullen\ betrachten.
352
Grundkonzept:
Konsistenzbedingungen:
Fur n 2 N zu speichernde Elemente werden Arrays theKeys und theInfos mit Indexbereich 0 : : : m ; 1, eingerichtet: m 2 N , m n.
Falls an Index i 2 f0; : : : ; m ; 1g momentan
Es gibt eine Folge von Funktionen f0; f1; f2;
Sei x ein momentan gespeicherter Schlusselwert, und sei i 2 f0; : : : ; m ; 1g der Index von x, das
: : : ; fm;1, von denen jede den Wertebereich fur Schlusselwerte auf f0; : : : ; m ; 1g abbildet,
und zwar so, da fi(x) != fj (x) fur alle potentiellen Schlusselwerte x und alle i; j 2 f0; : : : ; m ; 1g, i= 6 j , ist. ;! Fur jeden momentan gespeicherten Schlusselwert x gibt es genau ein i 2 f0; : : : ; m ; 1g, so da theKeys[fi (x)]
==
353
Idee fur HashDictionary.get: ist, durch.
dabei auftritt:
fi(x)] zuruckliefern und fertig.
Falls statt dessen theKeys[fi(x)] auftritt:
== null
;! Schlusselwert x ist gema Konsistenzbe-
Informatik II { Sommersemester 1999
354
;! Schlusselwert und Information in theKeys[fi(x)]
dingungen momentan nicht gespeichert.
bzw. theInfos[fi (x)] ablegen.
;! Einfach null zuruckliefern und fertig.
Informatik II { Sommersemester 1999
!= null.
ist, durchgehen. Falls theKeys[fi(x)] == x dabei auftritt: theInfos[fi (x)] mit Argument info u berschreiben, alten Wert zuruckliefern und fertig. Falls statt dessen theKeys[fi(x)] == null auftritt: ;! Schlusselwert x ist gema Konsistenzbedingungen momentan nicht gespeichert.
f0(x); f1(x); f2(x); : : : soweit, wie es notig == x
fj (x)]
theKeys[
Idee fur HashDictionary.put: Wieder f0(x); f1(x); f2(x); : : : soweit, wie es notig
Fur einen gegebenen Schlusselwert x gehe
theInfos[
heit theKeys[fi (x)] == x. Fur alle j 2 f0; : : : ; i ; 1g gilt dann
x ist.
Informatik II { Sommersemester 1999
Falls theKeys[fi(x)]
kein Element in den Arrays gespeichert ist, gilt theKeys[i] == null.
Methode HashDictionary.remove: Ist im eingangs formulierten Szenario irrelevant.
355
Informatik II { Sommersemester 1999
356
Frage: Was will man eigentlich erreichen?
Oen: Konkrete De nition der Funktionen f0; f1; f2; : : : Primitives Beispiel: fi(x) = i fur alle potentiellen
Schlusselwerte x.
Klare Antwort: Den Wert i mit theKeys[fi(x)] == x oder theKeys[fi(x)] == null moglichst klein halten (zumindest im Durchschnitt).
Beim Einfugen des i{ten Elements x sind
Vorbetrachtung: Wie mu fi de niert sein, damit fur zwei beliebige Schlusselwerte x und y die Wahrscheinlichkeit einer Kollision fi(x) = fi(y) moglichst klein
;! Einfugen von n m Elementen kostet Lauf-
Einkleidung in eine weniger abstrakte Fragestellung:
Trauriges Resultat:
f0(x); : : : ; fi;2(x) schon besetzt. zeit
2
n ! X i=1
i =
n(n + 1) 2
;
= n2
Wenn mit get nicht ausgerechnet immer nur auf ein
paar wenige, fruh eingefugte Elemente zugegrien wird, dann kostet get auch im Average Case (n) Laufzeit.
Informatik II { Sommersemester 1999
357
Wie gro ist die Wahrscheinlichkeit, da zwei beliebige Leute am gleichen Datum (Schaltjahre ignoriert) Geburtstag haben?
Naheliegende Antwort: Es gibt 365 365 mogliche Kombinationen. Davon gibt es 365 Kombinationen mit gleichem Datum.
1 ;! 365
Informatik II { Sommersemester 1999
358
Anschlufrage: Wie mute die Wahrscheinlichkeits-
Kleines Problem:
verteilung sein, damit gleiches Geburtsdatum moglichst unwahrscheinlich wird?
Die Rechnung ist richtig. Aber die Antwort ist falsch!
Ansatz:
Warum:
Die implizite Voraussetzung, da alle Geburtsdaten 1:1:;31:12: gleichwahrscheinlich sind, stimmt nicht. Im Fruhjahr werden mehr Kinder geboren als im Herbst.
Frage: A ndert sich dadurch wirklich etwas am Ergebnis?
Trockene Antwort durch Extrembeispiel: Alle Kinder werden am 1:1: geboren. 1 ;! Wahrscheinlichkeit 1 statt 365 Informatik II { Sommersemester 1999
wird?
359
Reellwertige Variable x1; x2; : : : ; x365 2 [0; 1]. Forderung: x1 + x2 + + x365 = 1. Interpretation: xi ist die Wahscheinlichkeit, da eine
Person am Datum Nr. i Geburtstag hat. ;! x2i ist die Wahrscheinlichkeit, da beide Personen am Tag i Geburtstag haben. ;! x21 + x22 + + x2365 ist die Wahrscheinlichkeit, da beide Personen an irgendeinem Tag zugleich Geburtstag haben. Ziel: Werte fur x1; : : : ; x365 so bestimmen, da x21 + x22 + + x2365 minimal wird. Informatik II { Sommersemester 1999
360
Behauptung: Das globale Minimum wird bei x1 = x2 = = x365 = 1=365 angenommen. Beweis:
Durch Widerspruch, das heit, die exakt gegenteilige
Behauptung wird zum Widerspruch gefuhrt. Gegenteilige Behauptung: Lat sich ohne Beschrankung der Allgemeinheit vereinfachen zu x1 6= x2 . Wegen y + y + x3 + x4 + + x365 = 1 mit y := (x1 + x2)=2 reicht zu zeigen: Wenn x1 und x2 beide durch y ersetzt werden, ergibt sich eine echte Verbesserung.
Ansatz mit 1. Binomischer Formel: x + x 2 2 2 y +y = 2 12 2 ; = 21 x21 + 2 x1 x2 + x22 Informatik II { Sommersemester 1999
Umgestellt:
2 x1 x2 < x21 + x22
Zusammengefat mit 2. Binomischer Formel: ( x2 ; x1 )2 > 0 Aber: (x2 ; x1)2 > 0 folgt sofort aus der Widerspruchsannahme x1 6= x2. ;! x21 + x22 + x23 + + x2365 >
y2 + y2 + x33 + + x2365
;! Beweis fertig. 361
Zuruck zu Hash{Tabellen und f0:
Informatik II { Sommersemester 1999
362
Idealisiertes Modell zur asymptotischen
Stand soweit: Ideal ware es, wenn jedes fi al-
le Schlusselwerte uniform uber den Indexbereich f0; : : : ; m ; 1g "verstreuen\ wurde.
Problem:
{ Das wurde eine echte Zufallsstreuung erfordern. { Wenn man die gespeicherten Schlusselwerte mittels f0; f1; f2; : : : wieder nden will, mussen diese Funktionen aber 100% deterministisch sein.
Abgeschwachte Zielsetzung: Finde Funktionen f0; f1; f2; : : :, die { 100% deterministisch sind, { aber einer uniformen Zufallsverteilung
Analyse: Seien i; j 2 f0; : : : ; m ; 1g. Die Wahrscheinlichkeit, da fi(x) = j ist, ist gleich 1=m, und zwar unabhangig von allen anderen Werten fj (y) mit j 6= i und/oder y 6= x, abgesehen davon, da weiterhin fi(x) 6= fj (x) fur alle i 6= j gelten soll. (Hintergrund: Vorlesungen zu Stochastik oder Statistik, Stichwort bedingte Wahrscheinlichkeiten.)
Behauptung: Einfugen und Suchen von n m Elementen kostet in diesem idealisierten Modell (1) Laufzeit pro Operation.
"zum Verwechseln\ ahnlich sehen.
Informatik II { Sommersemester 1999
Also zu zeigen: 1 ; x2 + 2 x x + x2 < x2 + x2 1 2 1 2 1 2 2
363
Informatik II { Sommersemester 1999
364
Einschub: Was sagt diese Behauptung eigentlich aus?
Also:
Analogie aus der Physik: Fallgesetz
(1) Laufzeit ist 100% korrekt fur das idealisierte
Liefert 100% korrekte Berechnungen fur den ideali-
sierten Fall eines Massepunkts ohne Ausdehnung in einem totalen Vakuum unter einem homogenen Gravitationsfeld und ohne die Wirkung weiterer Krafte.
Praktisch 100% korrekte Berechnungen fur Experimente unter "Laborbedingungen\.
Leidlich korrekte Berechnungen fur Szenarien, in
denen andere Ein usse eine geringe Rolle spielen (Ballistik, Flugbahnen im Weltraum...).
Modell. ;! Noch zu beweisen.
Auch noch praktisch korrekt, falls f0; f1; f2; : : : wie uniforme Zufallsverteilungen "aussehen\.
Aber allgemein lat sich fur beliebige f0; f1; f2; : : : nichts daraus folgern.
;! Siehe primitives Beispiel oben.
Vollig unbrauchbare Berechnungen fur Situationen mit "alltagstypischer\ Komplexitat (Flug einer Vogelfeder im Wind).
Informatik II { Sommersemester 1999
365
Beweis der Behauptung: Einfugen und Suchen in (1) Laufzeit im Average Case.
Einfugen eines Schlusselwertes x und spateres er-
folgreiches Suchen von x kosten asymptotisch gleich viel. ;! Einfugen mu im weiteren nicht betrachtet werden.
Erfolgreiches und erfolgloses Suchen eines nichtge-
speicherten Schlusselwertes sind verschiedene Szenarien. ;! Fallunterscheidung.
Informatik II { Sommersemester 1999
366
Teilbehauptung I: Erfolgreiche Suche erfordert im Durchschnitt die Auswertung von
1 1 ; mn+1 2 (1) Funktionen f0; f1; f2; : : :
Bemerkung: Formaler Beleg fur die intuitiv logische
Erkenntnis, da die Wahrscheinlichkeit fur Kollisionen (und damit die durchschnittliche Laufzeit) mit wachsendem Verhaltnis m=n nur kleiner wird.
Erinnerung: { 0; : : : ; m ; 1 Indexbereich der Arrays. { n m Anzahl der gespeicherten Elemente.
Informatik II { Sommersemester 1999
367
Informatik II { Sommersemester 1999
368
Notation fur den Beweis von Teilbehauptung I:
pi: Wahrscheinlichkeit, da genau i Auswertungen notig sind (i 2 f1; : : : ; mg). ;! Durchschnittliche Anzahl Auswertungen ist n X i=1
i=1
qi =
p1 + p2 + p3 + p4 + + p2 + p3 + p4 + + p3 + p4 + + p4 +
i pi :
qi: Wahrscheinlichkeit, da mindestens i Auswertungen notig sind.
+ + + +
n X n X i=1 j =i pi pi pi pi
=
n X i=1
;! 369
Ansatz:
pj =
+ + + +
+ pn-1 + pn + pn-1 + pn + p n-1 + pn + p n-1 + pn
+ pi +
+ p n-1 + pn + pn-1 + pn
i -mal
;! qi = pi + pi+1 + + pn.
Informatik II { Sommersemester 1999
n X
Beachte:
+ pn
i pi :
n X i=1
qi 2 (1) zu beweisen.
Informatik II { Sommersemester 1999
370
Allgemein:
q1 = 1 ist oensichtlich. Mindestens zwei Auswertungen notwendig. () theKeys[f0(x)] != x und
n X i=1
f0(x)] != null. () theKeys[f0(x)] ist eines der n ; 1 momentan gespeicherten Elemente 6= x von insgesamt m theKeys[
Indizes im Hash. ;! q2 = n ; 1
qi =
n n;1 n;2 X n;i+1 m;1 m;i+2 i=1 m
=
n iY ;1 n ; j X i=1 j =1
m;j+1
Nebenrechnung: Fur a < b und c 0 gilt
m
Mindestens drei Auswertungen notwendig. () theKeys[f0(x)] ist eines der n ; 1 Elemente = 6 x von insgesamt m Indizes, und theKeys[f1 (x)] ist eines der n ; 2 Elemente = 6 x von den restlichen m ; 1. ;! q3 = n m; 1 mn ;; 21
a;c a b;c b wegen (a ; c) b = a b ; c b a b ; c a = (b ; c) a.
Informatik II { Sommersemester 1999
Informatik II { Sommersemester 1999
371
372
Teilbehauptung II: Erfolglose Suche erfordert im Durchschnitt die Auswertung von 1 2 (1) 1 ; mn+1 +1 Funktionen f0; f1; f2; : : :
Anwendung der Nebenrechnung: n iY ;1 n ; j X i=1 j =1
!
m;j+1
n n i ; 1 X i=1
m+1
=
nX ;1 i=0
n
m+1
i
Beweis: q1 = 1 bleibt naturlich.
Gesuchter Schlusselwert x ist momentan nicht ge-
(Geometrische Reihe:)
1 n i X m+1 i=0
speichert: ;! k Auswertungen sind genau dann notwendig, wenn theKeys[f0 (x)] ... theKeys[fk;2 (x)] != null ist. Konsequenz: n n ; 1 n ; k + 1 qk = m m;1 m;k+1
1
= 1; n m+1
;! Teilbehauptung I bewiesen.
Weiterer Beweis: vollig analog. Informatik II { Sommersemester 1999
373
Typische Wahl der Funktionen f0; f1; f2; : : :
Informatik II { Sommersemester 1999
Einschrankung im folgenden zunachst: Schlusselwerte sind naturliche Zahlen.
Praktische Einschrankung: Alle Funktionen sollten nach einer einfachen Regel de niert sein.
Praktisch bewahrte Ideen fur Funktion f :
Grundidee in der Praxis:
f (x) := a x + b mit zwei festen Parametern a; b 2 N . Erfahrungsgema gute Streuung fur f0, wenn a, b und m paarweise verschiedene Primzahlen sind.
Zwei Funktionen f und g mit Wertebereich N . Fur jeden moglichen Schlusselwert x und jedes i 2 f0; : : : ; n ; 1g wird gesetzt: fi(x) := (f (x) + i g(x)) mod m.
Informatik II { Sommersemester 1999
374
f (x) := dm x ze mit einem festen Parameter z 2 (0; 1). Erfahrungsgema gute Streuungpfur f0, wenn z ungefahr der "Goldene Schnitt\ ( 5 ; 1)=2 ist. (Fur diese Erfahrung gibt es sogar mathematische Evidenz, wird hier aber nicht behandelt.) 375
Informatik II { Sommersemester 1999
376
Erinnerung:
Andere Arten von Schlusselwerten
te f0(x); f1(x); : : : ; fm;1(x) paarweise verschieden sein. Wir hatten uns auf einen Spezialfall "eingeschossen\: fi(x) = (f (x) + i g(x)) mod m.
Beispiel: Strings
Ideen fur Funktion g:
Seien c0(S ); : : : ; c`(S);1(S ) die einzelnen Zeichen
Fur jeden Schlusselwert X sollen die Indexwer-
von ci.
Hashfunktion f :
Double Hashing: g wird ahnlich wie f de niert (aber mit anderen Parameterwerten). Erfahrung: Streuverhalten kommt dem Ideal einer rein zufalligen Streuung sehr nah.
377
Warum Primzahlen: Je "primer\ die Parameter pi, um so starker wird erfahrungsgem a jedwede Besonderheit im Datenpro l "zerhackt\. Achtung: f (S ) kann sehr schnell Wertebereich von oder sogar long uberschreiten.
Technischer Trick: Zwischendurch immer wieder einmal das momentane Zwischenresultat durch Modulobildung mit einer Primzahl q auf sichere Groenordnungen reduzieren. int hashKey = 0; for ( int i=0; i maxSafeNumber ) hashKey %= q; }
Informatik II { Sommersemester 1999
Primzahlen.
Fur i 2 f0; : : : ; `(S ) ; 1g sei ai 2 N der ASCII{Wert
Keine gute Streuung wegen Haufungsbildungen: f0(x) = f0(y) fur zwei Schlusselwerte x und y ;! fi(x) = fi(y) fur alle i.
int
Seien p0; : : : ; pr;1 paarweise verschiedene eines Strings S der Lange `(S ).
Lineares Sondieren: g(x) = 1 fur alle x.
Informatik II { Sommersemester 1999
Idee:
379
f (S ) :=
`(X S );1 i=0
ai p(i mod r)
Analog die De nition der additiven Hashfunktion g (mit anderen Primzahlen).
Informatik II { Sommersemester 1999
378
Beispiele fur das Szenario "Statisches Dictionary\, auf das Hash{Tabellen passen:
On{Line{Worterbuch: { Schlusselwerte: Die eingetragenen Worter. { Informationen: Die erklarenden Texte.
Speicher einer WWW{Suchmaschine: { Schlusselwerte: Alle in den durchsuchten WWW{ Seiten gefundenen Worter. { Informationen: Zu jedem indizierten Wort die Liste der URLs, in denen es gefunden wurde.
Informatik II { Sommersemester 1999
380
Merke:
Thema 16: Prioritatswarteschlangen
Die rein statische Variante von Dictionaries
(d.h. nach Aufbau kein Einfugen und Loschen mehr) ist in vielen Anwendungen wichtig. Implementationen von dynamischen Dictionaries wie AVL- und B{Baume garantieren (log n) Aufwand pro Suche und (n log n) fur den Aufbau. Hash{Verfahren konnen im Worst Case nichts Besseres als (n) pro Suche und (n2) fur den Aufbau garantieren. Erfahrungsgema ist der reale Aufwand aber (1) pro Suche und (n) fur den Aufbau. Durch das wilde "Zerhacken\ mittels Primzahlen ist das empirische Laufzeitverhalten im Average Case kaum sensitiv gegenuber dem charakteristischen Datenpro l einer konkreten Anwendungssituation.
Informatik II { Sommersemester 1999
Wie Dictionaries eine Datenstruktur zum Speicher von Paaren (Schlussel,Information).
Aber: Andere Semantik fur Schlussel. { Nicht zum gezielten Suchen eines gegebenen Schlussels, { sondern als Prioritatswert fur die jeweils assozierte Information.
381
Mogliche Realisierung als Java{Interface: public interface PriorityQueue { public Object insert ( Object Object public Object getFirstKey (); public Object getFirstInfo (); public void removeFirst (); public Object getKey ( Object public void changeKey ( Object Object }
Informatik II { Sommersemester 1999
382
Weitere Erlauterungen:
Methoden
getFirstKey bzw. getFirstInfo liefern den Schlussel bzw. die Information desjenigen Paares, das momentan unter allen Paaren den kleinsten Schlusselwert (=die hochste Prioritat) besitzt.
key, info );
Bei mehreren Kandidaten mit kleinstem identification ); identification, key );
Erlauterungen:
Methode insert fugt ein neues Paar ein und liefert
Schlusselwert: { Einer davon wird ausgewahlt. { Die Auswahl ist nicht festgelegt, { sondern kann in jeder Klasse, die das Interface PriorityQueue jeweils implementiert, nach Gu" sto\ sein.
eine anonyme Identi kation dieses Paares zuruck. Methode getKey liefert fur diese Identi kation danach den Schlusselwert dieses Paares zuruck. Methode changeKey uberschreibt den so identi zierten Schlusselwert durch Parameter key.
Methode removeFirst loscht genau dieses Kandi-
Informatik II { Sommersemester 1999
Informatik II { Sommersemester 1999
383
datenpaar.
384
Beobachtung: Dictionary{Implementationen lassen sich auch zur Realisierung von Priority Queues verwenden. ;! Priority Queues lassen sich mittels AVL{ Baumen so implementieren, da jede Operation (log n) Laufzeit bei n momentan gespeicherten Elementen erfordert. insert: Wie put, nur da der Verweis auf das eingefugte TreeNode{Objekt (Referenzvariable vom Typ TreeNode) als Identi kation zuruckgeliefert wird. getKey: Dann trivial. changeKey: Erst loschen, dann mit neuem Schlusselwert wieder einfugen. Achtung: Damit die Identi kation nicht falsch wird, mu das neu eingefugte TreeNode{Objekt physisch mit dem "ausgeklinkten\ identisch sein. getFirstKey , getFirstInfo und removeFirst: Der Schlussel des "linkesten\ Elements im ganzen Baum. Informatik II { Sommersemester 1999
385
Begrundung:
Mit einer Priority Queue kann man sortieren. Die Laufzeit fur diesen Sortieralgorithmus wird von der Laufzeit fur diese drei Operationen auf der Priority Queue dominiert.
Selbst unter der Annahme, da der Vergleich zweier Werte (1) ist, geht Sortieren aber grundsatzlich nicht schneller als (n log n) im Average und Worst Case (Thema 10).
Nebenresultat: Dieselbe Argumentation liefert fur
Dictionaries das analoge Negativresultat: Besser als (log n) ist in jeder Implementation von Dictionaries fur mindestens eine der Operationen nicht drin.
Informatik II { Sommersemester 1999
387
Frage:
Es wird nur ein Teil der Funktionalitat von Dictio-
naries verwendet. Bei Hash{Tabellen konnte man diesen Tatbestand ausnutzen, um etwas Besseres als (log n) zumindest im Average Case zu bekommen. Kann man das auch bei Priority Queues erreichen?
Antwort: Selbst unter der idealisierten Annahme, da jeder Vergleich nur (1) Zeit braucht, braucht
in jeder nur moglichen Implementation von Priority Queues mindestens eine der Operationen insert, getFirstKey und removeFirst mindestens (log n) Laufzeit schon im Average Case (erst recht im Worst Case).
Informatik II { Sommersemester 1999
386
Sortieren durch Priority Queues Technische Annahmen:
Klasse
MyPriorityQueue PriorityQueue und
implementiert Interface
hat einen Konstruktor, der ein Comparator{Objekt
als Argument erhalt und intern zum Groenvergleich von Schlusselwerten verwendet. Idee: Die zu sortierenden Elemente sind die Suchschlussel (und die Information ist irrelevant und daher einfach null). public void sort ( Object[] A, Comparator cmp ) { MyPriorityQueue queue = new MyPriorityQueue (cmp); for ( int i=0; i 0 ist die Lange einer Kante (u; v), und
16
`(p) die Lange eines Pfades p. Startknoten s, Zielknoten t. Fur einen Knoten v sei s(v) die Lange eines kurzesten Pfades von s nach v.
12 14 8 12 7
Beobachtung: Es endet genau dann ein kurzester (s; v){Pfad mit der Kante (u; v), wenn `(u; v) = s(v) ; s(u) ist. Beweis:
11 14 11 13 5 11 15 9 10 3
s
p
u
v
Sei p ein kurzester (s; u){Pfad. ;! `(p) = s(u) ;! s(v) = `|(p)+{z`(u; v}) () `(u; v) = s(v) ; s(u) Lange des Pfades "p + (u; v)\.
8 16 15
407
Informatik II { Sommersemester 1999
408
Konsequenz: Falls der Wert s(v) fur jeden Knoten v bekannt ist, lat sich ein kurzester (s; t){Pfad von t aus ruckwarts nach s konstruieren: 1. Starte mit i := 1, v1 := t und Pfad p := ;. 2. Solange vi 6= s, wiederhole: (a) Suche eine Kante (vi+1; vi) mit `(vi+1; vi) = (vi) ; (vi+1). (b) Fuge (vi+1; vi) vorne an p an. (c) Setze i := i + 1. s=vk
vk-1
;! `(p) =
kX ;1 i=1
vk-2
v4
v3
v2
Technische Feinheit: Fur diese Ruckwartsberechnung eines kurzesten Pfades aus den {Werten braucht man
eine umgekehrte Verzeigerung (d.h. jede Kante halt einen Verweis auf ihren Ursprungsknoten).
Knotenbewertung berechnen:
Der eigentliche Algorithmus von Dijkstra
Basis: Reellwertige Variable (v) fur jeden Knoten v.
t=v1
(s(vi) ; s(vi+1))
= s(v1) ; s(vk) = s(t) Informatik II { Sommersemester 1999
409
Schleifeninvarianten nach i Durchlaufen: (s) = 0 (anders gesagt: (s) = (s)). (v) (v) fur alle Knoten s 6= v.
Informatik II { Sommersemester 1999
410
Intuition fur die Wellenfront:
Es gibt eine Partition der Knoten in
{ eine momentane "Wellenfront\ Wi, { die Menge Si aller Knoten, uber die die Wellen-
front schon hinweggegangen ist, { und die Restmenge Xi. Die Menge Si besteht genau aus s und den i Knoten v 6= s mit kleinsten Werten (v). Wi besteht genau aus den Knoten v 62 Si, zu denen eine Kante aus Si hinzeigt. Fur jeden Knoten v 2 Si [ Wi ist (v) die Lange eines kurzesten (s; v){Pfades, der (ggf. abgesehen von v selbst) nur Knoten aus Si enthalt. ;! Am Ende, wenn die Wellenfront uber alle Knoten hinweggegangen ist, gilt . Informatik II { Sommersemester 1999
411
111111111111111111 000000000000000000 000000000000000000 111111111111111111 000000000000000000 111111111111111111 000000000000000000 111111111111111111 000000000000000000 111111111111111111 000000000000000000 111111111111111111 000000000000000000 111111111111111111 s 000000000000000000 111111111111111111 000000000000000000 111111111111111111 000000000000000000 111111111111111111 000000000000000000 111111111111111111 000000000000000000 111111111111111111 000000000000000000 111111111111111111 000000000000000000 111111111111111111 000000000000000000 111111111111111111 000000000000000000 111111111111111111 000000000000000000 111111111111111111 000000000000000000 111111111111111111
Informatik II { Sommersemester 1999
412
Initialisierung:
Kernschleife:
(s) := 0. Fur jeden Knoten v mit Kante (s; v) wird gesetzt
Si entsteht aus Si;1 durch Einfugen des Knotens v 2 Wi;1 mit minimalem momentanem Wert (v).
Fur jeden weiteren Knoten v wird (v) auf einen
Wi entsteht aus Wi;1, indem dieser Knoten v aus
(v) := `(s; v).
Wert gesetzt, der von der Implementation im weiteren als "1\ interpretiert wird, zum Beispiel { ein unmoglich groer Wert, { ein negativer und damit ganzlich unmoglicher Wert.
Wi;1 entfernt wird und alle Knoten w 62 (Si;1 [ Wi;1), fur die es eine Kante (v; w) gibt, eingefugt werden.
Dabei wird jeweils gesetzt: (w) := minf(w); (v) + `(v; w)g.
Konsequenz:
S0 = fsg. W0 besteht aus allen Knoten, zu denen eine Kante von s aus unmittelbar hinzeigt.
Informatik II { Sommersemester 1999
413
Korrektheit der Schleifeninvariante mit vollstandiger Induktion:
Informatik II { Sommersemester 1999
414
Intuition zum Induktionsschritt:
Induktionsanfang: Ergibt sich sofort aus der Initialisierung.
Induktionsschritt: Alle Kantenlangen sind nichtnegativ.
;! Wenn ein Pfad teilweise uber Knoten auerhalb von Wi;1 [ Si;1 verlauft, kann er dadurch nur langer werden.
;! Fur den Knoten v 2 Wi;1 mit mini-
malem s(v) geht der kurzeste Pfad ganz durch Si;1 [ Wi;1.
111111111111111111 000000000000000000 000000000000000000 111111111111111111 000000000000000000 111111111111111111 000000000000000000 111111111111111111 000000000000000000 111111111111111111 000000000000000000 111111111111111111 000000000000000000 111111111111111111 s 000000000000000000 111111111111111111 000000000000000000 111111111111111111 000000000000000000 111111111111111111 000000000000000000 111111111111111111 000000000000000000 111111111111111111 000000000000000000 111111111111111111 000000000000000000 111111111111111111 000000000000000000 111111111111111111 000000000000000000 111111111111111111 000000000000000000 111111111111111111 000000000000000000 111111111111111111
Aber: Nach Induktionsvoraussetzung ist die kurzeste Lange eines solchen Pfades gerade (v). Informatik II { Sommersemester 1999
415
Informatik II { Sommersemester 1999
416
Laufzeit
Wellenfront Wi ist Inhalt einer Priority Queue:
{ Information: Knoten v. { Schlusselwert: (v). Si wird uberhaupt nicht explizit verwaltet (wozu
Merke:
Semester ist zu Ende!
auch?). Die Groe der Priority Queue ist durchgangig beschrankt durch die Gesamtzahl n von Knoten im Netzwerk. Jeder Knoten wird nur einmal in Wi eingefugt (also auch nur einmal geloscht). ;! (n log n) fur alle insert's und removeFirst's zusammen. Jede der m Kanten im Netzwerk kann genau einmal eine Reduzierung eines Wertes (v) provozieren. ;! (m log n) fur alle getKey's und changeKey's zusammen. Zusammengefat: ((n + m) log n) Informatik II { Sommersemester 1999
417
Informatik II { Sommersemester 1999
418