Die Präsentation wird geladen. Bitte warten

Die Präsentation wird geladen. Bitte warten

13. Kapitel: Hashfunktionen

Ähnliche Präsentationen


Präsentation zum Thema: "13. Kapitel: Hashfunktionen"—  Präsentation transkript:

1 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

2 Hash-Tabelle: m = 10 Schlüssel Daten 1 2 3 4 5 6 7 8 9 BOHR D1
1 2 3 4 5 6 7 8 9 BOHR D1 CURIE D2 DIRAC D3 EINSTEIN D4 PLANCK D5 HEISENBERG D7 SCHRÖDINGER D8

3 Divisionsrest- Verfahren: Forderungen an Divisor q
1) m > n Belegungsfaktor von HT: Verhältnis von aktuell belegten Speicherplätzen (n) zur gesamten Anzahl der Speicherplätze (m)  = na / m Für   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

4 4) q  a * bk  c a 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.

5 Eine Kollision ergibt sich, wenn
Ki 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.

6 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 = Ki2 =  h (Ki) = 1000 t

7 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.

8 Ü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.

9 Behandlung von Kollisionen
Zwei 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.

10 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.

11 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, ...

12 Beispiel: Einfüge-Reihenfolge:
BECKETT, HESSE, BÖLL, HAUPTMANN, STEINBECK, SACHS, HAMSUN, SARTRE HT: m = 8 Schlüssel Schlüssel 1 2 3 4 5 6 7 1 2 3 4 5 6 7 Lösche

13 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.

14 Suche in einer Hash-Tabelle bei linearem Sondieren
void 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;

15 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, ...

16 3) Double-Hashing Einsatz 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

17 Hash-Verfahren mit separatem Überlaufbereich
Dynamische 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

18 Beispiel: Schlüssel 1 2 3 4 5 6 * * * * * * * * * * * * HT: m = 7
1 2 3 4 5 6 HAYDN * HÄNDEL * VIVALDI * BEETHOVEN * BACH * BRAHMS * CORELLI * * SCHUBERT * LISZT * MOZART * *

19 Analyse des Hashing Kostenmaß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

20 Modell für das lineare Sondieren
sobald  eine gewisse Größe überschreitet, verschlechtert sich das Zugriffsverhalten sehr stark. 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.

21 Ergebnisse für das lineare Sondieren nach Knuth
1 1 -  Sn  n m mit 0   = < 1 1 ( 1 -  )2 Un  Abschätzung für offene Hash-Verfahren mit optimierter Kollisions-Behandlung (gleichmäßige HT-Verteilung von Kollisionen) 1 1 -  1 Sn ~ * ln ( 1 -  ) Un ~

22 Anzahl der Suchschritte in HT
Sn, Un Sn, Un 10 9 8 7 6 5 4 3 2 1 10 9 8 7 6 5 4 3 2 1 Un Sn Un Sn bei „unabhängiger“ Kollisions-Auflösung bei linearem Sondieren

23 Modell für separate Überlaufbereiche
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 ( i -1 ) / m Schritte, da Ki an das jeweilige Ende einer Kette angehängt wird. Erwartungswert für erfolgreiche Suche: n i - 1 m n - 1 2 * m 2 Sn = 1/n *  =  i = 1

24 Bei der erfolglosen Suche muss immer die ganze Kette
durchlaufen werden. Die Kostenformel hat somit folgende Struktur: Un = * WS ( zu einer Hausadresse existiert ein Überläufer) + 2 * WS (zu einer Hausadresse existieren zwei Überläufer) + 3 * ..... Un   - e - Sn Un

25 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.

26 Dynamische Hash-Verfahren
Wachstumsprobleme bei statischen Verfahren Statische Allokation von Speicherbereichen: Speicherausnutzung ? Bei Erweiterung des Adressraumes: Rehashing ==> Kosten, Verfügbarkeit, Adressierbarkeit S A‘ A h h‘ ==> alle Sätze erhalten eine neue Adresse

27 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, )

28 Zusammenfassung Hash-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

29 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

30 Erweiterungen: dynamische Hashing-Verfahren
Reorganisationsfreiheit Viele Vorschläge: Erweiterbares Hashing, Lineares Hashing, ... (  2 Seitenzugriffe )


Herunterladen ppt "13. Kapitel: Hashfunktionen"

Ähnliche Präsentationen


Google-Anzeigen