G.Heyer Algorithmen und Datenstrukturen 1 13. Kapitel: Hashfunktionen 1) Divisionsrest-Verfahren (...

30
G.Heyer Algorithmen und Datenstrukturen 1 13. Kapitel: Hashfunktionen 1) Divisionsrest-Verfahren ( kurz: Divisionsverfahren) h(K i ) = K i mod q, (q ~ m) Der entstehende Rest ergibt die relative Adresse in HT. Beispiel: Die Funktion nat wandle Namen in natürliche Zahlen um: nat(Name) = ord (1. Buchstabe von Name ) - ord (“A”) h (Name) = nat (Name) mod m

Transcript of G.Heyer Algorithmen und Datenstrukturen 1 13. Kapitel: Hashfunktionen 1) Divisionsrest-Verfahren (...

Page 1: G.Heyer Algorithmen und Datenstrukturen 1 13. Kapitel: Hashfunktionen 1) Divisionsrest-Verfahren ( kurz: Divisionsverfahren) h(K i ) = K i mod q, (q ~

G.Heyer Algorithmen und Datenstrukturen1

13. Kapitel: Hashfunktionen

1) Divisionsrest-Verfahren ( kurz: Divisionsverfahren)

h(Ki) = Ki mod q, (q ~ m)Der entstehende Rest ergibt die relative Adresse in HT.

Beispiel:

Die Funktion nat wandle Namen in natürliche Zahlen um:nat(Name) = ord (1. Buchstabe von Name ) - ord (“A”)h (Name) = nat (Name) mod m

Page 2: G.Heyer Algorithmen und Datenstrukturen 1 13. Kapitel: Hashfunktionen 1) Divisionsrest-Verfahren ( kurz: Divisionsverfahren) h(K i ) = K i mod q, (q ~

G.Heyer Algorithmen und Datenstrukturen2

Hash-Tabelle:m = 10 Schlüssel Daten

0

1

2

3

4

5

6

7

8

9

BOHR D1

CURIE D2

DIRAC D3

EINSTEIN D4

PLANCK D5

HEISENBERG D7

SCHRÖDINGER D8

Page 3: G.Heyer Algorithmen und Datenstrukturen 1 13. Kapitel: Hashfunktionen 1) Divisionsrest-Verfahren ( kurz: Divisionsverfahren) h(K i ) = K i mod q, (q ~

G.Heyer Algorithmen und Datenstrukturen3

Divisionsrest- Verfahren: Forderungen an Divisor q1) m > n• Belegungsfaktor von HT: Verhältnis von aktuell belegten

Speicherplätzen (n) zur gesamten Anzahl der

Speicherplätze (m) = na / m• Für 0.85 erzeugen alle Hash-Funktionen viele

Kollisionen und damit einen hohen Zusatzaufwand.

2) q gerade Zahl

sonst bleibt h (Ki) bei geradem Ki gerade und bei

ungeradem Ki ungerade.

3) q bk

b sei die Basis der Schlüsseldarstellung. Wenn q = bk ist,

dann liefert h (Ki) die letzten k Stellen von Ki.

h(Ki) = Ki mod q

Page 4: G.Heyer Algorithmen und Datenstrukturen 1 13. Kapitel: Hashfunktionen 1) Divisionsrest-Verfahren ( kurz: Divisionsverfahren) h(K i ) = K i mod q, (q ~

G.Heyer Algorithmen und Datenstrukturen4

4) q a * bk ca und c seien kleine ganze Zahlen. Der Divisor q soll nicht benachbart zu einer Potenz des Zahlensystems (in dem die Division durchgeführt wird) liegen, da sonst

(x + a * bk c ) mod q ~ x mod q ist, d. h., bei

gleichen Endziffern wiederholt sich fast die gleiche Menge von Adressen in verschiedenen Zahlenbereichen.

5) q = Primzahl ( größte Primzahl <= m)

Die Hash-Funktion muss etwaige Regelmäßigkeiten in der Schlüsselverteilung eliminieren, damit nicht ständig die gleichen Plätze der HT getroffen werden.

Bei äquidistantem Abstand der Schlüssel

Ki + j * K, j = 0, 1, 2, ,... maximiert eine Primzahl die Distanz, nach der eine Kollision auftritt.

Page 5: G.Heyer Algorithmen und Datenstrukturen 1 13. Kapitel: Hashfunktionen 1) Divisionsrest-Verfahren ( kurz: Divisionsverfahren) h(K i ) = K i mod q, (q ~

G.Heyer Algorithmen und Datenstrukturen5

Eine Kollision ergibt sich, wennKi mod q = (Ki + j * K) mod q oder

j * K = k * q, k = 1, 2, 3, ...

Eine Primzahl kann keine gemeinsamen Faktoren mit K besitzen, die den Kollisionsabstand verkürzen würden.

==> wichtigste Forderung an q !

2) Faltung

• Schlüssel wird in Teile zerlegt, die bis auf das letzte die

Länge einer Adresse für HT besitzen.

• Schlüsselteile werden dann übereinander gefaltet und

addiert.

Page 6: G.Heyer Algorithmen und Datenstrukturen 1 13. Kapitel: Hashfunktionen 1) Divisionsrest-Verfahren ( kurz: Divisionsverfahren) h(K i ) = K i mod q, (q ~

G.Heyer Algorithmen und Datenstrukturen6

3) Mid-Square-Methode• Schlüssel Ki wird quadriert, t aufeinanderfolgende Stellen

werden aus der Mitte des Ergebnisses für die Adressierung

ausgewählt.

• Es muss also bt = m gelten.

• Mittlere Stellen lassen beste Gleichverteilung der Werte

erwarten.

• Beispiel für b = 2, t = 4, m = 16 : Ki = 1100100

Ki2 = 10011100010000 h (Ki) = 1000

t

Page 7: G.Heyer Algorithmen und Datenstrukturen 1 13. Kapitel: Hashfunktionen 1) Divisionsrest-Verfahren ( kurz: Divisionsverfahren) h(K i ) = K i mod q, (q ~

G.Heyer Algorithmen und Datenstrukturen7

4) Weitere Verfahren

• Zufallsmethode: Ki dient als Saat für Zufallszahlengenerator

• Ziffernanalyse: setzt Kenntnis der Schlüsselmenge K voraus.

Die t Stellen mit der besten Gleichverteilung der Ziffern

oder Zeichen in K werden von Ki zur Adressierung

ausgewählt.

Bewertung

Das Verhalten einer Hash-Funktion hängt von der gewählten Schlüsselmenge ab.

Deshalb lassen sie sich auch nur unzureichend theoretisch oder mit Hilfe von analytischen Modellen untersuchen.

Page 8: G.Heyer Algorithmen und Datenstrukturen 1 13. Kapitel: Hashfunktionen 1) Divisionsrest-Verfahren ( kurz: Divisionsverfahren) h(K i ) = K i mod q, (q ~

G.Heyer Algorithmen und Datenstrukturen8

Über die Güte der verschiedenen Hash-Funktionen liegen

jedoch eine Reihe von empirischen Untersuchungen vor.• Das Divisionsrest-Verfahren ist im Mittel am

leistungsfähigsten; für bestimmte Schlüsselmengen können

jedoch andere Techniken besser abschneiden.

• Keine Hash-Funktion ist immer besser als alle anderen.

• Wenn die Schlüsselverteilung nicht bekannt ist, dann ist

das Divisionsrest-Verfahren die bevorzugte Hash-Technik.

==> Wenn eine Hash-Funktion gegeben ist, lässt sich immer eine Schlüsselmenge finden, bei der sie besonders viele Kollisionen erzeugt.

Page 9: G.Heyer Algorithmen und Datenstrukturen 1 13. Kapitel: Hashfunktionen 1) Divisionsrest-Verfahren ( kurz: Divisionsverfahren) h(K i ) = K i mod q, (q ~

G.Heyer Algorithmen und Datenstrukturen9

Behandlung von KollisionenZwei Ansätze, wenn h (Kq) = h (Kp):

• Es wird für Kp eine freier Platz in HT gesucht ; alle

Überläufer werden im Primärbereich untergebracht

(open adressing).

• Kp wird in einem separaten Überlaufbereich zusammen mit

allen anderen Überläufern gespeichert (separate overflow)

Die Methode der Kollisions-Auflösung entscheidet darüber, welche Folge und wie viele relative Adressen zur Ermittlung eines freien Platzes aufgesucht werden.

Page 10: G.Heyer Algorithmen und Datenstrukturen 1 13. Kapitel: Hashfunktionen 1) Divisionsrest-Verfahren ( kurz: Divisionsverfahren) h(K i ) = K i mod q, (q ~

G.Heyer Algorithmen und Datenstrukturen10

Adressfolge bei Speicherung und Suche für Schlüssel Kp sei

h0(Kp), h1(Kp), h2(Kp), ...

• Bei einer Folge der Länge n treten also n-1 Kollisionen auf

• Primärkollision: h (K p) = h (K q)

• Sekundärkollision: h i (Kp) = h j(Kq) , i j

Offene Hash-Verfahren

Speicherung der Synonyme (Überläufer) im Primärbereich

Das eingesetzte Hash-Verfahren muss in der Lage sein, eine Sondierungsfolge, d. h. eine Permutation aller Hash-Adressen, zu berechnen.

Page 11: G.Heyer Algorithmen und Datenstrukturen 1 13. Kapitel: Hashfunktionen 1) Divisionsrest-Verfahren ( kurz: Divisionsverfahren) h(K i ) = K i mod q, (q ~

G.Heyer Algorithmen und Datenstrukturen11

1) Lineares Sondieren (linear probing)

Von der Hausadresse aus wird sequentiell (modulo) gesucht. Diese Vorgehensweise kann mit jedem Hash-Verfahren kombiniert werden. Offensichtlich werden dabei alle Plätze in HT erreicht:

h0 (K p) = h (K p)

h i (K p) = ( h 0( K p ) - i ) mod m, i = 1, 2, ...

Page 12: G.Heyer Algorithmen und Datenstrukturen 1 13. Kapitel: Hashfunktionen 1) Divisionsrest-Verfahren ( kurz: Divisionsverfahren) h(K i ) = K i mod q, (q ~

G.Heyer Algorithmen und Datenstrukturen12

Beispiel: Einfüge-Reihenfolge:

BECKETT, HESSE, BÖLL, HAUPTMANN, STEINBECK, SACHS, HAMSUN, SARTRE

HT: m = 8

01234567

Schlüssel Schlüssel01234567

Lösche

Page 13: G.Heyer Algorithmen und Datenstrukturen 1 13. Kapitel: Hashfunktionen 1) Divisionsrest-Verfahren ( kurz: Divisionsverfahren) h(K i ) = K i mod q, (q ~

G.Heyer Algorithmen und Datenstrukturen13

• Irgendeine Primär- oder Sekundärkollision kann eine Häufung von Primär- oder Sekundärkollision auslösen.

• Löschen: implizit oft Verschiebungen. Entstehende Lücken

in Suchsequenzen sind auszufüllen, da das Antreffen eines

freien Platzes die Suche beendet.

Page 14: G.Heyer Algorithmen und Datenstrukturen 1 13. Kapitel: Hashfunktionen 1) Divisionsrest-Verfahren ( kurz: Divisionsverfahren) h(K i ) = K i mod q, (q ~

G.Heyer Algorithmen und Datenstrukturen14

Suche in einer Hash-Tabelle bei linearem Sondierenvoid Linsuche (Key X, Hashtab HT, Cardinal m, Cardinal j)

{ /* Suche in HT bei linearem Sondieren */

/*Bei erfolgreicher Suche zeigt j auf Position von X in HT */

Cardinal i;

i = H [X]; /* H sei global definierte Hash-Funktion */

j = i ; /* unbelegter Eintrag in HT sei durch */

/* „ - “ - Zeichen charakterisiert */

while ( (HT [ j ] != X) && (HT[ j ] != „ - „ ) )

{ j = (j -1 ) % m;

if ( i == j)

{ printf ( „ X ist nicht in HT \n“); return ; }

if ( HT [ j ] == „ - „ ) printf („ X ist nicht in HT \n“);

}

return;

}

Page 15: G.Heyer Algorithmen und Datenstrukturen 1 13. Kapitel: Hashfunktionen 1) Divisionsrest-Verfahren ( kurz: Divisionsverfahren) h(K i ) = K i mod q, (q ~

G.Heyer Algorithmen und Datenstrukturen15

Verbesserung: Modifikation der Überlauffolge(z.B. durch quadratisches Sondieren)

h0 ( K p) = h ( K p)

h i+1 ( K p ) = ( hi ( K p ) + f ( i ) ) mod m oder

h i+1 (K p) = (h i ( Kp ) + f ( i, h ( K p ) ) ) mod m , i= 1, 2, ...

2) Sondieren mit Zufallszahlen

Mit Hilfe eines deterministischen Pseudo-Zufallszahlen-Generators wird die Folge der Adressen [1 ... m-1] mod m genau einmal erzeugt. Abhängig von k wird eine zufällige Hashadresse s(j, k) gewählt.

h0 (K p) = h (K p)

h i (K p) = ( h0 (K p) + z i ) mod m , i = 1, 2, ...

Page 16: G.Heyer Algorithmen und Datenstrukturen 1 13. Kapitel: Hashfunktionen 1) Divisionsrest-Verfahren ( kurz: Divisionsverfahren) h(K i ) = K i mod q, (q ~

G.Heyer Algorithmen und Datenstrukturen16

3) Double-HashingEinsatz einer zweiten Funktion für die Sondierungsfolge

h0 (Kp) = h (Kp)

hi (Kp) = ( h0 (Kp) + i * h‘ (Kp) ) mod m , i = 1, 2, ...

Dabei ist h‘ (K) so zu wählen, dass für alle Schlüssel K die

resultierende Sondierungsfolge eine Permutation aller

Hash-Adressen bildet.

4) Kettung von Synonymen

• Explizite Kettung aller Sätze einer Kollisionsklasse

verringert nicht die Anzahl der Kollisionsklassen; verkürzt

jedoch den Suchpfad beim Aufsuchen eines Synonyms.

• Bestimmung eines freien Überlaufplatzes

(Kollisionsbehandlung) mit beliebiger Methode

Page 17: G.Heyer Algorithmen und Datenstrukturen 1 13. Kapitel: Hashfunktionen 1) Divisionsrest-Verfahren ( kurz: Divisionsverfahren) h(K i ) = K i mod q, (q ~

G.Heyer Algorithmen und Datenstrukturen17

Hash-Verfahren mit separatem ÜberlaufbereichDynamische Speicherplatz-Belegung für Synonyme

• Alle Sätze, die nicht auf ihrer Hausadresse unterkommen,

werden in einem separaten Bereich gespeichert.

• Die Bestimmung der Überlaufadresse kann entweder

durch Double Hashing oder durch Kettung der Synonyme

erfolgen.

• Die Synonym-Kettung erlaubt auch die Möglichkeit, den

Speicherplatz für Überläufer dynamisch zu belegen.

• Suchen, Einfügen und Löschen sind auf Kollisionsklasse

beschränkt.

• Unterscheidung nach Primär- und Sekundärbereich

Page 18: G.Heyer Algorithmen und Datenstrukturen 1 13. Kapitel: Hashfunktionen 1) Divisionsrest-Verfahren ( kurz: Divisionsverfahren) h(K i ) = K i mod q, (q ~

G.Heyer Algorithmen und Datenstrukturen18

Beispiel:

HAYDN *

HT:

m = 7

0

1

2

3

4

5

6

BEETHOVEN

CORELLI

SCHUBERT

MOZART

HÄNDEL *

BACH BRAHMS **

*

*

*

*

* *

LISZT *

*VIVALDI

Schlüssel

Page 19: G.Heyer Algorithmen und Datenstrukturen 1 13. Kapitel: Hashfunktionen 1) Divisionsrest-Verfahren ( kurz: Divisionsverfahren) h(K i ) = K i mod q, (q ~

G.Heyer Algorithmen und Datenstrukturen19

Analyse des HashingKostenmaße

• = n / m : Belegung von HT mit n Schlüsseln

• Sn = # Suchschritte für das Auffinden eines Schlüssels -

entspricht den Kosten für erfolgreiche Suche und

Löschen (ohne Reorganisation)

• Un = # der Suchschritte für die erfolglose Suche -

das Auffinden des ersten freien Platzes entspricht den

Einfügekosten

Grenzwerte: best case worst case

Sn = 1 Sn = n

Un = 1 Un = n + 1

Page 20: G.Heyer Algorithmen und Datenstrukturen 1 13. Kapitel: Hashfunktionen 1) Divisionsrest-Verfahren ( kurz: Divisionsverfahren) h(K i ) = K i mod q, (q ~

G.Heyer Algorithmen und Datenstrukturen20

Modell für das lineare Sondieren

• sobald eine gewisse Größe überschreitet, verschlechtert

sich das Zugriffsverhalten sehr stark.

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16

• Je länger eine Liste ist, um so schneller wird sie noch

länger werden.

• Zwei Listen können zusammen wachsen (Platz 3 und 14),

so dass durch neue Schlüssel eine Art Verdopplung der

Listenlänge eintreten kann.

Page 21: G.Heyer Algorithmen und Datenstrukturen 1 13. Kapitel: Hashfunktionen 1) Divisionsrest-Verfahren ( kurz: Divisionsverfahren) h(K i ) = K i mod q, (q ~

G.Heyer Algorithmen und Datenstrukturen21

Ergebnisse für das lineare Sondieren nach Knuth

Sn 0.5 1 + ------- 1

1 - mit 0 = --- < 1 n

mUn 0.5 1 + ---------

1

( 1 - )2

Abschätzung für offene Hash-Verfahren mit optimierter Kollisions-Behandlung

(gleichmäßige HT-Verteilung von Kollisionen)

Sn ~ - --- * ln ( 1 - ) Un ~ -------- 1

1

1 -

Page 22: G.Heyer Algorithmen und Datenstrukturen 1 13. Kapitel: Hashfunktionen 1) Divisionsrest-Verfahren ( kurz: Divisionsverfahren) h(K i ) = K i mod q, (q ~

G.Heyer Algorithmen und Datenstrukturen22

Anzahl der Suchschritte in HT

10 9 8 7 6 5 4 3 2 1

Sn, Un

0.1 0.3 0.5 0.7 0.9

Un

10 9 8 7 6 5 4 3 2 1

0.1 0.3 0.5 0.7 0.9

Sn Un

Sn

bei linearem Sondieren bei „unabhängiger“ Kollisions-Auflösung

Sn, Un

Page 23: G.Heyer Algorithmen und Datenstrukturen 1 13. Kapitel: Hashfunktionen 1) Divisionsrest-Verfahren ( kurz: Divisionsverfahren) h(K i ) = K i mod q, (q ~

G.Heyer Algorithmen und Datenstrukturen23

Analyse des Hashing (2)Modell für separate Überlaufbereiche

• Annahme: n Schlüssel verteilen sich gleichförmig über die m möglichen Ketten.

• Jede Synonym-Kette hat also im Mittel n/m = Schlüssel.

Wenn der i-te Schlüssel Ki in HT eingefügt wird, sind in jeder Kette ( i -1 ) / m Schlüssel. Die Suche nach Ki kostet also 1 + ( i -1 ) / m Schritte, da Ki an das jeweilige Ende einer Kette angehängt wird.

Erwartungswert für erfolgreiche Suche:

Sn = 1/n * 1 + ------ = 1 + ------- 1 + - i = 1

n i - 1

m

n - 1

2 * m

2

Page 24: G.Heyer Algorithmen und Datenstrukturen 1 13. Kapitel: Hashfunktionen 1) Divisionsrest-Verfahren ( kurz: Divisionsverfahren) h(K i ) = K i mod q, (q ~

G.Heyer Algorithmen und Datenstrukturen24

Bei der erfolglosen Suche muss immer die ganze Kettedurchlaufen werden. Die Kostenformel hat somit folgende Struktur:

Un = 1 + 1 * WS ( zu einer Hausadresse existiert ein Überläufer)

+ 2 * WS (zu einer Hausadresse existieren zwei Überläufer)

+ 3 * .....

Un - e -

0.5 0.75 1 1.5 2 3 4 5

Sn 1.25 1.37 1.5 1.75 2 2.5 3 3.5

Un 1.11 1.22 1.37 1.72 2.14 3.05 4.02 5.01

Page 25: G.Heyer Algorithmen und Datenstrukturen 1 13. Kapitel: Hashfunktionen 1) Divisionsrest-Verfahren ( kurz: Divisionsverfahren) h(K i ) = K i mod q, (q ~

G.Heyer Algorithmen und Datenstrukturen25

Separate Kettung ist auch der „unabhängigen“ Kollisions-Auflösung überlegen.

Hashing ist i. a. ein sehr leistungsstarkes Verfahren. Selbst bei starker Überbelegung ( > 1 ) erhält man bei separater Kettung noch günstige Werte.

Page 26: G.Heyer Algorithmen und Datenstrukturen 1 13. Kapitel: Hashfunktionen 1) Divisionsrest-Verfahren ( kurz: Divisionsverfahren) h(K i ) = K i mod q, (q ~

G.Heyer Algorithmen und Datenstrukturen26

Dynamische Hash-VerfahrenWachstumsprobleme bei statischen Verfahren

• Statische Allokation von Speicherbereichen:

Speicherausnutzung ?• Bei Erweiterung des Adressraumes: Rehashing

==> Kosten, Verfügbarkeit, AdressierbarkeitS

h

h‘

A

A‘

==> alle Sätze erhalten eine neue Adresse

Page 27: G.Heyer Algorithmen und Datenstrukturen 1 13. Kapitel: Hashfunktionen 1) Divisionsrest-Verfahren ( kurz: Divisionsverfahren) h(K i ) = K i mod q, (q ~

G.Heyer Algorithmen und Datenstrukturen27

Entwurfsziele

• Eine im Vergleich zu statischen Hashing dynamische

Struktur erlaubt Wachstum und Schrumpfung des

Hash-Bereichs ( Datei )

• keine Überlauftechniken

• Zugriffsfaktor 2 für direkte Suche

Viele konkurrierende Ansätze

• Extendible Hashing ( Fagin et al., 1978 )

• Virtual Hashing und Linear Hashing ( Letwin, 1978, 1980 )

• Dynamic Hashing (Larson, 1978 )

Page 28: G.Heyer Algorithmen und Datenstrukturen 1 13. Kapitel: Hashfunktionen 1) Divisionsrest-Verfahren ( kurz: Divisionsverfahren) h(K i ) = K i mod q, (q ~

G.Heyer Algorithmen und Datenstrukturen28

ZusammenfassungHash-Funktion

• berechnet Speicheradresse des Satzes

• zielt auf bestmögliche Gleichverteilung der Sätze im

Hash-Bereich

Hashing bietet im Vergleich zu Bäumen eine eingeschränkte

Funktionalität

• direkter Schlüsselzugriff

• i. a. kein sortiert sequentieller Zugriff

• ordnungserhaltendes Hashing nur in Sonderfällen

anwendbar

• statisches Verfahren

Page 29: G.Heyer Algorithmen und Datenstrukturen 1 13. Kapitel: Hashfunktionen 1) Divisionsrest-Verfahren ( kurz: Divisionsverfahren) h(K i ) = K i mod q, (q ~

G.Heyer Algorithmen und Datenstrukturen29

Idealfall: Direkte Adressierung• nur in Ausnahmefällen möglich ( „dichte“ Schlüsselmenge)

• jeder Satz kann mit einem Zugriff referenziert, eingefügt

oder gelöscht werden

Hash-Verfahren im Hauptspeicher

• Standard: Divisions-Rest-Verfahren

• bei offenen Hash-Verfahren ist der

Belegungsgrad 0.85

dringend zu empfehlen

• Kollisionsbehandlung mit separatem Überlaufbereich

i. a. effizienter und einfacher zu realisieren

Page 30: G.Heyer Algorithmen und Datenstrukturen 1 13. Kapitel: Hashfunktionen 1) Divisionsrest-Verfahren ( kurz: Divisionsverfahren) h(K i ) = K i mod q, (q ~

G.Heyer Algorithmen und Datenstrukturen30

Erweiterungen: dynamische Hashing-Verfahren

• Reorganisationsfreiheit

• Viele Vorschläge: Erweiterbares Hashing,

Lineares Hashing, ...

( 2 Seitenzugriffe )