Datové struktury 2: Rozptylovací tabulky prof. Ing. Pavel Tvrdík CSc. Katedra počítačových systémů Fakulta informačních technologií České vysoké učení technické v Praze c Pavel Tvrdík, 2010 Efektivní algoritmy (BI-EFA) ZS 2010/11, Přednáška 2 Evropský sociální fond. Praha & EU: Investujeme do vaší budoucnosti prof. Pavel Tvrdík (FIT ČVUT) Rozptylovací tabulky BI-EFA, 2010, Předn. 2 1 / 19
ADT tabulka (opakování) Signatura ADT Tabulka Signatura ADT Tabulka Bool delete iselem Key search init Table insert Value prof. Pavel Tvrdík (FIT ČVUT) Rozptylovací tabulky BI-EFA, 2010, Předn. 2 2 / 19
ADT tabulka (opakování) Složitosti operací nad tabulkou Operační složitosti operací nad tabulkou operace operační složitost při implementaci pomocí pam. pole uspoř. pam. uspoř. spoj. přímá tab. rozpt. tab. spoj. sezn. pole sez. init O(1) O(1) O(1) O(U) O(M) insert O(n) O(n) O(n) O(1) Θ(1) delete O(n) O(n) O(n) O(1) Θ(1) iselem O(n) O(log n) O(n) O(1) Θ(1) search O(n) O(log n) O(n) O(1) Θ(1) kde: U = mohutnost univerza U všech možných klíčů, M = velikost (počet řádků, přihrádek) rozptylovací tabulky, n = počet platných prvků v tabulce, Znak * označuje průměrnou složitost, složitost v nejhorším případě je O(n). prof. Pavel Tvrdík (FIT ČVUT) Rozptylovací tabulky BI-EFA, 2010, Předn. 2 3 / 19
ADT tabulka (opakování) Možnosti implementace operací nad tabulkou Možnosti implementace operací nad tabulkou Asociativní vyhledávání = porovnávání klíčů (opakování z BI-PA2). Hledaný klíč se porovnává s uloženými klíči. Sekvenční vyhledávání: Implementační struktury: paměťové pole, jednosměrný spojový seznam, uspořádaný jednosměrný spojový seznam, binární vyhledávací strom. Paměťová složitost tabulky je O(n). Operační složitost vyhledávání je O(n). Vyhledávání pomocí půlení intervalů: Implementační struktura: uspořádané paměťové pole. Paměťová složitost tabulky je O(n). Operační složitost vyhledávání je O(log n). prof. Pavel Tvrdík (FIT ČVUT) Rozptylovací tabulky BI-EFA, 2010, Předn. 2 4 / 19
ADT tabulka (opakování) Možnosti implementace operací nad tabulkou Možnosti implementace operací (pokr.) Adresní vyhledávání: Indexace klíčem (=přímý přístup), (opakování z BI-PA2). Klíč je použit přímo jako adresa. Implementační struktura: přímá tabulka. Paměťová složitost je O(U) a nezávisí!!! na počtu platných prvků tabulky. Operační složitost operace vyhledávání je Θ(1)!! Rozptylování (hashing): (tato přednáška). Adresa se z hodnoty klíče vypočítá rozptylovací funkcí. Implementační struktura: rozptylovací tabulka. Paměťová složitost je O(M) a to si uživatel předem určuje. Operační složitost operace vyhledávání je v průměrném případě Θ(1). prof. Pavel Tvrdík (FIT ČVUT) Rozptylovací tabulky BI-EFA, 2010, Předn. 2 5 / 19
Rozptylovací tabulky Rozptylovací tabulky Definice 1 U = U, kde U je universum všech možných klíčů. K = K, kde K je množina použitých (očekávaných) klíčů. T = rozptylovací tabulka o velikosti (počtu řádků) M, obvyklý rozsah indexů je M = 0, M 1. Rozptylovací tabulky se používají typicky, když platí U >> K M. U K k2 T 0 h(k 2) k 3 k 4 k 5 k 1 h(k 3) = h(k 5) h(k 1) h(k 4) M-1 prof. Pavel Tvrdík (FIT ČVUT) Rozptylovací tabulky BI-EFA, 2010, Předn. 2 6 / 19
Rozptylovací tabulky Rozptylování Rozptylování Rozptylování má dvě fáze. 1 Výpočet rozptylovací funkce, která z hodnoty klíče k vypočítá adresu řádku h(k) v T. Definice 2 Rozptylovací funkce h : U M zobrazuje množinu použitých klíčů K U do množiny adres M rozptylovací tabulky. Typicky M = {0,..., M 1}. 2 Vyřešení případných kolizí. Protože U >> M, rozptylovací funkce h nemůže být prostá. Definice 3 Synonyma = klíče se stejnou hodnotou rozptylovací funkce. Kolize = požadavek zápisu prvku na obsazenou pozici v tabulce. Příklad 4 Pro h(k) = k mod 5 jsou synonymní klíče např. {2, 12, 17,... }. prof. Pavel Tvrdík (FIT ČVUT) Rozptylovací tabulky BI-EFA, 2010, Předn. 2 7 / 19
Rozptylovací tabulky Rozptylování Rozptylovací funkce Volba rozptylovací funkce h závisí na vlastnostech univerza klíčů: 1 implementační typ klíčů: přirozené číslo, reálné číslo, řetězec, atd. 2 rozsah (interval) hodnot klíčů. Požadované vlastnosti rozptylovací funkce: 1 výpočetní jednoduchost a rychlost výpočtu, 2 aproximace náhodné funkce, 3 rovnoměrné využití adresního prostoru M tabulky, 4 generování minimálního počtu kolizí, 5 využití pokud možno všech částí klíče (obecně lze použít jen část klíče). prof. Pavel Tvrdík (FIT ČVUT) Rozptylovací tabulky BI-EFA, 2010, Předn. 2 8 / 19
Rozptylovací tabulky Často používané rozptylovací funkce Často používané rozptylovací funkce Nechť M je velikost rozptylovací tabulky a M = {0,..., M 1}. Modulární rozptylovací funkce: Uvažujme přirozené klíče (U = N ). h(k) = k mod M. Vlastnosti h silně závisí na volbě M. Např. M = 2 p nebo M = 10 p je vhodné pouze, pokud pravděpodobnostní rozložení klíčů je rovnoměrné přes posledních p bitů/číslic. M se typicky volí jako prvočíslo dostatečně vzdálené od mocniny základu. Multiplikativní rozptylovací funkce 1: Uvažujme přirozené klíče reprezentované jako w-bitová slova, w je konst. (U = B w ). h(k) = M (k/2 w ), dělení 2 w je posuv binární čárky. Není citlivé na volbu M. Naopak, z implementačních důvodů se volí M = 2 p (rychlejší aritmetické operace). prof. Pavel Tvrdík (FIT ČVUT) Rozptylovací tabulky BI-EFA, 2010, Předn. 2 9 / 19
Řetězení (Chaining) = Otevřené rozptylování (Open hashing) = Interpolační rozptylování. Otevřené adresování (Open addressing) = Uzavřené rozptylování (Closed hashing). prof. Pavel Tvrdík (FIT ČVUT) Rozptylovací tabulky BI-EFA, 2010, Předn. 2 10 / 19
Řetězení (Chaining) Řetězení Metoda řešící kolize tím, že synonyma zřetězí/spojí/seskupí do dílčích tabulek (řetězců). Typická implementace takové rozptylovací tabulky je pole M ukazatelů na dílčí tabulky: V dílčí tabulce na ukazateli T [i] jsou ukládány prvky se (synonymními) klíči k, pro které h(k) = i. Dílčí tabulky lze realizovat různým způsobem, např. 1 spojovým seznamem, 2 uspořádaným spojovým seznamem, 3 rozšiřitelným polem, 4 stromem. prof. Pavel Tvrdík (FIT ČVUT) Rozptylovací tabulky BI-EFA, 2010, Předn. 2 11 / 19
Řetězení (Chaining) Řetězení Příklad 5 Předpokládejme, že: M = 3 a h(k) = k mod 3. Dílčí tabulky realizujeme spojovým seznamem. Vkládáme posloupnost prvků s klíči: 1, 5, 21, 10, 7. Nové prvky vkládáme vždy na začátek příslušného spojového seznamu (při vkládání je třeba kontrolovat, zda prvek se stejným klíčem už v tabulce není). T 0 1 2 21 7 5 \ \ 10 1 \ Seznamy synonym prof. Pavel Tvrdík (FIT ČVUT) Rozptylovací tabulky BI-EFA, 2010, Předn. 2 12 / 19
Řetězení (Chaining) Otevřené adresování (Open addressing) Metoda řešení kolizí v rozptylovacích tabulkách, založená na hledání alternativní volné pozice jejím procházením. Východiska: Známe/odhadneme předem počet použitých klíčů K. Chceme pevnou velikost rozptylovací tabulky. Prvky tabulky ukládáme (obecně nesouvisle) do tabulky na místa postupně generovaná rozptylovací funkcí h(k, i). Definice 6 Rozptylovací funkci rozšíříme o parametr i, reprezentující pořadí pokusu o vložení prvku s daným klíčem do rozptylovací tabulky. h(k, i) : U {0, 1, 2,..., M 1} {0, 1, 2,..., M 1} prof. Pavel Tvrdík (FIT ČVUT) Rozptylovací tabulky BI-EFA, 2010, Předn. 2 13 / 19
Řetězení (Chaining) Myšlenka algoritmu Otevřeného adresování 1 V případě kolize pro daný klíč k postupně zkoušíme indexy h(k, 0), h(k, 1),..., h(k, M 1) a toto pořadí musí generovat permutaci indexů rozptylovací tabulky (čili posloupnost zkoušek musí pokrýt všechna místa v tabulce). 2 Pokud ke kolizi nedošlo, vrací poslední volání rozptylovací funkce index volného místa, nad kterým můžeme provést požadovanou operaci (insert, search, delete). 3 Ideálem (nedosažitelným) je uniformní rozptylovací funkce h(k, i), která dokáže pro libovolný klíč k U vygenerovat posloupnost zkoušek rovnou kterékoli předem určené permutaci M prvků. prof. Pavel Tvrdík (FIT ČVUT) Rozptylovací tabulky BI-EFA, 2010, Předn. 2 14 / 19
Řetězení (Chaining) Metody řešící kolize při otevřeném adresování 1 Lineární prohledávání (Linear Probing) 2 Lineární prohledávání s krokem (Linear Probing by Step) 3 Kvadratické prohledávání (Quadratic Probing) 4 Dvojí rozptylování (Double Hashing) prof. Pavel Tvrdík (FIT ČVUT) Rozptylovací tabulky BI-EFA, 2010, Předn. 2 15 / 19
Lineární procházení (Linear Probing) Lineární procházení (Linear Probing) Základní myšlenka: V případě kolize postupně testuje následující pozice a hodnotu uloží na první volnou pozici. Příklad jednoduchého řešení: h(k, i) = (k + i) mod M. Příklad 7 Uvažujme M = 11, h(k, i) = (k + i) mod 11 a vkládání prvků. Posloupnost: 3, 16, 6, 29, 9, 25, 5, 4 h(4,6) = 10 3 25 16 6 29 5 9 4 0 1 2 3 4 5 6 7 8 9 10 Celkový počet kolizí od začátku vkládání: 10 prof. Pavel Tvrdík (FIT ČVUT) Rozptylovací tabulky BI-EFA, 2010, Předn. 2 16 / 19
Lineární prohledávání s krokem (Linear Probing by Step) Lineární prohledávání s krokem (Linear Probing by Step) Základní myšlenka: Je třeba redukovat lokální souvislé shluky a zároveň prohledat všechny pozice krok prohledávání bude větší než 1. h(k, i) = (k + c i) mod M, kde c je velikost kroku. c volíme tak aby mohly být navštíveny všechny pozice číslo c musí být nesoudělné s M. Příklad 8 h(k, i) = (k + 4 i) mod 11 Posloupnost: 3, 16, 6, 29, 9, 25, 5, 4 h(4,0) = 4 25 5 3 4 16 6 29 9 0 1 2 3 4 5 6 7 8 9 10 Celkový počet kolizí od začátku vkládání: 4 prof. Pavel Tvrdík (FIT ČVUT) Rozptylovací tabulky BI-EFA, 2010, Předn. 2 17 / 19
Kvadratické prohledávání (Quadratic Probing) Kvadratické prohledávání (Quadratic Probing) Základní myšlenka: Je třeba omezit rezonanci shluků a zároveň prohledat všechny pozice délka kroku prohledávání nelineárně závislá na počtu neúspěšných testů kvadratická fce. h(k, i) = (h (k) + c 1 i 2 + c 2 i) mod M, kde c 1 0 a c 2 jsou konstanty. Konstanty c 1 a c 2 volíme tak, aby mohly být navštíveny všechny pozice posloupnost generovaná výrazem c 1 i 2 + c 2 i musí být permutací {0,..., M 1}. Možnosti pro operaci delete jsou obdobné jako u předchozí metody. Příklad 9 h(k, i) = (k + i2 2 + i 2 ) mod 8 Posloupnost: 16, 6, 85, 19, 9, 8 h(8,4) = 2 16 9 8 19 85 6 0 1 2 3 4 5 6 7 Celkový počet kolizí od začátku vkládání: 4 prof. Pavel Tvrdík (FIT ČVUT) Rozptylovací tabulky BI-EFA, 2010, Předn. 2 18 / 19
Dvojité rozptylování (double hashing) Dvojité rozptylování (double hashing) Základní myšlenka: Permutační posloupnost adres testovaných pozic relativně k počátku má být pro dva různé klíče odlišná. Pro generování testovacích posloupností použijeme 2 rozptylovací funkce a na jedné z nich bude záviset testovací krok. Příklad řešení: h(k, i) = (h 1 (k) + i h 2 (k)) mod M, kde h 1 (k) = k a h 2 (k) = 1 + k mod L. L volíme tak, aby mohly být navštíveny všechny pozice. Doporučuje se, aby M bylo prvočíslo a L číslo o něco menší než M. Příklad 10 h(k, i) = (h 1 (k) + i h 2 (k)) mod 11, h 1 (k) = k, h 2 (k) = 1 + k mod 7. Posloupnost: 3, 16, 6, 29, 9, 25, 5, 4 h(4,0) = 0 5 3 4 16 6 29 25 9 0 1 2 3 4 5 6 7 8 9 10 Celkový počet kolizí od začátku vkládání: 2 prof. Pavel Tvrdík (FIT ČVUT) Rozptylovací tabulky BI-EFA, 2010, Předn. 2 19 / 19