12.07.2015 Views

Tabelle di Hash ADT Dizionario - Xoom.it

Tabelle di Hash ADT Dizionario - Xoom.it

Tabelle di Hash ADT Dizionario - Xoom.it

SHOW MORE
SHOW LESS
  • No tags were found...

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

Algor<strong>it</strong>mi e Programmazione Avanzata<strong>Tabelle</strong> <strong>di</strong> hash<strong>Tabelle</strong> <strong>di</strong> <strong>Hash</strong>Fulvio Corno, Matteo Sonza ReordaDip. Automatica e InformaticaPol<strong>it</strong>ecnico <strong>di</strong> Torino<strong>ADT</strong> <strong>Dizionario</strong>In molte applicazioni è necessario un <strong>ADT</strong>“<strong>Dizionario</strong>” che supporti le seguentioperazioni:• INSERT: Inserisce un elemento nuovo, conun certo valore (unico) <strong>di</strong> un campo chiave• SEARCH: Determina se un elemento con uncerto valore della chiave esiste; se esiste,lo rest<strong>it</strong>uisce• DELETE: Elimina l’elemento identificato dalcampo chiave, se esiste.A.A. 2001/2002 APA-hash 21


Algor<strong>it</strong>mi e Programmazione Avanzata<strong>Tabelle</strong> <strong>di</strong> hashEsempi• Tabella dei simboli <strong>di</strong> un compilatore• Chiave = nome <strong>di</strong> un identificatore• Dati aggiuntivi = tipo, contesto, <strong>di</strong>chiarazione• Cache <strong>di</strong> file o URL• Chiave = path• Dati aggiuntivi = attributi e contenutoA.A. 2001/2002 APA-hash 3Array associativiUna struttura a <strong>di</strong>zionario si potrebbeimplementare facilmente <strong>di</strong>sponendo <strong>di</strong> arrayassociativi, ossia vettori in<strong>di</strong>cizzabili percontenuto anziché per posizione.Esempio (<strong>di</strong> fantasia):• Simboli[“main”] = { prog.c, 100, void, {int,char **}}• Line n = Simboli[“counter”].linenumA.A. 2001/2002 APA-hash 42


Algor<strong>it</strong>mi e Programmazione Avanzata<strong>Tabelle</strong> <strong>di</strong> hashObiettiviLe tabelle <strong>di</strong> hash sono una tecnicaimplementativa per realizzare arrayassociativi.Si vuole ottenere una compless<strong>it</strong>à nel caso piùfrequente O(1) per le 3 operazionifondamentali, anche se nel caso peggiore èΘ(n).A.A. 2001/2002 APA-hash 5Idea baseOgni elemento è memorizzato ad un certoin<strong>di</strong>rizzo <strong>di</strong> un array.L’in<strong>di</strong>rizzo, anziché venire calcolato da unafunzione <strong>di</strong> ricerca, viene calcolato daun’opportuna funzione, detta funzione <strong>di</strong>hash, in tempo O(1).Esempio:• <strong>Hash</strong>(“main”) = 117: il simbolo “main” èmemorizzato alla posizione 117 dell’array.A.A. 2001/2002 APA-hash 63


Algor<strong>it</strong>mi e Programmazione Avanzata<strong>Tabelle</strong> <strong>di</strong> hash<strong>Tabelle</strong> associative•1•2•4U (universo delle chiavi)•7•0•6•9•3 •5•80123456789T2358chiaveK (chiavi usate)dati associatiA.A. 2001/2002 APA-hash 7<strong>Dizionario</strong> me<strong>di</strong>ante tabellaassociativa• T: tabella associativa, k: chiave, x:elemento• Search(T, k)• Return T[k]• Insert(T, x)• T[key[x]] ← x• Delete(T, x)• T[key[x]] ← NIL• Compless<strong>it</strong>à O(1), occupazione O(|U|)A.A. 2001/2002 APA-hash 84


Algor<strong>it</strong>mi e Programmazione Avanzata<strong>Tabelle</strong> <strong>di</strong> hashIpotesiLo schema precedente funziona solamente sesono verificate delle assunzioni fondamentali:• Non esistono elementi con chiave uguale• L’array T contiene tanti elementi quantisono i possibili valori <strong>di</strong>versi delle chiavi.A.A. 2001/2002 APA-hash 9<strong>Tabelle</strong> <strong>di</strong> <strong>Hash</strong>Nella maggior parte dei casi, il numero <strong>di</strong>elementi |K| è molto minore del numero <strong>di</strong>valori possibili delle chiavi |U|.Quando l’universo delle chiavi è vasto (|U|cresce) non è possibile allocare il vettore T.Una tabella <strong>di</strong> hash è una struttura dati conun’occupazione <strong>di</strong> spazio O(|K|) e tempi <strong>di</strong>accesso O(1), nel caso me<strong>di</strong>o.A.A. 2001/2002 APA-hash 105


Algor<strong>it</strong>mi e Programmazione Avanzata<strong>Tabelle</strong> <strong>di</strong> hashFunzione <strong>di</strong> hash• La tabella <strong>di</strong> hash contiene m elementi(m


Algor<strong>it</strong>mi e Programmazione Avanzata<strong>Tabelle</strong> <strong>di</strong> hashCollisione• Ogniqualvolta h(k i )=h(k j ) quando k i ≠ k j , siverifica una collisione• Occorre:• Minimizzare il numero <strong>di</strong> collisioni (ottimizzandola funzione <strong>di</strong> hash)• Gestire le collisioni residue, quando avvengono(permettendo a più elementi <strong>di</strong> risiedere nellastessa locazione)A.A. 2001/2002 APA-hash 13Ridurre le collisioniLe funzioni <strong>di</strong> hash migliori sono quelle che<strong>di</strong>stribuiscono il più uniformemente possibile i|K| elementi negli m in<strong>di</strong>rizzi a <strong>di</strong>sposizione.La funzione h(k) deve sembrare il più“casuale” possibile. Sol<strong>it</strong>amente <strong>di</strong> effettuanomanipolazioni sui b<strong>it</strong> della chiave k,un<strong>it</strong>amente ad una scelta <strong>di</strong> un numero primoper il valore <strong>di</strong> m.A.A. 2001/2002 APA-hash 147


Algor<strong>it</strong>mi e Programmazione Avanzata<strong>Tabelle</strong> <strong>di</strong> hashGestire le collisioni residueSol<strong>it</strong>amente si utilizzano due tecniche:• Chaining• Open AddressingA.A. 2001/2002 APA-hash 15Chaining (I)La soluzione più semplice per gestire lecollisioni è permettere a più elementi <strong>di</strong>risiedere nella stessa locazione della tabella T.Ogni locazione <strong>di</strong> T è quin<strong>di</strong> un insieme <strong>di</strong>elementi, e può essere implementata sottoforma <strong>di</strong> lista concatenata.Tale tecnica viene detta chaining.A.A. 2001/2002 APA-hash 168


Algor<strong>it</strong>mi e Programmazione Avanzata<strong>Tabelle</strong> <strong>di</strong> hashChaining (II)•k 6•k 3 •k 4•k•k 21 •k 53 k 445 k 267k 50U12 k 1 k 68m-1k 3TA.A. 2001/2002 APA-hash 17Pseudo-co<strong>di</strong>ce• T[i] sono puntatori a liste, inizializzati aNIL.• CHAINED-HASH-INSERT(T,x)• inserisci x alla testa della lista T[h(key[x])]• CHAINED-HASH-SEARCH(T,k)• cerca l’elemento con chiave k nella lista T[h(k)]• CHAINED-HASH-DELETE(T,x)• cancella x dalla lista T[h(key[x])]A.A. 2001/2002 APA-hash 189


Algor<strong>it</strong>mi e Programmazione Avanzata<strong>Tabelle</strong> <strong>di</strong> hashEsercizio propostoSi definiscano in C le strutture dati ed iprototipi delle funzioni necessarie permemorizzare in una hash table con chaningdegli elementi contenenti una stringa (campochiave) e due interi (dati aggiuntivi).A.A. 2001/2002 APA-hash 19Esercizio propostoSi completi l’esercizio precedenteimplementando le funzioni <strong>di</strong> inserimento,ricerca e cancellazione.Si assuma <strong>di</strong> <strong>di</strong>sporre <strong>di</strong> un’opportunafunzione h(k), <strong>di</strong> cui occorre fornire ilprototipo.A.A. 2001/2002 APA-hash 2010


Algor<strong>it</strong>mi e Programmazione Avanzata<strong>Tabelle</strong> <strong>di</strong> hashCompless<strong>it</strong>à• Ipotesi: liste non or<strong>di</strong>nate• Inserimento: O(1)• Ricerca: O(lunghezza delle liste)• Cancellazione:• O(1) se ho il puntatore ad x e la lista èdoppiamente linkata• Uguale alla ricerca se ho il valore <strong>di</strong> x, oppure ilvalore della chiave k, oppure la lista èsemplicemente linkataA.A. 2001/2002 APA-hash 21Compless<strong>it</strong>à delle ricerche (I)• Detti:• n il numero <strong>di</strong> elementi memorizzati• m la <strong>di</strong>mensione della tabella <strong>di</strong> hash• Si definisce:• α=n/m: fattore <strong>di</strong> carico della tabella <strong>di</strong> hash T• Può essere α>1• Che cosa succede quando m,n→∞ (a par<strong>it</strong>à<strong>di</strong> α) ?A.A. 2001/2002 APA-hash 2211


Algor<strong>it</strong>mi e Programmazione Avanzata<strong>Tabelle</strong> <strong>di</strong> hashCompless<strong>it</strong>à delle ricerche(II)• Nel caso peggiore la ricerca richiede Θ(n),più il tempo per calcolare h(k): la tabella <strong>di</strong>hash degenera in una lista semplice nonor<strong>di</strong>nata• Il caso migliore <strong>di</strong>pende da quantouniformemente h(k) <strong>di</strong>stribuisce glielementi. Assumiamo per ora che h(k)abbia egual probabil<strong>it</strong>à <strong>di</strong> generare gli mvalori <strong>di</strong> usc<strong>it</strong>a: hashing semplice uniformeA.A. 2001/2002 APA-hash 23<strong>Hash</strong>ing semplice uniformeAssumiamo <strong>di</strong> saper calcolare h(k) in O(1). Lacompless<strong>it</strong>à per la ricerca <strong>di</strong>pende linearmentedalla lunghezza della lista T[h(k)].Occorre valutare separatamente il caso <strong>di</strong>elemento trovato ed elemento non trovato.Si può <strong>di</strong>mostrare che in entrambi i casi lacompless<strong>it</strong>à è Θ(1+α).A.A. 2001/2002 APA-hash 2412


Algor<strong>it</strong>mi e Programmazione Avanzata<strong>Tabelle</strong> <strong>di</strong> hashConclusioneSe:• Il numero m <strong>di</strong> “slot” cresceproporzionalmente ad n (α costante)• h(k) <strong>di</strong>stribuisce uniformemente glielementiAllora:• La funzione <strong>di</strong> ricerca in una tabella <strong>di</strong> hashcon chaining è Θ(1+α)=O(1).A.A. 2001/2002 APA-hash 25Progettare le funzioni <strong>di</strong> hashLa scelta della funzione <strong>di</strong> hashing è crucialeper l’efficienza dell’intera struttura dati.Si assume che le funzioni migliori siano quelleche realizzano un hashing uniforme: se i valoridelle chiavi k sono equiprobabili, allora tutti ivalori della funzione h(k) devono essereanch’essi equiprobabili.∑k:h(k ) = j1P( k)= , j = 0,1, K,m −1mA.A. 2001/2002 APA-hash 2613


Algor<strong>it</strong>mi e Programmazione Avanzata<strong>Tabelle</strong> <strong>di</strong> hashCr<strong>it</strong>eri generali• Poiché le chiavi k sol<strong>it</strong>amente non sonoequiprobabili, anzi spesso sono moltocorrelate (si pensi ai nomi <strong>di</strong> variabili),occorre:• Usare tutti i b<strong>it</strong> della chiave• “Amplificare” le <strong>di</strong>fferenze• Si può sempre pensare che le chiavi sianorappresentate come numeri interi (illim<strong>it</strong>ati)• Es: “abc” può essere interpretata come‘a’*256 2 + ‘b’*256 + ‘c’A.A. 2001/2002 APA-hash 27Chiavi come numeriNel segu<strong>it</strong>o si assume che k siano numeriinteri, o siano ricondotti a numeri interi.Nella pratica, lavorando con stringhe <strong>di</strong> unacerta lunghezza non è pratico convertire innumeri interi, per cui si adotteranno dellevarianti dei meto<strong>di</strong> esposti.A.A. 2001/2002 APA-hash 2814


Algor<strong>it</strong>mi e Programmazione Avanzata<strong>Tabelle</strong> <strong>di</strong> hash<strong>Hash</strong>ing per <strong>di</strong>visione• Interpretando k come un numero intero, sidefinisce:• h(k) = k mod m• Dato un numero previsto <strong>di</strong> elementi n, pergarantire una certa compless<strong>it</strong>à occorrescegliere m≥αn.A.A. 2001/2002 APA-hash 29Scelta <strong>di</strong> m• Occorre ev<strong>it</strong>are che m sia• una potenza <strong>di</strong> 2 (usa solo gli ultimi m b<strong>it</strong> <strong>di</strong> k)• una potenza <strong>di</strong> 10 (se k sono numeri decimali)• 2 p -1 (se si trattano stringhe, in quantotrasposizioni <strong>di</strong> caratteri generano collisioni)• ...• Sol<strong>it</strong>amente si sceglie per m un valore:• corrispondente ad un numero primo• non troppo vicino ad una potenza <strong>di</strong> 2A.A. 2001/2002 APA-hash 3015


Algor<strong>it</strong>mi e Programmazione Avanzata<strong>Tabelle</strong> <strong>di</strong> hashEsempio• n = 2000 elementi previsti• Vogliamo un numero <strong>di</strong> confronti me<strong>di</strong>opari a 3 nelle ricerche• m = 701 è un numero primo vicino a2000/3 ma <strong>di</strong>stante dalle potenze <strong>di</strong> 2• h(k) = k mod 701A.A. 2001/2002 APA-hash 31<strong>Hash</strong>ing per moltiplicazione• Interpretando k come un numero intero, sidefinisce:• Una costante 0


Algor<strong>it</strong>mi e Programmazione Avanzata<strong>Tabelle</strong> <strong>di</strong> hashScelta <strong>di</strong> m e A• Il valore <strong>di</strong> m non è affatto cr<strong>it</strong>ico.Sol<strong>it</strong>amente si sceglie una potenza <strong>di</strong> 2, inmodo che moltiplicazione e parte intera siriducano ad estrarre una sotto-sequenza <strong>di</strong>b<strong>it</strong>• La scelta ottima <strong>di</strong> A <strong>di</strong>pende dallecaratteristiche statistiche delle chiavi• A = (√5 – 1) / 2 = 0.6180339887... è una“buona” sceltaA.A. 2001/2002 APA-hash 33<strong>Hash</strong>ing universaleTutte le funzioni <strong>di</strong> hashing sono suscettibili <strong>di</strong>qualche caso peggiore nella scelta “cattiva”delle chiavi.Si può pensare <strong>di</strong> “randomizzare” la sceltadella funzione h(k), per “proteggerla” contro icasi peggiori.Ad ogni esecuzione del programma, si scegliea caso una funzione <strong>di</strong> hash tra un insieme <strong>di</strong>funzioni predefin<strong>it</strong>e. La probabil<strong>it</strong>à del casopeggiore viene così notevolmente ridotta.A.A. 2001/2002 APA-hash 3417


Algor<strong>it</strong>mi e Programmazione Avanzata<strong>Tabelle</strong> <strong>di</strong> hashConsiderazioni pratiche• Quasi sempre le chiavi sono stringhe(trattarle come numeri interi è complesso)• Gli operatori b<strong>it</strong>-a-b<strong>it</strong> del C sono moltoefficienti• Gli shift > possono spostare parti dellachiave per rompere schemi ripetuti• L’or esclusivo ^ permette <strong>di</strong> combinaresottosequenze <strong>di</strong> b<strong>it</strong> senza il mascheramento <strong>di</strong>and (&) e or (|)• Si può sfruttare il parallelismo delle parole dellaCPU (16, 32 b<strong>it</strong>)A.A. 2001/2002 APA-hash 35<strong>Hash</strong>PJW#define PRIME 211int hashpjw(char *s){ char *p ;unsigned int h=0, g;for ( p=s; *p != '\0'; p++ ) {h = ( h > 24 ) ;h = h ^ g ;}}return h % PRIME ;}A.A. 2001/2002 APA-hash 3618


Algor<strong>it</strong>mi e Programmazione Avanzata<strong>Tabelle</strong> <strong>di</strong> hashEsercizio propostoSi completi il programma implementando lafunzione hashpjw e confrontandonesperimentalmente le prestazioni con altrefunzioni <strong>di</strong> hash più semplici.Si può calcolare la lunghezza minima/massima(non me<strong>di</strong>a!) delle liste, o la varianza dellalunghezza, o il numero <strong>di</strong> liste vuote, ilnumero <strong>di</strong> confronti totale, ...A.A. 2001/2002 APA-hash 37Analisi sperimentaleÈ stata condotta un’analisi sulle prestazioni <strong>di</strong><strong>di</strong>verse funzioni <strong>di</strong> hash su <strong>di</strong>verse tipologie <strong>di</strong>dati <strong>di</strong> ingresso.Per ciascuna, è stato misurato il rapporto tra ilnumero <strong>di</strong> confronti misurato ed il caso attesoper una funzione <strong>di</strong> hash totalmente uniforme.La tabella <strong>di</strong> hash conteneva 211 elementi(numero primo).A.A. 2001/2002 APA-hash 3819


Algor<strong>it</strong>mi e Programmazione Avanzata<strong>Tabelle</strong> <strong>di</strong> hashInput utilizzati1: i 50 identificatori e parole chiave più frequenti in un campione<strong>di</strong> programmi C2: i 100 identificatori e parole chiave più frequenti in uncampione <strong>di</strong> programmi C3: i 500 identificatori e parole chiave più frequenti in uncampione <strong>di</strong> programmi C4: 952 nomi ‘extern’ nel kernel <strong>di</strong> Unix5: 627 identificatori in un programma C generato dalcompilatore C++6: 915 stringhe generate casualmente7: 614 parole tratte da un testo <strong>di</strong> informatica8: 1201 parole inglesi, con “xxx” aggiunto come prefisso esuffisso9: i 300 nomi: “v100”, “v101”, …, “v399”A.A. 2001/2002 APA-hash 39Funzioni <strong>di</strong> hash• hashpjw• ×β, con β=65599, 16, 5, 2, 1• h(k) = Σ k[i] × β i• middle: considera i 4 caratteri centrali• ends: considera i primi 3 e gli ultimi 3caratteri• quad: raggruppa i caratteri 4 a 4 e sommagli interi corrispondentiA.A. 2001/2002 APA-hash 4020


Algor<strong>it</strong>mi e Programmazione Avanzata<strong>Tabelle</strong> <strong>di</strong> hashQuant<strong>it</strong>à misurate• Il numero <strong>di</strong> confronti attesi per una lista <strong>di</strong>lunghezza b j è b j (b j +1)/2.• Il numero totale è ottenuto sommando ilcontributo delle m liste: Σ j=0..m-1 b j (b j +1)/2• Il caso migliore è dato da (n/2m)(n+2m–1)• Viene calcolato il rapporto• Σ j=0..m-1 b j (b j +1)/2 ÷ (n/2m)(n+2m–1)A.A. 2001/2002 APA-hash 41RisultatiA.A. 2001/2002 APA-hash 4221


Algor<strong>it</strong>mi e Programmazione Avanzata<strong>Tabelle</strong> <strong>di</strong> hashOpen AddressingLa tecnica nota come Open Addressing èun’alternativa al Chaining per gestire lecollisioni.Ogni cella <strong>di</strong> T può contenere un soloelemento, e non è necessario gestire le liste <strong>di</strong>collisione.In caso <strong>di</strong> collisione si ricerca un’altra cellanon ancora occupata.Funziona solo con α


Algor<strong>it</strong>mi e Programmazione Avanzata<strong>Tabelle</strong> <strong>di</strong> hash<strong>Hash</strong>-InsertHASH-INSERT(T, k)1 i ← 02 repeat j ← h(k, i)3 if T[j] = NIL4 then T[j] ← k5 return6 else i ← i + 17 until i = m8 error “hash table overflow”A.A. 2001/2002 APA-hash 45<strong>Hash</strong>-SearchHASH-SEARCH(T, k)1 i ← 02 repeat j ← h(k, i)3 if T[j] = k4 then return j5 i ← i + 16 until T[j] = NIL or i = m7 return NILA.A. 2001/2002 APA-hash 4623


Algor<strong>it</strong>mi e Programmazione Avanzata<strong>Tabelle</strong> <strong>di</strong> hashCancellazioneLa cancellazione è un’operazione complessa,in quanto “rompe” le catene <strong>di</strong> collisione.L’open addressing è in pratica utilizzato soloquando non si deve mai cancellare.A.A. 2001/2002 APA-hash 47Funzioni <strong>di</strong> hashLinear probing• h(k, i) = (h’(k)+i) mod mQuadratic probing• h(k, i) = (h’(k)+ c 1 i + c 2 i 2 ) mod mDouble hashing• h(k, i) = (h 1 (k)+ i h 2 (k) ) mod mA.A. 2001/2002 APA-hash 4824


Algor<strong>it</strong>mi e Programmazione Avanzata<strong>Tabelle</strong> <strong>di</strong> hashCompless<strong>it</strong>àNel caso <strong>di</strong> hashing uniforme e <strong>di</strong> probinguniforme, si può <strong>di</strong>mostrare che:• Il numero atteso <strong>di</strong> tentativi <strong>di</strong> “probing” è1/(1–α), ed è uguale alla compless<strong>it</strong>à perl’inserimento• La compless<strong>it</strong>à della ricerca è invece1 1 1ln +α 1−ααA.A. 2001/2002 APA-hash 49Esercizio propostoSi implementi in C una tabella <strong>di</strong> hash conprobing lineare, realizzando le funzioni <strong>di</strong>inserimento e <strong>di</strong> ricerca.A.A. 2001/2002 APA-hash 5025

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!