Vyhledávání, zejména rozptylování

Podobné dokumenty
Topics. Vyhledávání, zejména rozptylování. Slovník - Dictionary. Vyhledávání. Rozptylování - Hashing. Rozptylování - Hashing

Datové struktury 2: Rozptylovací tabulky

Adresní vyhledávání (přímý přístup, zřetězené a otevřené rozptylování, rozptylovací funkce)

Návrh designu: Radek Mařík

Abstraktní datové typy II.

HASHING GENERAL Hashovací (=rozptylovací) funkce

HASHING GENERAL Hashovací (=rozptylovací) funkce

Základy algoritmizace. Hašování

Rozptylovací tabulky

Algoritmizace Hashing II. Jiří Vyskočil, Marko Genyg-Berezovskyj 2010

Úvod. Úvod do programování. Úvod. Hashovací tabulky

POZOR klíč NENÍ index (adresa), ale podle klíče se hodnoty ukládají na indexy (adresy).

Třetí skupina zadání projektů do předmětu Algoritmy II, letní semestr 2017/2018

Tabulka. Často jde nejenom o dynamickou množinu, ale i statickou množinu. Matematické tabulky statická množina

2 Datové struktury. Pole Seznam Zásobník Fronty FIFO Haldy a prioritní fronty Stromy Hash tabulky Slovníky

Šablony, kontejnery a iterátory

Dynamické datové struktury III.

ALS1 Přednáška 1. Pravěpodobnost, náhodná proměnná, očekávaná hodnota náhodné proměnné, harmonická čísla

vyhledávací stromové struktury

B3B33ALP - Algoritmy a programování - Zkouška z předmětu B3B33ALP. Marek Boháč bohacm11

Algoritmizace a programování

B3B33ALP - Algoritmy a programování - Zkouška z předmětu B3B33ALP. Marek Boháč bohacm11

Spojová implementace lineárních datových struktur

5 Rekurze a zásobník. Rekurzivní volání metody

Abstraktní datové typy

Algoritmizace Dynamické programování. Jiří Vyskočil, Marko Genyg-Berezovskyj 2010

Binární vyhledávací stromy pokročilé partie

Test prvočíselnosti. Úkol: otestovat dané číslo N, zda je prvočíslem

ALG 14. Vícedimenzionální data. Řazení vícedimenzionálních dat. Experimentální porovnání řadících algoritmů na vícedimenzionálních datech

vyhledávací stromové struktury

součet cvičení celkem. známka. Úloha č.: max. bodů: skut. bodů:

Poslední nenulová číslice faktoriálu

Úvod do programovacích jazyků (Java)

Vyhledávací algoritmy

5. Vyhledávání a řazení 1

Vyhledávání. doc. Mgr. Jiří Dvorský, Ph.D. Katedra informatiky Fakulta elektrotechniky a informatiky VŠB TU Ostrava. Prezentace ke dni 21.

Jak v Javě primitivní datové typy a jejich reprezentace. BD6B36PJV 002 Fakulta elektrotechnická České vysoké učení technické

2) Napište algoritmus pro vložení položky na konec dvousměrného seznamu. 3) Napište algoritmus pro vyhledání položky v binárním stromu.

ALG 09. Radix sort (přihrádkové řazení) Counting sort. Přehled asymptotických rychlostí jednotlivých řazení. Ilustrační experiment řazení

Náplň. v Jednoduché příklady na práci s poli v C - Vlastnosti třídění - Způsoby (algoritmy) třídění

Michal Krátký. Úvod do programovacích jazyků (Java), 2006/2007

Kolekce, cyklus foreach

Algoritmizace prostorových úloh

Úvod do programovacích jazyků (Java)

Základní pojmy. Úvod do programování. Základní pojmy. Zápis algoritmu. Výraz. Základní pojmy

Algoritmizace prostorových úloh

Hašování (Vyhledávání metodou transformace klíče)

Tabulka symbolů. Vazba (binding) Vazba - příklad. Deklarace a definice. Miroslav Beneš Dušan Kolář

ADT/ADS = abstraktní datové typy / struktury

Robert Haken [MVP ASP.NET/IIS, MCT] software architect, HAVIT, Základní algoritmy v praxi

Programování v C++, 2. cvičení

Struktura programu v době běhu

PB161 Programování v jazyce C++ Přednáška 3

Základy algoritmizace a programování

Šablony, kontejnery a iterátory

Dynamické programování. Optimální binární vyhledávací strom

Obsah. Předmluva 13 Zpětná vazba od čtenářů 14 Zdrojové kódy ke knize 15 Errata 15

Rekurentní rovnice, strukturální indukce

Operátory, výrazy. Tomáš Pitner, upravil Marek Šabo

int => unsigned int => long => unsigned long => float => double => long double - tj. bude-li:

Vyhledávání. doc. Mgr. Jiří Dvorský, Ph.D. Katedra informatiky Fakulta elektrotechniky a informatiky VŠB TU Ostrava. Prezentace ke dni 12.

Michal Krátký. Úvod do programovacích jazyků (Java), 2006/2007

Funkce pokročilé možnosti. Úvod do programování 2 Tomáš Kühr

- znakové konstanty v apostrofech, např. a, +, (znak mezera) - proměnná zabírá 1 byte, obsahuje kód příslušného znaku

Operační systémy. Jednoduché stránkování. Virtuální paměť. Příklad: jednoduché stránkování. Virtuální paměť se stránkování. Memory Management Unit

ÚVODNÍ ZNALOSTI. datové struktury. správnost programů. analýza algoritmů

Michal Krátký. Úvod do programování. Cíl kurzu. Podmínky získání zápočtu III/III

Pole a kolekce. v C#, Javě a C++

Karel Kohout 18. května 2010

Časová složitost algoritmů

Algoritmy I, složitost

Přednáška. Správa paměti II. Katedra počítačových systémů FIT, České vysoké učení technické v Praze Jan Trdlička, 2012

Datové struktury. alg12 1

IB111 Úvod do programování skrze Python

IAJCE Přednáška č. 9. int[] pole = new int[pocet] int max = pole[0]; int id; for(int i =1; i< pole.length; i++) { // nikoli 0 if (Pole[i] > max) {

Paměť počítače. alg2 1

Dynamické programování

Zpracování deklarací a přidělování paměti

AVL stromy. pro každý uzel u stromu platí, že rozdíl mezi výškou jeho levého a pravého podstromu je nejvýše 1 stromy jsou samovyvažující

Datové struktury. Obsah přednášky: Definice pojmů. Abstraktní datové typy a jejich implementace. Algoritmizace (Y36ALG), Šumperk - 12.

Ukazatel (Pointer) jako datový typ - proměnné jsou umístěny v paměti na určitém místě (adrese) a zabírají určitý prostor (počet bytů), který je daný

Algoritmy a datové struktury

ABSTRAKTNÍ DATOVÉ TYPY (ADT)

Rekurentní rovnice, strukturální indukce

Základní datové struktury

Dynamicky vázané metody. Pozdní vazba, virtuální metody

typová konverze typová inference

Pokročilá algoritmizace amortizovaná složitost, Fibonacciho halda, počítačová aritmetika

Hashovací funkce. Andrew Kozlík KA MFF UK

Algoritmizace a programování

Programování v C++ 1, 5. cvičení

Databázové systémy. - SQL * definice dat * aktualizace * pohledy. Tomáš Skopal

Aplikace. vliv na to, jakou mají strukturu i na to, jak pracné je je vyvinout. Bylo vypozorováno, že aplikace je možné rozdělit do skupin

Databáze I. 5. přednáška. Helena Palovská

Fronta (Queue) Úvod do programování. Fronta implementace. Fronta implementace pomocí pole 1/4. Fronta implementace pomocí pole 3/4

Základní definice Aplikace hašování Kontrukce Známé hašovací funkce. Hašovací funkce. Jonáš Chudý. Úvod do kryptologie

Programování v Javě I. Leden 2008

Úvod do programování 7. hodina

Zápis programu v jazyce C#

Konstruktory a destruktory

Transkript:

Datové struktury a algoritmy Část 11 Vyhledávání, zejména rozptylování Petr Felkel 16.5.2016

Topics Vyhledávání Rozptylování (hashing) Rozptylovací funkce Řešení kolizí Zřetězené rozptylování Otevřené rozptylování Linear Probing Double hashing DSA 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

Vyhledávání Porovnáváním klíčů (log n) Nalezeno, když 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 (adresou) rozsah klíčů ~ rozsahu indexů Rozptylováním průměrně (1) výpočtem adresy z hodnoty klíče asociativní adresní vyhledávání DSA 4

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) málo času i paměti - hashing - velikost tabulky reguluje čas vyhledání DSA 5

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 podmnožiny a řazení (select a sort) DSA 6

Rozptylování použité klíče 10 2 21 31 K U možné klíče = Universum klíčů Rozptylování vhodné pro K << U K množina použitých klíčů U universum klíčů DSA 7

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

1. Výpočet rozptylovací funkce h(k) DSA 9

Rozptylovací funkce h(k) Zobrazuje množinu klíčů K U do intervalu adres A = <a min, a max >, obvykle <0,M-1> U >> K ~= A (h(k) Vypočítá adresu z hodnoty klíče) Synonyma: k 1 k 2, h(k 1 ) = h(k 2 ) = kolize DSA 10

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 11

Rozptylovací funkce h(k) -příklady Příklady fce h(k) pro různé typy klíčů reálná čísla celá čísla bitová řetězce Chybná rozptylovací funkce DSA 12

Rozptylovací funkce h(k)-příklady Pro reálná čísla z intervalu <0, 1> multiplikativní: h(k,m) = round( k * M ) neoddělí shluky blízkých čísel (s rozdílem < 1/M) M = velikost tabulky (table size) DSA 13

Rozptylovací funkce h(k)-příklady Pro celá čísla multiplikativní: (kde M je prvočíslo, klíče mají w bitů) h(k,m) = round( k /2 w * M ) modulární: h(k,m) = k % M kombinovaná: h(k,m) = round( c * k ) % M, c <0,1> h(k,m) = (int)(0.616161 * k ) % M h(k,m) = (16161 * k) % M // pozor na přetečení DSA 14

Rozptylovací funkce h(k)-příklady Hash functions h(k) - examples Rychlá, silně závislá na reprezentaci klíčů & je bitový součin h(k) = k & (M-1) kde M = 2 x (není prvočíslo), je totéž jako h(k) = k % M, tj.použije x nejnižších bitů klíče DSA 15

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 : P(a) = k 4 * a 4 + k 3 * a 3 + k 2 * a 2 + k 1 *a 1 + k 0 * a 0 = (((k 4 *a + k 3 )*a + k 2 )*a + k 1 )*a + k 0 Výpočet hodnoty polynomu P v bodě a, koeficienty P jsou jednotlivé znaky (jejich číselná hodnota) v řetězci *k. DSA 16

Rozptylovací funkce h(k)-příklady Pro řetězce (for strings) Java: public int hashcode( String s, int M ) { int h = 0; for( int i = 0; i < s.length(); i++ ) h = 31 * h + s.charat(i); return h; } Hodnota konstant 127, 31 přispívá rovnoměrnému psoudonáhodnému rozptýlení. DSA 17

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; } DSA 18

Rozptylovací funkce h(k)-chyba Častá chyba: funkce vrací stále nebo většinou stejnou hodnotu chyba v konverzi typů funguje, ale vrací blízké adresy proto generuje hodně kolizí => aplikace je extrémně pomalá, řešení kolizí zdržuje. DSA 19

Rozptylovací funkce h(k) Shrnutí -počítá adresu z hodnoty klíče DSA 20

Rozptylovací funkce h(k) Každá hashovací funkce má slabá místa, kdy pro různé klíče dává stejnou adresu Univerzální hashování Místo jedné hashovací funkce h(k) máme konečnou množinu H funkcí mapujících U do intervalu {0, 1,, m-1} Při spuštění programu jednu náhodně zvolíme Tato množina je univerzální, pokud pro různé klíče x,y U vrací stejnou adresu h(x) = h(y) přesně v H /m případech Pravděpodobnost kolize při náhodném výběru funkce h(k) je tedy přesně 1/m DSA 21

2. Vyřešení kolizí DSA 22

a) Zřetězené rozptylování 1/5 Chaining h(k) = k mod 3 posloupnost : 1, 5, 21, 10, 7 heads link 0 21 \ Vkládá se na začátek 1 7 10 1 \ 2 5 \ seznamy synonym DSA 23

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

a) Zřetězené rozptylování 3/5 Item search( Key k ) { return searchlist( heads[hash(k, M)], k ); } void insert( Item item ) // Vkládá se na začátek { int i = hash( item.key(), M ); heads[i] = new node( item, heads[i] ); N++; } DSA 25

a) Zřetězené rozptylování 4/5 n = počet prvků, m = velikost tabulky, m<n. Řetěz synonym má ideálně délku =n/m, >1 (plnění tabulky) Insert I(n) = t hash + t link = O(1) velmi nepravděpodobný extrém Search Q(n) = t hash + t search průměrně = t hash + t c * n/(2m) = O(n) O(1 + ) Delete D(n) = t hash + t search + t link = O(n) O(1 + ) pro malá (velká m) se hodně blíží O(1)!!! pro velká (malá m) m-násobné zrychlení vůči sekvenčnímu hledání. DSA 26

a) Zřetězené rozptylování 5/5 Praxe: volit m = n/5 až n/10 => plnění = 10 prvků / řetěz vyplatí se hledání sekvenčně (je krátké) 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 27

b) Otevřené rozptylování (open-address hashing) Známe předem počet prvků (odhad) nechceme ukazatele (v prvcích ani tabulku) => posloupnost do pole Podle tvaru hashovací funkce h(k) při kolizi: 1. lineární prohledávání (linear probing) 2. dvojí rozptylování (double hashing) 0 5 1 1 2 21 3 10 4 DSA 28

b) Otevřené rozptylování h(k) = k mod 5 (h(k) = k mod m, m je rozměr pole) posloupnost: 1, 5, 21, 10, 7 0 5 1 1 2 3 4 Problém: kolize - 1 blokuje místo pro 21 1. linear probing 2. double hashing Pozn.: 1 a 21 jsou synonyma často ale blokuje nesynonymum. Kolize je blokování libovolným klíčem DSA 29

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

b) Otevřené rozptylování (open-addressing hashing) Metoda řešení kolizí (solution of collisions) b1) Linear probing Lineární prohledávání b2) Double hashing Dvojí rozptylování DSA 31

b1) Linear probing h(k) = [(k mod 5) + i ] mod 5 = (k + i) mod 5; i = 0; posloupnost: 1, 5, 21, 10, 7 0 5 1 1 2 21 3 kolize - 1 blokuje => 1. linear probing vlož o 1 pozici dál (i++ => i = 1) 4 DSA 32

b1) Linear probing h(k) = (k + i) mod 5 posloupnost: 1, 5, 21, 10, 7 0 5 1 1 2 21 3 10 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) 4 DSA 33

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

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

b1) Linear probing h(k) = k mod 5 posloupnost: 1, 5, 21, 10, 7 0 5 1 1 kolize - 1 blokuje (collision-blocks) 2 3 4 DSA 36

b1) Linear probing h(k) = [(k mod 5) + i.const ] mod 5, h(k) = (k + i.3) mod 5 posloupnost: 1, 5, 21, 10, 7 0 5 1 1 2 3 kolize - 1 blokuje (collision blocks) stačí prvočíslo m nebo číslo nesoudělné s m vlož o 3 pozice dál (i++ => i = 1) 4 21 (i je číslo pokusu) DSA 37

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

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

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

b1) Linear probing h(k) = (k + i) mod 5 h(k) = (k + i.3) mod 5 0 5 i = 0 0 5 i = 0 1 1 i = 0 1 1 i = 0 2 21 i = 1 2 7 i = 0 3 10 i = 3! 3 10 i = 1 4 7 i = 2 4 21 i = 1 hrozí dlouhé shluky (long clusters) vhodná volba posunu i 3 je věcí náhody DSA 41

b1) Linear probing private: Item *ht; int N,M; [Sedgewick] Item nullitem; public: init( int maxn ) // initialization { N=0; // Number of stored items M = 2*maxN; // load_factor < 1/2 ht = new Item[M]; for( int i = 0; i < M; i++ ) ht[i] = nullitem; }... DSA 42

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

Item search( Key k ) { int i = hash( k, M ); b1) Linear probing } while(!ht[i].null() ) { //!cluster end // zarážka (sentinel) if( k == ht[i].key() ) return ht[i]; else i = (i+const) % M; // Linear probing } return nullitem; DSA 44

b) Otevřené rozptylování (open-addressing hashing) Metoda řešení kolizí (solution of collisions) b1) Linear probing Lineární prohledávání b2) Double hashing Dvojí rozptylování DSA 45

b2) Double hashing Hash function h(k) = [h 1 (k) + i.h 2 (k) ] mod m h 1 (k) = k mod m // initial position h 2 (k) = 1 + (k mod m ) // offset Both depend on k => Each key has different probe sequence m = prime number or m = power of 2 m = slightly less m = odd If d = greatest common divisor => search m/d slots only Ex: k = 123456, m = 701, m = 700 h 1 (k) = 80, h 2 (k) = 257 Starts at 80, and every 257 % 701 DSA 46

b2) Double hashing void insert( Item item ) { Key k = item.key(); int i = hash( k, M ), j = hashtwo( k, M );// different for k 1!= k 2 while(!ht[i].null() ) i = (i+j) % M; //Double Hashing } ht[i] = item; N++; DSA 47

b2) Double hashing Item search( Key k ) { int i = hash( k, M ), j = hashtwo( k, M );// different for k 1!= k 2 } while(!ht[i].null() ) { if( k == ht[i].key() ) return ht[i]; else i = (i+j) % M; // Double Hashing } return nullitem; DSA 48

Double hashing - example b2) Double hashing h(k) = [h 1 (k) + i.h 2 (k) ] mod m Input h 1 (k)= k %11 h 2 (k)= 1+k %10 i h(k) 1 1 2 0 1 25 3 6 0 3 23 1 4 0,1 1,5 45 1 6 0,1 1,7 102 3 3 0,1 3,6 20 9 1 0 9 0 1 2 3 4 5 6 7 8 9 10 1 25 23102 45 20 h 1 (k) = k % 11 h 2 (k) = 1 + (k % 10) DSA 49

b) Otevřené rozptylování (open-addressing hashing) = plně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 50

b) Otevřené rozptylování (open-addressing hashing) Expected number of probes Linear probing: Search hits 0.5 ( 1 + 1 / (1 - ) ) found Search misses 0.5 ( 1 + 1 / (1 - ) 2 ) not found Double hashing: Search hits (1 / ) ln ( 1 / (1 - ) ) Search misses 1 / (1 - ) = n/m, 0,1 DSA 51

b) Očekávaný počet testů Linear probing: Plnění 1/2 2/3 3/4 9/10 Search hit 1.5 2.0 3.0 5.5 Search miss 2.5 5.0 8.5 55.5 Double hashing: Plnění 1/2 2/3 3/4 9/10 Search hit 1.4 1.6 1.8 2.6 Search miss 2.0 3.0 4.0 10.0 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 52

References [Cormen] Cormen, Leiserson, Rivest: Introduction to Algorithms, Chapter 12, McGraw Hill, 1990 or better: [CLRS] Cormen, Leiserson, Rivest, Stein: Introduction to Algorithms, third edition, Chapter 11, MIT press, 2009 DSA 53