Prezentace se nahrává, počkejte prosím

Prezentace se nahrává, počkejte prosím

Datové struktury a algoritmy Část 11 Rozptylování - Hashing

Podobné prezentace


Prezentace na téma: "Datové struktury a algoritmy Část 11 Rozptylování - Hashing"— Transkript prezentace:

1 Datové struktury a algoritmy Část 11 Rozptylování - Hashing
Petr Felkel

2 Slovník - Dictionary Řada aplikací potřebuje dynamickou množinu
s operacemi: Search, Insert, Delete = slovník Př. Tabulka symbolů překladače identifikátor typ adresa suma int 0xFFFFDC09 DSA

3 Dictionary Many applications need dynamic set
with operations: Search, Insert, Delete = dictionary Ex. Compiler symbol table identifier type address sum int 0xFFFFDC09 DSA

4 Vyhledávání Porovnáváním klíčů (log n)
klíč prvku = hledaný klíč např. sekvenční vyhledávání,BVS,... Indexováním klíčem (přímý přístup) (1) klíč je přímo indexem rozsah klíčů ~ rozsahu indexů Rozptylováním průměrně (1)! výpočtem adresy z hodnoty klíče DSA

5 Searching Comparing search keys (log n)
search key with keys in items e.g. sequential search,BST,... Key-indexed search (direct access) (1) use key value directly as array index key range ~ table indices Hashing expected (1)! transform keys into a table address DSA

6 Rozptylování - Hashing
= kompromis mezi rychlostí a spotřebou paměti ∞ času - sekvenční vyhledávání ∞ paměti - přímý přístup (indexování klíčem) velikost tabulky reguluje čas vyhledání DSA

7 Hashing = time-space tradeoff ∞ time - sequential search
∞ space - key-indexed search (direct access) balance by adjusting hash-table size DSA

8 Rozptylování - Hashing
Konstantní očekávaný čas pro vyhledání a vkládání (search and insert) !!! Něco za něco: čas provádění ~ délce klíče není vhodné pro operace výběru a řazení (select and sort) DSA

9 Hashing Constant expected time for search and insert but
running time does depend on the length of the key not efficient for select and sort DSA

10 Rozptylování Dvě fáze 1. Výpočet rozptylovací funkce h(k)
klíče 0 10 1 21 2 2 ... M-1 h(10) 10 h(21) 2 h(2) 21 h(31)? 31 h(k) Dvě fáze 1. Výpočet rozptylovací funkce h(k) 2. Vyřešení kolizí h(31) kolize - index 1 již obsazen DSA

11 Hashing Two steps 1. Computation of the hash function h(k)
klíče 0 10 1 21 2 2 ... M-1 h(10) 10 h(21) 2 h(2) 21 h(31)? 31 h(k) Two steps 1. Computation of the hash function h(k) 2. Handling of collisions h(31) collision - index 1 already used DSA

12 1. Výpočet rozptylovací funkce h(k) Computation of the hash function h(k)
DSA

13 Rozptylovací funkce h(k)
Zobrazuje množinu klíčů K do intervalu adres A = <amin, amax>, obvykle <0,M-1> |K| >> |A| Synonyma: k1  k2, h(k1) = h(k2) = kolize DSA

14 Hash function h(k) Transforms the search key into a table address
set of keys K table addresses A  <amin, amax>, usually A  <0,M-1> |K| >> |A| Synonyms: k1  k2, h(k1) = h(k2) = collision DSA

15 Rozptylovací funkce h(k)
Je silně závislá na vlastnostech klíčů a jejich reprezentaci v paměti Ideálně: výpočetně co nejjednodušší (rychlá) aproximuje náhodnou funkci využije rovnoměrně adresní prostor generuje minimum kolizí proto: využívá všechny složky klíče DSA

16 Hash function h(k) Heavily depends on the key properties and on the representation of the keys Ideally: computationally as simple as possible (fast) approximates a random function uses the address space regularly generates minimum of collisions therefore: uses all key parts DSA

17 Rozptylovací funkce h(k)-příklady Hash functions h(k) - examples
Pro reálná čísla for real numbers multiplikativní: h(k,M) = round( k * M ) (neoddělí shluky blízkých čísel) (does not separate clusters of similar numbers) M = velikost tabulky DSA

18 Rozptylovací funkce h(k)-příklady
Pro celá čísla (w-bitová) - for w-bit integers multiplikativní: (kde M je prvočíslo-prime) h(k,M) = round( k /2w * M ) modulární: h(k,M) = k % M kombinovaná (combined): h(k,M) = round( c * k ) % M, c <0,1> h(k,M) = (int)( * (float) k ) % M h(k,M) = (16161 * (unsigned) k) % M DSA

19 Rozptylovací funkce h(k)-příklady Hash functions h(k) - examples
Rychlá, silně závislá na reprezentaci klíčů (Fast, heavily dependent on the representation of keys in memory): h(k) = k & (M-1) pro M = 2x (není prvočíslo) , a & = bitový součin (M not prime, & = bit-wise AND) DSA

20 Rozptylovací funkce h(k)-příklady
Pro řetězce (for strings): int hash( char *k, int M ) { int h = 0, a = 127; for( ; *k != 0; k++ ) h = ( a * h + *k ) % M; return h; } // Hornerovo schéma: k2 * a2 + k1*a1 + k0 * a0 = ((k2 * a) + k1)*a + k0 DSA

21 Rozptylovací funkce h(k)-příklady
Pro řetězce: (pseudo-) randomizovaná int hash( char *k, int M ) { int h = 0, a = 31415; b = 27183; for( ; *k != 0; k++, a = a*b % (M-1) ) h = ( a * h + *k ) % M; return h; } // Univerzální rozptylovací fce kolize s pravděpodobností 1/M odlišná náhodná konstanta pro různé pozice v řetězci DSA

22 Hash functions h(k) - examples
For strings: (pseudo-) randomized int hash( char *k, int M ) { int h = 0, a = 31415; b = 27183; for( ; *k != 0; k++, a = a*b % (M-1) ) h = ( a * h + *k ) % M; return h; } // Universal hashing function chance of collisions between distinct keys exactly 1/M different random constant for different string positions DSA

23 Rozptylovací funkce h(k)-chyba
funkce vrací stejnou hodnotu chyba v konverzi funguje, ale vrací blízké adresy proto generuje hodně kolizí => aplikace je extrémně pomalá DSA

24 Hash functions h(k) - performance bug
always to return the same value conversion did not take place properly generates many collisions program is likely to run correctly, but to be extremely slow DSA

25 2. Vyřešení kolizí Handling of collisions
DSA

26 a) Zřetězené rozptylování 1/5 Separate chainimg
h(k) = k mod 3 posloupnost (sequence) : 1, 5, 21, 10, 7 heads link 1 2 21 \ 7 10 1 \ 5 \ seznamy synonym DSA

27 a) Zřetězené rozptylování 2/5
private: link* heads; int N,M; [Sedgewick] public: ST( int maxN ) // initialization { N=0; M = maxN / 5; // No.nodes,table size heads = new link[M];// table with pointers for( int i = 0; i < M; i++ ) heads[i] = null; }... DSA

28 a) Zřetězené rozptylování 3/5
Item search( Key k ) { return searchList( heads[ hash(k, M)], k );} void insert( Item item ) { int i = hash( item.key(), M ); heads[i] = new node( item, heads[i] ); N++; } DSA

29 a) Zřetězené rozptylování 4/5
Řetěz synonym má ideálně délku  =n/m,  >1 (n = počet prvků, m = velikost tabulky, m<n) Insert I(n) = thash + tlink = O(1) Search Q(n) = thash + tsearch průměrně = thash + tc* n/(2m) = O(n) O(1 + ) Delete D(n) = thash + tsearch + tlink = O(n) O(1 + ) pro malá  (velká m) se hodně blíží O(1) !!! pro velká  (malá m) m-násobné zrychlení x seq. s. velmi nepravděpodobný extrém DSA

30 a) Zřetězené rozptylování 5/5
Praxe: volit m = n/5 až n/10 =>  = 10 prvků / řetěz vyplatí se hledání sekvenčně neplýtvá nepoužitými ukazateli Shrnutí: + nemusíme znát n předem - potřebuje dynamické přidělování paměti - potřebuje paměť na ukazatele a na tabulku[m] DSA

31 b) Otevřené rozptylování (open-addressing hashing)
Znám předem počet prvků (odhad) nechci ukazatele (v prvcích ani tabulku) => posloupnost do pole Podle tvaru hashovací funkce h(k) při kolizi 1. linear probing 2. double hashing DSA

32 b) Otevřené rozptylování
h(k) = k mod 5 posloupnost: 1, 5, 21, 10, 7 2 3 4 kolize - 1 blokuje 1. linear probing 2. double hashing Pozn.: 1 a 21 jsou synonyma často ale blokuje nesynonymum DSA

33 Probe = určení, zda pozice v tabulce obsahuje klíč shodný s hledaným klíčem search hit = klíč nalezen search miss = pozice prázdná, klíč nenalezen jinak = na pozici je jiný klíč, hledej dál DSA

34 Probe = determining, whether or not a given table position holds an item with a key equal to the search key search hit = key matches search miss = the table position is empty otherwise = the table position contains an item with a different key, so probe the the table position with a next higher index DSA

35 b) Otevřené rozptylování (open-addressing hashing)
b1) Linear probing

36 b1) Linear probing h(k) = [(k mod 5) + i ] mod 5 = (k + i) mod 5
posloupnost: 1, 5, 21, 10, 7 3 4 kolize - 1 blokuje vlož o pozici dál (i++ => i = 1) insert one position ahead DSA

37 b1) Linear probing h(k) = (k + i) mod 5 posloupnost: 1, 5, 21, 10, 7
4 1. kolize - 5 blokuje - vlož dál 2. kolize - 1 blokuje - vlož dál 3. kolize - 21 blokuje - vlož dál vloženo o 3 pozice dál (i = 3) collision - position blocked - i++ finally inserted 3 indexes ahead DSA

38 b1) Linear probing h(k) = (k + i) mod 5 posloupnost: 1, 5, 21, 10, 7
1. kolize - vlož dál (i++) 2. kolize - vlož dál (i++) vlož o 2 pozice dál (i = 2) DSA

39 b1) Linear probing h(k) = (k + i) mod 5 posloupnost: 1, 5, 21, 10, 7
i = 0 i = 1 i = 3 i = 2 DSA

40 b1) Linear probing private: Item *st; int N,M; [Sedgewick]
Item nullItem; public: ST( int maxN ) // initialization { N=0; M = 2*maxN; // load_factor < 1/2 st = new Item[M]; for( int i = 0; i < M; i++ ) st[i] = nullItem; }... DSA

41 b1) Linear probing void insert( Item item ) {
int i = hash( item.key(), M ); while( !st[i].null() ) i = (i+1) % M; // Linear probing st[i] = item; N++; } DSA

42 b1) Linear probing Item search( Key k ) { int i = hash( k, M );
while( !st[i].null() ) { // zarážka if( k == st[i].key() ) return st[i]; else i = (i+1) % M; // Linear probing } return nullItem; DSA

43 b) Otevřené rozptylování (open-addressing hashing)
b2) Double hashing

44 b2) Double hashing h(k) = k mod 5 posloupnost: 1, 5, 21, 10, 7 0 5 1 1
2 3 4 kolize - 1 blokuje (collision-blocks) 1. linear probing 2. double hashing DSA

45 b2) Double hashing h(k) = [(k mod 5) + i.h2(k) ] mod 5, h(k) = (k + i.3) mod 5 posloupnost: 1, 5, 21, 10, 7 stačí prvočíslo  m prime number  m 2 3 kolize - 1 blokuje vlož o 3 pozice dál (i++ => i = 1) DSA

46 b2) Double hashing h(k) = (k + i.3) mod 5 posloupnost: 1, 5, 21, 10, 7
2 1. kolize - 5 blokuje - vlož dál vlož o 3 pozice dál (i = 1) DSA

47 b2) Double hashing h(k) = (k + i.3) mod 5 posloupnost: 1, 5, 21, 10, 7
i = 0 DSA

48 b2) Double hashing h(k) = (k + i.3) mod 5 posloupnost: 1, 5, 21, 10, 7
DSA

49 Double hashing x Linear probing
h(k) = (k + i.3) mod h(k) = (k + i) mod 5 i = 0 i = 1 i = 0 i = 1 i = 3 ! i = 2 vnořené sekvence (mixed probe sequences) dlouhé shluky (long clusters) DSA

50 b2) Double hashing void insert( Item item ) { Key k = item.key();
int i = hash( v, M ), j = hashTwo( v, M ); while( !st[i].null() ) i = (i+j) % M; // Double Hashing st[i] = item; N++; } DSA

51 b2) Double hashing Item search( Key k ) { int i = hash( k, M ),
j = hashTwo( v, M ); while( !st[i].null() ) { if( k == st[i].key() ) return st[i]; else i = (i+j) % M; // Double Hashing } return nullItem; DSA

52 Linear-probing Item Removal
// do not leave the hole - it can break a cluster void remove( Item item ) { int i = hash( v, M ), j; while( !st[i].null() ) // find item to remove if( item.key() == st[i].key() ) break; else i = (i+1) % M; if( st[i].null() ) return; // not found st[i] = nullItem; N--; // delete, reinsert for( j = i+1; !st[j].null(); (j+1) % M, N--) { Item v = st[j]; st[j] = nullItem; insert(v); } } DSA

53 Double-hashing Item Removal
// Double Hashing - overlapping search sequences // - fill up the hole by sentinel // - skipped by search, replaced by insert void remove( Item item ) { int i = hash( v, M ), j = hashTwo( v, M ); while( !st[i].null() ) // find item to remove if( item.key() == st[i].key() ) break; else i = (i+j) % M; if( st[i].null() ) return; // not found st[i] = sentinelItem; N--; // delete } DSA

54 b) Otevřené rozptylování (open-addressing hashing)
 = zaplnění tabulky (load factor of the table)  = n/m,  0,1 n = počet prvků (number of items in the table) m = velikost tabulky, m>n (table size) DSA

55 b) Otevřené rozptylování (open-addressing hashing)
Average number of probes [Sedgewick] Linear probing: Search hits ( / (1 - ) ) Search misses 0.5 ( / (1 - )2 ) Double hashing: Search hits (1 / ) ln ( 1 / (1 - ) ) Search misses 1 / (1 - ) DSA

56 b) Očekávaný počet testů
Linear probing: Plnění  1/2 2/3 3/4 9/10 Search hit Search miss Double hashing: Search hit Search miss Tabulka může být více zaplněná než začne klesat výkonnost. K dosažení stejného výkonu stačí menší tabulka. DSA

57 b) Expected number of probes
Linear probing: Load factor  1/2 2/3 3/4 9/10 Search hit Search miss Double hashing: Search hit Search miss - Table can be more full before performance degrades. - We need smaller table for the same performance. DSA


Stáhnout ppt "Datové struktury a algoritmy Část 11 Rozptylování - Hashing"

Podobné prezentace


Reklamy Google