1 / 30

13. Kapitel: Hashfunktionen

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:

misty
Download Presentation

13. Kapitel: Hashfunktionen

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


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

  3. 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   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 Divisionsrest- Verfahren: Forderungen an Divisor q

  4. 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. 4) q  a * bk  c 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. 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. Eine Kollision ergibt sich, wenn

  6. 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 3) Mid-Square-Methode

  7. 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. 4) Weitere Verfahren

  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 vieleKollisionen 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 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 Lösche

  13. 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. Irgendeine Primär- oder Sekundärkollision kann eine

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

  15. (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, ... Verbesserung: Modifikation der Überlauffolge

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

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

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

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

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

  21. Ergebnisse für das lineare Sondieren nach Knuth 1 1 -  Sn 0.5 1 + ------- n m mit 0   = --- < 1 1 ( 1 -  )2 Un 0.5 1 + --------- 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 0.1 0.3 0.5 0.7 0.9 0.1 0.3 0.5 0.7 0.9 bei „unabhängiger“ Kollisions-Auflösung bei linearem Sondieren

  23. 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: Analyse des Hashing (2) n i - 1 m n - 1 2 * m  2 Sn = 1/n *  1 + ------ = 1 + -------  1 + - i = 1

  24. durchlaufen 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 - Bei der erfolglosen Suche muss immer die ganze Kette  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

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

  27. 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 ) Entwurfsziele

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

  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 )

More Related