HASHING’ Kapitel6 - informatik.hs-mannheim.deschramm/ads/files/Kapitel06.pdf · 1 Übersicht 1....
Transcript of HASHING’ Kapitel6 - informatik.hs-mannheim.deschramm/ads/files/Kapitel06.pdf · 1 Übersicht 1....
1
Übersicht
1. Einführung 2. Algorithmen 3. Eigenscha?en von
Programmiersprachen 4. Algorithmenparadigmen 5. Suchen & SorGeren 6. Hashing 7. Komplexität von Algorithmen 8. Abstrakte Datentypen (ADT) 9. Listen 10. Bäume 11. Graphen
2
Lernziele des Kapitels
¨ Kennenlernen von Hashing bzw. was die MoGvaGon für Hashing ist?
¨ Verstehen wie Hashing funkGoniert.
¨ Verstehen, was eine HashfunkGon ist.
¨ Behandlung von Kollisionen beim Hashing verstehen.
¨ Einsatzmöglichkeiten für Hashing kennenlernen.
2
3
Inhalt
o Hashing o NotaGonen
o HashfunkGon bzw. Streuwer_unkGon o Hashtabelle
o Beispiele
o Kollisionen und Kollisionsstrategien o Offenes bzw. Geschlossenes Hashing
o Komplexität o Anwendungsgebiete von Hashing
o Java Hashtable-‐Klasse
o Programmierbeispiel
4
Hashing
o Speichermethode ¤ bei großen Datenbanken ¤ beschleunigt das Finden von Daten
o Die Grundidee des Hashing-‐Verfahrens ¤ Hash-‐FunkGon: Schlüsselwert à Speicheradresse
o GrundoperaBonen ¤ Einfügen ¤ Löschen ¤ Suchen
0 1 2 3 4 5 6 7
5
Anwendungsgebiete
o Datenbanken ¤ Index für Tabellen
à unter günsGgen Bedingungen „ideale“ Zugriffszeiten
o Compiler ¤ InterpretaGon von Symboltabellen
o Betriebssysteme ¤ ImplemenGerung von Seitentabellen
o SonsGge ApplikaGonen ¤ ImplemenGerung von Caches ¤ ImplemenGerung von Mengen
6
Hashing: DefiniGonen 1/6
o U sei die Menge der möglichen Schlüssel. o S ⊆ U sei die Menge der zu speichernden Schlüssel mit |S| = n. o Ein Behälter (Bucket) kann ein mit einem Schlüssel zu idenGfizierendes
Element aufnehmen. o Eine Hashtabelle H ist eine Menge von nummerierten Behältern
B0,B1,B2,….Bm-‐1 mit |H| = m.
¤ Anmerkung: häufig ist eine Hashtabelle ein Array und der Bucket ein Arrayplatz
7
Hashing: DefiniGonen 2/6
}1,...,0{U:h −→ m
¨ Eine HashfunkBon ist eine ganzzahlige FunkGon die einem Schlüssel u den Hashwert a zuordnet, der den Behälter Ba bezeichnet.
au )h( =
Anmerkung: bei Hasharray: statt Hashwert auch oft Hashindex
8
Beispiel Namen
Schlüssel: mögliche Schlüssel U = [A-‐Z][a-‐z]* zu speichernde Schlüssel S = <<Vornamen>>
Hashtabelle: Array 0..7 of Integer HashfunkGon: h(u) = <<Länge von u>> h(u) = <<Länge von u>> mod 8
Gelöst (1): mod
Zu lösen (1): Länge der Hash-Tabelle müsste unendlich sein.
Zu lösen (2): „Eva“ und „Ann“ haben gleich viele Buchstaben à „Kollision“
Gelöst (2): Liste
Array 0..7 of List of Integer
alternativ zu (2): falls a[i] besetzt, wähle a[i+1], usw.
11
Hashing: DefiniGonen 3/6
muf mod)(:h
¨ Anmerkung: ¤ Eine HashfunkBon wird o? noGert als
mit
m = |H| d.h. ⇒ f liefert eine „gut verteilte“ Abbildung auf ℕ. ⇒ Die modulo-‐OperaGon reduziert die Zahlen auf die Länge der Hash-‐
Tabelle
Ν∈)(uf
H Hashtabelle |H| Länge der
Hashtabelle u ganzzahliger
Schlüssel
12
Hashing: DefiniGonen 4/6
¨ Die Schlüsseldichte ist das Verhältnis zu speichernde zu mögliche Schlüssel, d.h.
¨ Der Belegungsfaktor ist das Verhältnis zu speichernde Schlüssel zu Anzahl der Behälter
U: mögliche Schlüssel S: zu speichernde Schlüssel B: Behälter
B/S
U/S
14
Hashing: DefiniGonen 5/6
o Der Füllgrad α ist das Verhältnis ¤ aktuell gespeicherte Schlüssel zu ¤ Länge der Hashtabelle, d.h.
mit m = |H| bzw. m = |B| a = Anzahl gespeicherter Schlüssel
Anmerkung Offensichtlich gilt: je höher der Füllgrad, um so größer die Wahrscheinlichkeit, dass zwei Schlüssel auf den gleichen Hash-‐Wert abgebildet werden („Kollision“).
m/a α =
15
Beispiel 1/4
Aufgabe o Verteilung von Monatsnamen auf 17
Behälter 0..16
Lösung o Namen werden als Strings dargestellt
→ Umwandlung in Zahlen notwendig ¤ nur Großbuchstaben ¤ f("A") = 1, f("B") = 2, usw.
A 1 B 2
C 3 D 4
E 5 F 6
G 7 H 8
I 9 J 10
K 11 L 12
M 13
N 14 O 15
P 16 Q 17
R 18 S 19
T 20 U 21
V 22 W 23
X 24 Y 25
Z 26
16
Beispiel 2/4
( ) ( )〉〉〈〈=
=∑x
xx
von Buchstaben 3ersten der lOrdinalzahder Summe
f3
¨ Als HashfunkGon nehmen wir ¤
¤
Beispiel: h(Februar) = (6+5+2) mod 17 = 13 mod 17 = 13 h(August) = (1+21+7) mod 17 = 29 mod 17 = 12
h(x) = f x( ) mod 17 = x( )3∑ mod 17
17
0 NOV 9 JUL 1 APR 10 2 MAE 11 JUN 3 12 AUG 4 13 FEB 5 14 6 MAI 15 7 16 8 JAN
Beispiel 3/4
• Etliche Buckets bleiben leer – Füllgrad α = Anteil der belegten Plätze in %, d.h. α = m / n mit m := Anzahl der Elemente
• Es kann zu Kollisionen kommen!
Es fehlen noch:
SEP, OKT, DEZ
, DEZ , OKT , SEP
A 1 B 2
C 3 D 4
E 5 F 6
G 7 H 8
I 9 J 10
K 11 L 12
M 13
N 14 O 15
P 16 Q 17
R 18 S 19
T 20 U 21
V 22 W 23
X 24 Y 25
Z 26
18
Beispiel 4/4
APR, DEZ à 1 MAI, SEP à 6 FEB, OKT à 13
… mehrere Schlüssel werden auf denselben Behälter abgebildet.
! Kollision
" Auflösung
l dem Behälter hinzufügen ! Verketten (lineare Liste)
l neuen Behälter suchen ! Sondieren
l vermeiden ! perfektes Hashing
19
Wahrscheinlichkeit für Kollision
mit 1 ≤ m ≤ n n ⋅ (n-‐1) ⋅ … ⋅ (n-‐m+1): Anzahl der Möglichkeiten, kollisionsfrei m
Elemente zu verteilen nm : Anzahl m Elemente
zu verteilen ¨ Beispiele
¤ Monatsnamen ¤ „Geburtstage in Schulklassen“
mmk nmnn
nmnnnnP
)!(!)1(...)2()1(1
−=
+−⋅⋅−⋅−⋅−=
n m Pk
17 12 0,99
365 22 0,48
365 23 0,51
365 50 0,97
20
Hashing: DefiniGonen 6/6
)(h )h( ba =
¨ Eine Kollision tri� auf, wenn zwei Schlüssel auf den gleichen Hashwert
abgebildet werden:
mit . ba ≠
21
Eigenscha?en einer HashfunkGon
o surjekBv ¤ d.h. alle Behälter sollten erfasst werden.
o gleichverteilend ¤ d.h. jeder Behälter sollte mit gleicher Wahrscheinlichkeit getroffen
werden. o einfach
¤ d.h. sie sollte mit minimalen Aufwand berechenbar sein.
23
Offenes bzw. geschlossenes Hashing
Problem : Was passiert wenn Anzahl Schlüssel > Anzahl Speicherplätze
Lösung :
1. Offenes Hashing:
Jeder Behälter kann beliebig viele Elemente aufnehmen. Für jeden Behälter wird eine verke�ete Liste angelegt, in die alle Schlüssel eingefügt werden, die auf diesen Behälter abgebildet werden.
2. Geschlossenes Hashing: Hier darf jeder Behälter nur eine Konstante Anzahl b ≥ 1 von Schlüsseln aufnehmen.
manchmal auch als
geschlossen bzgl. der
Indexpositionen bezeichnet
!
manchmal auch als
offen bzgl. der
Indexpositionen bezeichnet
!
24
Offenes Hashing: Verke�en
o Ein Behälter kann mehr als ein Element fassen o Alle Schlüssel s mit h(s) = a werden in Ba abgelegt
als lineare Liste o Gefahr: Entartung zur linearen Liste à Zugriffszeit wächst rapide
Maerz
…
3
4
5
…
…
… April Januar Dezember
25
Geschlossenes Hashing: Lineares Sondieren 1/3
o Pro Behälter ein Schlüssel o Bei Kollision
¤ Linear in einer Richtung nächsten freien Behälter suchen
o Formal
i=0; while (occupied(hi(x)) do i++; od; // hash-key is hi(x)
o Gefahr: Folge von besetzten Feldern vergrößert sich (Verklumpung) à Kollisionswahrscheinlichkeit steigt.
( ) mixhxhi mod)()( +=
27
Geschlossenes Hashing: Lineares Sondieren 3/3
o Varianten 1. Linear in einer Richtung
den nächsten freien Behälter suchen, mit Sprüngen der Länge c
Beispiel c = 7; h(a) = 27 falls 27 besetzt, … 27 + 7 = 34 mod m falls 34 besetzt, … 34 + 7 = 41 mod m etc.
2. Linear in beiden Richtungen (alternierend)
Beispiel h(a) = 27 falls 27 besetzt, … 27 – 1*7 = 20 mod m falls 20 besetzt, … 20 + 2*7 = 34 mod m falls 34 besetzt, … 34 – 3*7 = 13 mod m etc.
28
Geschlossenes Hashing: QuadraGsches Sondieren
mixhxh ii mod
2.)1()()(
21
⎟⎟⎠
⎞⎜⎜⎝
⎛⎥⎥
⎤⎢⎢
⎡−+= +
¨ Wie lineares Sondieren, jedoch ¤ Schri�weite quadraGsch (nicht linear) / alternierend Beispiel h(a) = 27 falls besetzt, … 27 + 12 = 28 mod m
27 – 12 = 26 mod m 27 + 22 = 31 mod m 27 – 22 = 23 mod m 27 + 32 = 36 mod m etc.
¨ Formal:
29
Löschen von Elementen
Liste: kein Problem Sondieren
¤ Element kann nicht einfach gelöscht werden, da sonst die Ke�e unterbrochen wäre.
¤ Bsp.: FEB verursacht Lücke, OKT wird nicht gefunden.
Mögliche Lösungen ¤ Element wird nicht
gelöscht, sondern nur zum Überschreiben markiert.
Folie 29 Prof. Dr. M. Gumbel • WS09 • ADS: Hashing
Lineares Sondieren
0 NOV 9 JUL 1 APR 10 2 MAE 11 JUN 3 DEZ 12 AUG 4 13 FEB 5 14 OKT 6 MAI 15 7 SEP 16 8 JAN !
30
Komplexität 1/2
Größe der Hashtabelle: N o Aufwand im besten Fall
¤ Berechnung des Hashwertes unabhängig von n: O(1)
o Aufwand im schlechtesten Fall ¤ Ganze Hashtabelle muss durchsucht werden
O(N) (Hashtabelle wg. Kollision zu lin. Liste entartet)
31
Komplexität 2/2
Größe der Hashtabelle: N o Aufwand im mi�leren Fall (bei sondieren)
¤ Wahrscheinlichkeit für Behälter j: 1/N ¤ Wahrscheinlichkeit einer Kollision:
n abhängig vom Füllgrad α n Wahrscheinlichkeit für „Behälter belegt“: α n …nächster Behälter belegt: α2
n … übernächstes Bucket belegt: α3 etc
¤ erfolgloses Suchen: 1 + α + α2 + α3+ ... =
¤ erfolgreiches Einfügen:
α−11
⎟⎠
⎞⎜⎝
⎛−αα 11ln1
32
Komplexität: Übersicht
Folie 32 Prof. Dr. M. Gumbel • WS09 • ADS: Hashing
Operation Fall Liste oder Sondieren
add bester O(1)
durchschnittlich
schlechtester O(m)
contains bester O(1)
durchschnittlich erfolgreich/-los /
schlechtester O(m)
remove bester O(1)
durchschnittlich
schlechtester O(m)
⎟⎠
⎞⎜⎝
⎛−α11O⎟
⎠
⎞⎜⎝
⎛−αα 11ln1O
⎟⎠
⎞⎜⎝
⎛−α11O
⎟⎠
⎞⎜⎝
⎛−αα 11ln1O
33
Optimaler Füllgrad α
¨ Ab Füllgrad von ca. 80 % ist das Verhalten schlecht.
Folie 33 Prof. Dr. M. Gumbel • WS09 • ADS: Hashing
α−11
αα −11ln1
Erfolgreiche Suche
Erfolglose Suche,
Einfügen, Löschen
34
Rehashing
¨ Füllgrad zu groß oder das Array voll: à Rehashing ¤ Array wird vergrößert und ¤ alle Elemente werden neu eingefügt.
¨ Vorteil: Zum Löschen markierte Elemente können ebenfalls freigegeben werden.
¨ Sog. dynamisches Hashen passt Arraygröße automaGsch an.
Folie 34 Prof. Dr. M. Gumbel • WS09 • ADS: Hashing
35
Java Hashtable-‐Klasse
Für die ImplementaGon von Hashtabellen steht uns in Java unmi�elbar die
Klasse Hashtable zur Verfügung. Sie hat die folgenden Methoden:
Hashtable(): der Konstruktor für die DefiniGon einer leeren Hashtabelle
elements(): Rückgabe aller Daten aus der Hashtabelle
isEmpty(): Abfrage, ob die Hashtabelle leer ist
get(): liefert Element gemäß Schlüsselwertangabe
36
Java Hashtable-‐Klasse
keys(): gibt alle (belegten) Schlüsselwerte der Hashtabelle zurück
put(): speichert Element gemäß Schlüsselwert in Hashtabelle
remove(): en_ernt referenziertes Hashtabellenelement
size(): gibt Anzahl gespeicherter Elemente in der Hashtabelle zurück
clear(): en_ernt alle Schlüssel und die Elemente aus der Hashtabelle
37
Java Hashtable-‐Klasse
contains(): prü?, ob sich ein Element in der Hashtabelle befindet
containsKey(): prü?, ob sich ein Schlüsselwert in der Hashtabelle befindet
clone(): erzeugt einen Klone einer Hashtabelle
toString(): generiert eine String-‐RepräsentaGon einer Hashtabelle
rehash(): führt das Rehashing für eine Hashtabelle durch.