Datenstrukturen - sven.köppel.org

Werbung
Datenstrukturen
Sommersemester 2010
Isolde Adler
Herzlich willkommen!
Organisatorisches
Wiederholung
Hashing
Ankündigungen
• Heute gegen Ende der Vorlesung: Studierendenbefragung
• Ein Lösungsvorschlag für die klausurtypischen Aufgaben aus der
Wiederholungsstunde ist auf den Webseiten erhältlich
• Letzte Vorlesungsstunde (13.7.2010): Wiederholungs- & Fragestunde
• 29.9.–5.10.2010: Vorsemesterkurs Quick-Start Informatik“ für
”
Studienanfänger/innen und Studierende nach dem ersten Jahr.
Wiederholung von Schulwissen, Vorbereitung auf die Themen der
Informatik
Anmeldung: Ab kommender Woche unter
www.vorkurs.informatik.uni-frankfurt.de/
Die Teilnehmerzahl ist begrenzt!
Isolde Adler
Datenstrukturen 2010
2/24
Organisatorisches
Wiederholung
Hashing
(a,b)-Bäume
Es gelte a ≥ 2 und b ≥ 2a − 1.
Ein Baum T hat die (a, b)-Eigenschaft, falls
• alle Blätter von T die gleiche Tiefe haben,
• alle Knoten höchstens b Kinder besitzen und
• die Wurzel mindestens zwei Kinder hat,
während alle sonstigen Knoten mindestens a Kinder haben.
• Interessant sind (a, b)-Bäume vor Allem für große Werte von a und
b, wenn Daten auf einem Externspeicher abgelegt sind:
• Die Tiefe wird dementsprechend klein sein
• und wenige der sehr langsamen Zugriffe auf den Externspeicher
genügen.
• Suchstruktur von (a, b)-Bäumen: verallgemeinert binäre Suchbäume
• lookup, insert, remove in O(Tiefe(T )), Tiefe(T ) ist
logarithmisch in der Anzahl der Knoten.
Isolde Adler
Datenstrukturen 2010
3/24
Organisatorisches
Wiederholung
Hashing
Ausblick
• Hashing mit Verkettung
• Hashing mit offener Adressierung
• Cuckoo-Hashing
Isolde Adler
Datenstrukturen 2010
4/24
Organisatorisches
Wiederholung
Hashing
Hashing – Anwendungen
• eine Hashfunktion bildet Elemente aus einem großen Universum in
eine kleine Zielmenge ab (die Ausgabe heißt auch Hashcode)
• Anwendungen: Hash-Tabellen zum schnellen Suchen in großen
Datenmengen
• Anwendungen: Kryptographie, etwa für Digitale Signaturen
(Prof. Schnorr, Goethe-Universität Frankfurt, hat die berühmte
Schnorr-Signatur erfunden.)
Isolde Adler
Datenstrukturen 2010
5/24
Organisatorisches
Wiederholung
Hashing
Hashing
• Sei U die Menge aller möglichen Schlüssel und sei m die Größe einer
im Hauptspeicher abspeicherbaren Tabelle.
• Eine Funktion
h : U → {0, 1, ..., m − 1}
heißt eine Hashfunktion.
• Zum Beispiel können wir insert (x, info) implementieren, indem wir
• h(x) = i berechnen und
• (x, info) in Zelle i der Tabelle eintragen.
Aber was passiert bei einer Kollision, wenn also Zelle i bereits
besetzt ist?
Wir beschreiben zwei Hashing-Verfahren, Hashing mit Verkettung und
Hashing mit offener Adressierung.
Isolde Adler
Datenstrukturen 2010
6/24
Organisatorisches
Wiederholung
Hashing
Hashing mit Verkettung
Für jede Zelle i wird eine anfänglich leere Liste angelegt.
• Jede Liste wird sortiert gehalten.
• Für lookup(x): Durchlaufe die Liste von h(x).
• Für insert(x) und remove(x): Führe die insert- und
remove-Operation für einfach-verkettete Listen aus.
Beispiel: Wähle h(x) = (x mod 11) als Hashfunktion. Die Operationen
insert(59), insert(18) und insert(125) führen auf die Tabelle
4
-
59
- 125
7
-
18
-
-
lookup (26) benötigt nur einen Suchschritt: Schlüssel 59 wird gefunden
und es wird geschlossen, dass 26 nicht präsent ist.
Isolde Adler
Datenstrukturen 2010
7/24
Organisatorisches
Wiederholung
Hashing
Die Wahl der Hashfunktion
Jeder Schlüssel x wird als Bitvektor dargestellt. Wir können also
annehmen, dass x eine natürliche Zahl ist.
• Eine beliebte und gute Wahl ist h(x) = x mod m.
h(x) kann schnell berechnet werden und wird bei guter“ Wahl von
”
m zufriedenstellende Ergebnisse liefern.
• Was ist eine schlechte Wahl von m?
• Angenommen, m ist eine Zweierpotenz.
• Wenn die Schlüssel Charakter-Strings sind, dann werden alle
Character-Strings mit gleicher Endung auf dieselbe Zelle gehasht.
• Häufig auftretende Endungen provozieren viele Kollisionen und damit
lange Listen: Die Bearbeitungszeit der einzelnen Operationen wächst!
Wähle stattdessen Primzahlen mit großem Abstand zur
nächstliegenden Zweierpotenz.
Isolde Adler
Datenstrukturen 2010
8/24
Organisatorisches
Wiederholung
Hashing
Wie schnell ist Hashing mit Verkettung?
Annahme: es befinden sich n Schlüssel in einer Tabelle mit m Zellen.
Wir sagen dann, dass λ = mn der Auslastungsfaktor der Tabelle ist.
Wie schnell wird eine insert(x), remove(x) oder lookup(x) Operation
ausgeführt?
• Bestenfalls ist die Liste für h(x) = i leer und wir erreichen eine
konstante Laufzeit.
• Schlimmstenfalls sind alle n Schlüssel auf die Liste von i verteilt und
die worst-case Laufzeit Θ(n) folgt.
Weder best-case noch worst-case Laufzeit scheinen verlässliche
Voraussagen der tatsächlichen Laufzeit zu sein.
Wir sollten die erwartete Laufzeit betrachten.
Isolde Adler
Datenstrukturen 2010
9/24
Organisatorisches
Wiederholung
Hashing
Die erwartete Laufzeit I
Wir machen die folgenden Annahmen:
• jedes Element x ∈ U hat die Wahrscheinlichkeit
1
|U|
als Operand in
einer Operation aufzutreten.
• Die Hashfunktion h streutndie Schlüsselogleichmäßig, d.h.
|{x ∈ U | h(x) = i}| ∈
|U|
b |U|
m c, d m e
gilt für jedes i.
• Die Hashfunktion h(x) = (x mod m) erfüllt die Streubedingung.
• Die Wahrscheinlichkeit pi , dass ein zufällig gezogener Schlüssel auf
die Zelle i gehasht wird, ist höchstens
pi ≤
d |U|
m e
≤
|U|
|U|
m
+1
1
1
≤
+
:
|U|
m |U|
Wie groß ist ni , die Anzahl der Schlüssel für Zelle i?
Isolde Adler
Datenstrukturen 2010
10/24
Organisatorisches
Wiederholung
Hashing
Die erwartete Laufzeit II
L=
Pm−1
i=0
pi · ni ist die erwartete Listenlänge.
• Wie groß ist L?
m−1
X
i=0
pi · ni
m−1
X
m−1
X
1
1
1
1
≤
+
· ni =
+
·
ni
m |U|
m |U|
i=0
i=0
1
1
n
=
+
n =λ+
.
m |U|
|U|
• Da die Hash-Tabelle bereits mit n Schlüsseln belegt ist, gilt n ≤ |U|
und
n
|U|
≤ 1 folgt.
• In allen Fällen von praktischer Relevanz wird n sehr viel kleiner als
|U| sein und der zweite Bruch kann vernachlässigt werden.
Isolde Adler
Datenstrukturen 2010
11/24
Organisatorisches
Wiederholung
Hashing
Zusammenfassung
• Die erwartete Länge einer Liste für Hashing mit Verkettung ist
höchstens 1 + λ.
• Die erwartete Laufzeit einer insert-, remove- oder lookup-Operation
ist höchstens O(1) + O(λ):
Die Hashfunktion ist auszuwerten und
dann muss die Hashliste durchlaufen werden.
• Hashing mit Verkettung ist ein hochgradig praxistaugliches
Verfahren.
• Einziger Nachteil:
Durch die Verwendung von Listen, und damit durch die Verwendung
von Zeigern, entsteht zusätzlicher Speicherbedarf.
Isolde Adler
Datenstrukturen 2010
12/24
Organisatorisches
Wiederholung
Hashing
Hashing mit offener Adressierung
Wir arbeiten mit einer Folge
h0 , ..., hm−1 : U → {0, ..., m − 1}
von Hashfunktionen. Setze i = 0.
(1) Wenn die Zelle hi (x) frei ist, dann füge x in Zelle hi (x) ein.
(2) Ansonsten setze i = i + 1 und gehe zu Schritt (1).
Die Anzahl der Fehlversuche sollte“ ansteigen, wenn λ zu groß
”
wird. Was ist in einem solchen Fall zu tun?
• Wenn der Auslastungsfaktor größer als 1/2 wird, dann lade die
Tabelle in eine doppelt so große Tabelle.
• Die Zeit für die Reorganisation wird durch die schnellere Bearbeitung
der Operationen amortisiert.
Wie sollen die einzelnen Operationen implementiert werden?
Isolde Adler
Datenstrukturen 2010
13/24
Organisatorisches
Wiederholung
Hashing
Implementierung von Lookup, Insert und Remove
• lookup und insert lassen sich für jede Folge von Hashfunktionen
leicht implementieren.
• Kopfzerbrechen bereitet remove: Wird nach Einfügen des Schlüssels
x in Zelle h1 (x) der Schlüssel in Zelle h0 (x) entfernt, dann hat die
Operation lookup (x) ein Problem.
• Ist x nicht präsent, weil Zelle h0 (x) leer ist oder
• muß weitergesucht werden?
• Bringe eine entfernt“ Markierung nach Löschen des Schlüssels in
”
Zelle h0 (x) an. Die erwartete Laufzeit einer erfolglosen Suche wird
aber anwachsen.
Hashing mit offener Adressierung sollte vermieden werden, wenn viele
Daten entfernt werden.
Isolde Adler
Datenstrukturen 2010
14/24
Organisatorisches
Wiederholung
Hashing
Lineares Austesten
In der Methode des linearen Austestens wird die Folge
hi (x) = (x + i) mod m
benutzt: Also wird die jeweils nächste Zelle untersucht.
+ Für jeden Schlüssel x ist die Folge h0 (x), . . . , hm−1 (x) eine zyklische
Verschiebung der Zellen. Insbesondere wird jede Zelle getestet“.
”
- Lineares Austesten führt zur Klumpenbildung.
• Angenommen, die Daten besetzen ein Intervall {i, i + 1, . . . , j − 1, j}
von Zellen.
• Wenn ein weiterer Schlüssel x mit h0 (x) ∈ {i, +1, . . . , j − 1, j}
eingefügt wird, dann wird x am Ende des Intervalls eingefügt.
• Das Intervall wächst und dementsprechend steigt der Aufwand für
die einzelnen Operationen.
Isolde Adler
Datenstrukturen 2010
15/24
Organisatorisches
Wiederholung
Hashing
Doppeltes Hashing
Wir benutzen zwei Hashfunktionen f und g und verwenden die Folge
hi (x) = (f (x) + i · g (x)) mod m.
• Die Klumpenbildung wird vermieden.
• Man erhält gute Ergebnisse bereits für
f (x) = x mod m
und g (x) = m∗ − (x mod m∗ ).
• Wähle m als Primzahl und fordere m∗ < m.
• g (x) ist stets von Null verschieden.
• Wenn f (x) + i · g (x) = f (x) + j · g (x) mod m,
dann (i − j) · g (x) = 0 mod m. Also folgt i = j.
• Also {hi (x) | 0 ≤ i < m} = {0, . . . , m − 1}.
Im doppelten Hashing werden alle Zellen getestet.
Isolde Adler
Datenstrukturen 2010
16/24
Organisatorisches
Wiederholung
Hashing
Die erwartete Laufzeit einer erfolglosen Suche I
Die Annahmen:
• Jeder Schlüssel x ∈ U tritt mit Wahrscheinlichkeit
1
|U|
als Operand
einer Operation auf.
• Für jedes x ∈ U ist die Folge
(h0 (x), h1 (x), ..., hm−1 (x)) = πx
eine Permutation von {0, 1, ..., m − 1} und
• Jede Permutation tritt für
|U|
m!
Schlüssel in U auf.
• Die letzte Annahme ist nur schwer zu erfüllen und dient nur zur
Erleichterung der Analyse.
• Wie lange müssen wir auf einen Erfolg, eine freie Zelle, warten?
Isolde Adler
Datenstrukturen 2010
17/24
Organisatorisches
Wiederholung
Hashing
Die erwartete Laufzeit einer erfolglosen Suche II
Man stelle sich vor, dass wir einen Schlüssel zufällig ziehen. Nach der
Annahme ist jede Permutation getesteter Zellen gleichwahrscheinlich.
• Der Auslastungsfaktor ist λ.
• Die Erfolgswahrscheinlichkeit im ersten Versuch ist 1 − λ und steigt
in nachfolgenden Versuchen an, da bisher nur besetzte Zellen
getestet wurden.
• Wie lange müssen wir auf einen Erfolg warten, wenn die
Erfolgswahrscheinlichkeit eines einzigen Versuchs mindestens
p = 1 − λ ist?
• Mit Wahrscheinlichkeit höchstens (1 − p)k · p werden k + 1 Versuche
benötigt.
• Die erwartete Zeit bis zum ersten Erfolg beträgt höchstens
P∞
k=0 (k
+ 1) · (1 − p)k · p = p1 .
Die erwartete Anzahl getesteter Zellen ist höchstens
Isolde Adler
Datenstrukturen 2010
18/24
1
1−λ .
Organisatorisches
Wiederholung
Hashing
Zusammenfassung
Der Auslastungsfaktor sei λ.
• Hashing mit Verkettung besitzt für alle Operationen eine erwartete
Laufzeit von höchstens O(1) + λ.
• Wegen der Klumpenbildung des linearen Austestens werden die
Operationen bei hoher Auslastung sehr langesm Allerdings ist
lineares Austesten cache-freundlich“.
”
• Die erwartete Laufzeit einer erfolglosen Suche für doppeltes Hashing
1
ist höchstens 1−λ .
Der Auslastungsfaktor für das lineare Austesten oder das doppelte
Hashing sollte nicht zu groß werden: Lade in eine doppelt so große
Tabelle, wenn λ > 1/2.
Animation
Isolde Adler
Datenstrukturen 2010
19/24
Organisatorisches
Wiederholung
Hashing
Cuckoo Hashing I
Arbeite mit zwei Hashtabellen T1 und T2 sowie
zwei Hashfunktionen h1 undh2 .
• Insert(x): Wiederhole bis zu M mal,
• Speichere x in Tabelle T1 und Zelle h1 (x) ab.
• Wenn die Zelle h1 (x) in Tabelle T1 durch einen Schlüssel y belegt
war, dann füge y in Tabelle T2 und Zelle h2 (y ) ein.
• Wenn die Zelle h2 (y ) in Tabelle T2 durch einen Schlüssel z belegt
war, dann setze x = z und beginne eine neue Iteration.
• Lookup(x): Überprüfe Zelle h1 (x) in Hashtabelle T1 und
gegebenenfalls Zelle h2 (x) in Hashtabelle T2 .
• Remove(x): Wenn x vorhanden ist, dann entferne x aus Zelle h1 (x)
in Hashtabelle T1 oder aus Zelle h2 (x) in Hashtabelle T2 .
Warum der Name Cuckoo Hashing? Eine Kuckuck Art wirft ein oder
mehrere Eier aus einem fremden Nest und legt ein eigenes Ei hinzu.
Isolde Adler
Datenstrukturen 2010
20/24
Organisatorisches
Wiederholung
Hashing
Cuckoo Hashing II
• Cuckoo Hashing hasht direkt in die Tabellen. Die remove-Operation
ist aber mit Leichtigkeit implementierbar.
• Eine worst-case Garantie für lookup und remove: Höchstens zwei
Zellen werden inspiziert.
• Nur die insert-Operation ist komplizierter:
• Beachte, dass der Auslastungsfaktor λ durch 21 beschränkt ist.
• Es kann gezeigt werden, dass die erwartete Anzahl getesteter Zellen
1
höchstens O(1 + 0.5−λ
) beträgt.
• Wenn die insert Prozedur nach M Iterationen nicht erfolgreich ist,
dann wird der zuletzt herausgeworfene Schlüssel in einer Liste von
”
Fehlversuchen“ abgelegt.
• Welche Hashfunktionen? Wähle 0 < a1 , a2 , a3 < m · 2w zufällig und
setze h(x) = fa1 (x) ⊕ fa2 (x) ⊕ fa3 (x), wobei
fa (x) = (a · x mod m · 2w ) div 2w .
Isolde Adler
Datenstrukturen 2010
21/24
Organisatorisches
Wiederholung
Hashing
Zusammenfassung
Der Auslastungsfaktor sei λ.
• Hashing mit Verkettung besitzt für alle Operationen eine erwartete
Laufzeit von höchstens O(1) + λ.
• Wegen der Klumpenbildung des linearen Austestens werden die
Operationen bei hoher Auslastung sehr langsam. Allerdings ist
lineares Austesten cache-freundlich“.
”
• Die erwartete Laufzeit einer erfolglosen Suche für doppeltes Hashing
1
ist höchstens 1−λ
.
Der Auslastungsfaktor für das lineare Austesten oder das doppelte
Hashing sollte nicht zu groß werden: Lade in eine doppelt so große
Tabelle, wenn λ > 1/2.
• Die erwartete Anzahl getesteter Zellen für insert bei Cuckoo Hashing
ist höchstens 21 (1 +
1
0.5−λ ).
Höchstens zwei Zellen werden für lookup- oder remove inspiziert.
Animation
Isolde Adler
Datenstrukturen 2010
22/24
Organisatorisches
Wiederholung
Hashing
Universelles Hashing
• Für jede Hashfunktion, ob für Hashing mit Verkettung oder für
Hashing mit offener Addressierung kann eine worst-case Laufzeit von
Θ(n) erzwungen werden.
Wir müssen also Glück“ haben, dass unsere Operationen kein
”
worst-case Verhalten zeigen.
• Stattdessen arbeiten wir mit einer Klasse H von Hashfunktionen:
• Zu Beginn der Berechnung wählen wir zufällig eine Hashfunktion
h∈H
• und führen Hashing mit Verkettung mit der Hashfunktion h durch.
• Warum sollte“ ein solches Verfahren funktionieren?
”
• Eine einzelne Hashfunktion ist durch eine bösartig gewählte
Operationenfolge zum Scheitern verurteilt,
• aber die meisten Hashfunktion werden diese Operationenfolge mit
Bravour meistern.
• Was ist eine geeignete Klasse H?
Isolde Adler
Datenstrukturen 2010
23/24
Organisatorisches
Wiederholung
Hashing
c-universelle Klassen von Hashfunktionen
Eine Menge H ⊆ {h | h : U → {0, ..., m − 1}} ist c-universell, falls
c
|{h ∈ H | h(x) = h(y )}|
≤
|H|
m
für alle x, y ∈ U mit x 6= y gilt.
Wenn H c-universell ist, dann gibt es keine zwei Schlüssel, die mit
Wahrscheinlichkeit größer als mc auf die gleiche Zelle hashen.
• Gibt es c-universelle Klassen von Hashfunktionen für kleine Werte
von c
• und können wir dann für jede Operationenfolge lookup, insert und
remove hochwahrscheinlich schnell ausführen?
Isolde Adler
Datenstrukturen 2010
24/24
Herunterladen