Hashtabeller. Lars Vidar Magnusson Kapittel 11 Direkte adressering Hashtabeller Chaining Åpen-adressering

Like dokumenter
Hashing: Håndtering av kollisjoner

INF1020 Algoritmer og datastrukturer

INF1010 Hashing. Marit Nybakken 8. mars 2004

... HASHING. Hashing. Hashtabeller. hash(x)

Maps og Hashing. INF Algoritmer og datastrukturer. Map - ADT. Map vs Array

INF Algoritmer og datastrukturer

Maps og Hashing. INF Algoritmer og datastrukturer. Map - ADT. Map vs Array

Lars Vidar Magnusson

Løsningsforslag for Obligatorisk Oppgave 3. Algoritmer og Datastrukturer ITF20006

Øvingsforelesning 2 - TDT4120. Grafer og hashing. Benjamin Bjørnseth

Alg. Dat. Øvingsforelesning 3. Grafer, BFS, DFS og hashing. Børge Rødsjø

INF2220: Forelesning 3

Hashing. INF Algoritmer og datastrukturer HASHING. Hashtabeller

INF2220: Forelesning 3. Map og hashing Abstrakte datatyper (kapittel 3.1) Map (kapittel 4.8) Hashing (kapittel 5)

Kapittel 14, Hashing. Tema. Definere hashing Studere ulike hashfunksjoner Studere kollisjonsproblemet 17-1

Grunnleggende Datastrukturer

Alg. Dat. Øvingsforelesning 3. Grafer, BFS, DFS og hashing

Datastrukturer. Algoritmer og datastrukturer. Øvingsforelesning 2

INF2220: Forelesning 3

Ny/utsatt EKSAMEN. Dato: 6. januar 2017 Eksamenstid: 09:00 13:00

O(log n) - søk. Søking i et balansert søketre med n elementer er alltid O(log n) Søkingen er basert på parvise sammenligninger av to og to verdier

Lars Vidar Magnusson Kapittel 13 Rød-Svarte (Red-Black) trær Rotasjoner Insetting Sletting

Heapsort. Lars Vidar Magnusson Kapittel 6 Heaps Heapsort Prioritetskøer

... Når internminnet blir for lite. Dagens plan: Løsning: Utvidbar hashing. hash(x) katalog. O modellen er ikke lenger gyldig ved

Lars Vidar Magnusson

O(1) søking? Søking i sortert array og i søketrær: Optimalt søk som er O(1):

Sortering i Lineær Tid

Hashfunksjoner. Hashfunksjonen beregner en indeks i hashtabellen basert på nøkkelverdien som vi søker etter

Søking i strenger. Prefiks-søking Naiv algoritme Knuth-Morris-Pratt-algoritmen Suffiks-søking Boyer-Moore-algoritmen Hash-basert Karp-Rabin-algoritmen

Grunnleggende Grafalgoritmer II

EKSAMENSOPPGAVE. IAI20102 Algoritmer og datastrukturer

Notater til INF2220 Eksamen

Turingmaskiner.

EKSAMEN. Dato: 28. mai 2018 Eksamenstid: 09:00 13:00

Løsningsforslag for Obligatorisk Oppgave 2. Algoritmer og Datastrukturer ITF20006

public interface Collec>on<V> { public void add(v value); public default V remove(v value) { return null;

Quicksort. Lars Vidar Magnusson Kapittel 7 Quicksort Randomisert Quicksort Analyse av Quicksort

EKSAMENSOPPGAVE. INF-1101 Datastrukturer og algoritmer. Adm.bygget, rom K1.04 og B154 Ingen

INF 4130 / / Dagens foiler hovedsakelig laget av Petter Kristiansen Foreleser Stein Krogdahl Obliger:

Studentnummer: Side 1 av 1. Løsningsforslag, Eksamen i TDT4120 Algoritmer og datastrukturer August 2005

Ny/utsatt EKSAMEN. Dato: 5. januar 2018 Eksamenstid: 09:00 13:00

Divide-and-Conquer II

Pensum: fra boken (H-03)+ forelesninger

INF Algoritmer og datastrukturer

Grådige algoritmer. Lars Vidar Magnusson Kapittel 16. Aktivitetvelgingsproblemet Huffmankoder

Grunnleggende Grafalgoritmer III

Pensum: fra boken (H-03)+ forelesninger

INF2220: Forelesning 2

Algoritmer og Datastrukturer

Propabilistisk Analyse og Randomiserte Algoritmer

Sorteringsproblemet. Gitt en array A med n elementer som kan sammenlignes med hverandre:

Generelle Tips. INF Algoritmer og datastrukturer. Åpen og Lukket Hashing. Hashfunksjoner. Du blir bedømt etter hva du viser at du kan

Hvor raskt klarer vi å sortere?

Mål. Pensum. TDT4110 Informasjonsteknologi grunnkurs: Tema: Unntak (exceptions) (Kap 6) Dictionaries (Kap. 9) Terje Rydland - IDI/NTNU

Grunnleggende Grafalgoritmer

Liste som abstrakt konsept/datatype

Python: Rekursjon (og programmering av algoritmer) Python-bok: Kapittel 12 + teoribok om Algoritmer

Søkeproblemet. Gitt en datastruktur med n elementer: Finnes et bestemt element (eller en bestemt verdi) x lagret i datastrukturen eller ikke?

SIF8010 ALGORITMER OG DATASTRUKTURER

Eksamen i tdt4120 Algoritmer og datastrukturer

IN Algoritmer og datastrukturer

Hva er en liste? Hvert element har en forgjenger, unntatt første element i listen. Hvert element har en etterfølger, unntatt siste element i listen

Hva er en liste? Hvert element har en forgjenger, unntatt første element i listen. Hvert element har en etterfølger, unntatt siste element i listen

Divide-and-Conquer. Lars Vidar Magnusson

Uke 5 Disjunkte mengder

Forelesning 6 torsdag den 4. september

Innhold. Innledning 1

Pensum: 3. utg av Cormen et al. Øvingstime: I morgen, 14:15

Avsluttende eksamen i TDT4120 Algoritmer og datastrukturer

Om Kurset og Analyse av Algoritmer

Datastrukturer for rask søking

Backtracking som løsningsmetode

Stein Krogdahl, Dino Karabeg, Petter Kristiansen. Kenneth A. Berman and Jerome L. Paul.

Dynamisk programmering Undervises av Stein Krogdahl

Forelesning 4 torsdag den 28. august

Definisjon. I et binært tre har hver node enten 0, 1 eller 2 barn

Histogramprosessering

Høgskoleni østfold EKSAMEN. 4 dobbeltsidige ark med notater Lars Magnusson

Eksamensoppgave i TDT4120 Algoritmer og datastrukturer

Dictionary er et objekt som lagrer en samling av data. Minner litt om lister men har klare forskjeller:

Minimum Spenntrær - Kruskal & Prim

UNIVERSITETET I OSLO

Dynamisk programmering

Morfologi i Binære Bilder III

Disjunkte mengder ADT

deeegimnoorrrsstt Sjette forelesning

Oversikt. Introduksjon Kildekode Kompilering Hello world Hello world med argumenter. 1 C programmering. 2 Funksjoner. 3 Datatyper. 4 Pekere og arrays

INF Algoritmer og datastrukturer

Øvingsforelesning 4. Martin Aasen

INF2220: Time 12 - Sortering

TDT4165 PROGRAMMING LANGUAGES. Exercise 02 Togvogn-skifting

Løsningsforslag til eksamen i PG4200 Algoritmer og datastrukturer 10. desember 2014

Avsluttende eksamen i TDT4120 Algoritmer og datastrukturer

Analyse av Algoritmer

Forelesning 30: Kompleksitetsteori

Stack. En enkel, lineær datastruktur

Dagens stoff er hentet fra kapittel 9 i læreboka, samt kapittel 20.5 (som vi «hoppet over» sist)

n/b log b n = (lg n) a log b n = n log b a

INF2220: Forelesning 1. Praktisk informasjon Analyse av algoritmer (kapittel 2) (Binær)trær (kapittel )

Oversikt over kvadratiske kongruenser og Legendresymboler

Transkript:

Hashtabeller Lars Vidar Magnusson 12.2.2014 Kapittel 11 Direkte adressering Hashtabeller Chaining Åpen-adressering

Dictionaries Mange applikasjoner trenger dynamiske sett som bare har dictionary oparsjonene Insert, Search og Delete. En symboltabell i en kompilator er et eksempel. Det er mulig å implementere dictionariy operasjonene på en vanlig array, men det vil i mange situasjoner være lite praktiskt. Hashtabeller kan være et effektivt alternativ.

Direkteadresserte Arrays Direkteadresserte arrays eller tabeller kan brukes til å enkelt implementere en dictionary. Hvert element x har en nøkkel i universet U = {0, 1,..., m 1}, hvor m er relativt liten i.e vi har ganske få ulike nøkler. Hver nøkkel er unik i.e. ingen elementer har samme nøkkel. Direkteadresserte tabeller blir representert av en array T [0... m 1] Hver plass (array indeks) fungerer som en nøkkel i U. Hvis det finnes element x med nøkkel k i settet, så vil T [k] inneholde en peker til elementet. Hvis ikke vil T [k] være tom (representert av nil).

Hvordan Direkteadresserte Arrays Fungerer Figuren under viser hvordan direkteadresserte tabeller henger sammen med universet U av mulige nøkler, settet K med faktiske nøkler, og selve elementene.

Dictionary Operasjoner på Direkteadresserte Tabeller Implementasjonen av dictionary operasjoner på direkteadresserte tabeller er trivielt. Alle operasjonene har kjøretid på Θ(1).

Hashtabeller Problemet med direkteadresserte tabeller er at universet U kan bli stort i.e. det er mange mulige nøkler. I mange tilfeller blir U så stor at en tabell med plass til hver nøkkel er upraktiskt eller til og med umulig. Ofte er antall nøkler som faktiskt blir lagret liten, som vil gi mye bortkastet plass med direkteadresserte tabeller. Når settet med faktiske nøkler K er mye mindre enn universet U med alle mulige nøkler. Kan redusere lagringsbehovet til Θ( K ). Kan få O(1) i gjennomsnitt (men ikke i verstefall).

Ideen bak Hashtabeller Ideen bak hashtabeller kan summeres med at i stedet for å lagre et element x med nøkkel k på plass k, så tar vi i bruk en funksjon h og lagrer elementet på plass h(k). Vi bruker fortsatt en array T [0, 1,..., m 1], men nå er ikke m antall mulige nøkler som ved direkteadressert tabeller men ledige plasser. Vi kaller h en hashfunksjon. h : U {0, 1,..., m 1} i.e. h er en funksjon som mapper fra elementene i U til en gyldig plass i T. Vi sier at k hashes til h(k).

Hvordan Fungerer Hashtabeller Figuren under viser hvordan nøklene i K U henger sammen med hashfunksjonen h og tabellen T.

Hashtabeller og Kollisjoner Når to nøkler får samme plass i hashtabellen får vi en kollisjon. Kan forekomme hvis h er en dårlig hashfunksjon (kommer tilbake til dette senere) Kan forekomme hvis U > m (som er vanlig når hashtabeller velges fremfor direkte adressering) Må forekomme hvis K > m, men ikke nødvendigvis hvis K m. Det finnes ulike strategier for å overkomme problemet med kollisjoner. Chaining (Lenkede Lister) Åpen adressering (open addressing)

Ordne Kollisjoner med Chaining Chaining er en metode som tar i bruk lenkede lister for å overkomme problemet med hashkollisjoner. T [j] inneholder en peker til en lenket liste med alle elementer med h(k) = j. T [j] er nil hvis plassen er tom. Chaining fungerer stort sett bedre enn åpen adresssering, men strategien krever også mere plass pga. alle pekerne.

Hvordan Fungerer Chaining Figuren under viser hvordan lenkede lister kobles inn i oppsettet med nøkler og hashtabellen.

Chained-Hash-Insert Algoritmen Chained-Hash-Insert brukes for å legge til nye elementer i tabellen. Kjøretiden er Θ(1). Vi setter alltid inn det nye elementet først i den eventuelle listen. Vi antar at elementet ikke allerede er satt inn, siden det ville krevd et ekstra søk for å finne det ut.

Chained-Hash-Search Algoritmen Chained-Hash-Search algoritmen brukes til å søke etter et element x med nøkkel k. Kjøretiden er proporsjonal med antall elementer i listen i.e. elementer med samme nøkkel, men det kan bevises at gjennomsnitts kjøretid er O(1). Vi skal holde oss til en nokså overfladisk analyse av Chained-Hash-Search i denne forelesningen.

Chained-Hash-Delete Algoritmen Chained-Hash-Delete brukes til å slette elementer fra en hashtabell med lenkede lister. Vi tar en peker til elementet x som argument i stedet for nøkkelen. Dette gjør at vi kan utføre slettingen i konstant tid (Θ(1)) så lenge vi bruker en dobbeltlenket liste. Hvis vi hadde brukt en enkeltlenket liste måtte vi først utføre et søk for å finne korrekt element.

Analyse av Søking i Hashtabeller med Chaining Analysen av operasjonene på hashtabeller med chaining baseres på den såkalte load faktoren α = n/m n er antall elementer i tabellen m er antall plasser i tabellen Load faktoren α kan sees som gjennomsnitts antall elementer i hver liste (så lenge hashingen er uniform). Vi kan ha α < 1, α = 1 eller α > 1, men lavere load faktorer er naturlig nok å foretrekke.

Analyse av Søking i Hashtabeller med Chaining Verstefall kjøretid for søk i hashtabeller forekommer når alle elementene hashes til samme plass. Vi får en enkelt lang list med alle elementene. Verstefall kjøretid for å søke tabellen blir da Θ(n) pluss tiden det tar å regne ut hashverdien (normalt O(1)). Gjennomsnittsytelsen til en hashtabell er avhengig av hvor godt hashfunksjonen distruberer elementene. Det kan bevises (se i boka) at gjennomsnittskjøretiden til et søk er Θ(1 + α). Hvis n = O(m), så er α = n/m = O(m)/m = O(1) i.e. hvis antall elementer ikke er polynomisk større enn antall plasser så er kjøretiden konstant.

Hashfunksjoner En god hashfunksjon skal i prinsippet være uniform i.e. den skal sørge for at elementene blir jevnt fordelt utover tabellen. I praksis er dette normalt sett ikke mulig siden vi ikke vet noe om distribusjonen nøklene og hvorvidt de er uavhengige trukket eller ikke. Man tyr derfor ofte til heuristics, som kan beskrives som en kvalifisert gjetning eller tilnærming til et problem.

Nøkler som Naturlige Tall Hashfunksjoner går utifra at alle nøkler er naturlige tall. Når de ikke er det e.g. tekststrenger, må de konverteres til naturlige tall. Eksempel: En tekststreng med ASCII-tegn kan konvertes til et tall med radix notasjon. Vi har tekststrengen CLRS. C = 67, L = 76, R = 82 og S = 83 i ASCII verdier. Vi kan da si at CLRS = (67 128 3 ) + (76 128 2 ) + (82 128) + 83 = 141764947

Divisjonsmetoden som Hashfunksjon En hashfunksjon som bruker divisjonsmetoden kan beskrives med følgende ligning. h(k) = k mod m Eksempel: m = 20 og k = 91 gir en hashverdi på k mod m = 11.

Fordeler og Ulemper med Divisjonsmetoden Fordelen divisjonsmetoden er at den er rask siden bare en enkelt divisjon må utføres. Ulempen er at man må være forsiktig med valget av størrelsen på tabellen m. 2 er potenser er generelt sett dårlig. Hvis m = 2 p så blir h(k) bare de p minste-signifikante bittene i k. Hvis k er en tekststreng i en radix 2 p så er m = 2 p 1 et dårlig valg siden dette vil gjøre ulike permutasjoner av de samme tegnene for samme hashverdi. Et godt valg for m er typisk et primtall som er relativt langt unna en 2 er potens.

Multiplikasjonsmetoden En hashfunksjon som bruker multiplikasjonsmetoden kan beskrives med følgende ligning. h(k) = m(ka mod 1). Hvor ka mod 1 = ka ka i.e. desimaldelen av ka Vi kan også beskrive hashfunksjonen med følgende steg 1 Velg en konstant 0 < A < 1 2 Gang nøkkelen k med A 3 Trekk ut desimaldelen av resultatet 4 Gang desimaldelelen med antall plasser i tabellen m. 5 Finn nærmest heltall mindre enn resultatet og bruk denne som indeks i tabellen.

Fordeler og Ulemper med Multiplikasjonsmetoden Fordelen med multiplikasjonsmetoden er at den ikke blir preget av størrelsen m slik som divisjonsmetoden. Ulempen er at metoden er tregere en divisjonsmetoden. Det kan også være vanskelig å finne en god verdi for konstanten A. Alle gyldige verdier er mulige (0 < A < 1) Donald Knuth foreslår å bruke A ( 5 1)/2

Åpen Adressering Åpen adressering (open addressing) er et alternativ til chaining for å overkomme kollisjoner i hashverdiene. Ideen går ut på å lagre nøklene i tabellen direkte i stedet for i lenkede lister. Hvert felt inneholder enten en nøkkel eller nil. Vi utfører såkalte probes for å sjekke om en plass er ledig eller ikke. Hashfunksjonen må utvides slik at den kan returnere en sekvens av plasser å utføre probes på. Vi får da en hashfunksjon h(k, i) hvor k er nøkkelen som skal hashes og i {0, 1,... m 1}. Sekvensen av posisjoner som testes må være en permutasjon av 0, 1,..., m 1 slik at vi er innom alle posisjoner.

Hash-Search Algoritmen Hash-Search algoritmen kan brukes for å søke i en hashtabell med åpen adressering. Algoritmen returnerer enten posisjonen til elementet, eller nil hvis elementet ikke ikke ble funnet. Kjøretiden til algoritmen avhenger av hvor mange probes som må utføres før elementet finnes eller vi kommer til en ledig plass.

Hash-Insert Algoritmen Hash-Insert algoritmen brukes til å sette inn elementer inn i en hashtabell med åpen adressering. Algoritmen returner posisjonen til det nye elementet eller den kaster en exception hvis tabellen er full. Kjøretiden til algoritmen avhenger av hvor mange probes som må utføres før vi kommer til en ledig plass.

Sletting fra Hashtabeller med Åpen Adressering Man kan ikke bare slette et element fra en tabell ved å sette plassen som ledig da dette vil ødelegge både probe sekvensen. Vi prøver oss på å slette et element ved å sette posisjonen til ledig. Vi antar at elementet var det andre av tre elementer med samme nøkkel Fremtidige søk vil ikke lenger ha mulighet til å finne det siste elementet siden kjeden er brutt. En løsning er å i stedet sette posisjonen som deleted. Dette fikser problemet med søkingen. Problemet med denne løsningen er at søketiden nå ikke lenger er avhengig av load faktoren α.

Hvordan Genererer Probe-Sekvenser Ideelt sett så hadde vi hatt uniform hashing hvor alle permutasjoner m! er like sansynlige som probe-sekvenser. I praksis er det vanskelig å implementere uniform hashing Vi bruker i stedet tilnærminger, men ingen av disse er kapable til å generere m! sekvenser.

Lineær Probing I lineær probing tar vi bruk en auxiliary hashfunksjon h som fungerer som en normal hashfunksjon. Gitt en nøkkel k og et probe nummber 0 i < m så implmenteres lineær probing med følgende ligning. h(k, i) = (h (k) + i) mod m Den første probeposisjonen bestemmer hele sekvensen i.e. vi har m mulige sekvenser. Ulempen med lineær probing er at metoden lider av at det bygger seg lange sammenhengende sekvenser som påvirker søketiden.

Kvadratisk Probing Som i lineær probing så bygger kvadratisk probing på en auxiliary hashfunksjon h som angir startposisjonen. I motsetning til lineær probing så hopper vi med kvadratisk probing rundt utifra en kvadratisk funksjon. h(k, i) = (h (k) + c 1 i + c 2 i 2 ) mod m Den første probeposisjonen bestemmer hele sekvensen også her i.e. vi har m mulige sekvenser. Kvadratisk probing lider også av at elementer hoper seg opp, men med denne strategien er sjansen mindre.

Dobbelhash Probing I dobbelhash probing (double hashing) benytter vi i motsetning til de andre metodene to auxiliary hashfunksjoner h 1 og h 2. h 1 bestemmer første probeposisjon, mens h 2 bestemmer de resterende. h(k, i) = (h 1 (k) + ih 2 (k)) mod m Metoden gir Θ(n 2 ) mulige sekvenser, som er en vesentlig forbedring. Hashfunksjonen h 2 må ha få faktorer felles med m for å besøke alle posisjonene. Kan velge m til å være en 2 er potens og la h 2 alltid generere oddetall større enn 1. Kan la m være et primtall og la 1 < h 2(k) < m.

Analyse av Åpen Adressering Som med chaining så er effektiviteten til åpen adressering avhengig av load faktoren α = n/m. Det kan bevises (se fagboka) at det forventede antallet probes i et søk som ikke finner elementet er 1/(1 α). Dette gir en konstant kjøretid på begge operasjonene så lenge α er konstant.