Haszowanie dr inż. Urszula Gałązka
Problem Potrzebujemy struktury do Wstawiania usuwania wyszukiwania Liczb, napisów, rekordów w Bazach danych, sieciach komputerowych, innych Rozwiązanie Tablice z haszowaniem
Tablice z haszowaniem O Haszowanie- inaczej zwane mieszaniem lub rozpraszaniem. O Tablica z haszowaniem jest strukturą służącą do reprezentacji słowników. O Wyszukiwanie elementu w takiej tablicy w najgorszym wypadku trwa tyle co na liście - (n), w najlepszym (1). O Rozmiar tablicy z haszowaniem zwykle jest proporcjonalny do liczby elementów, które zawiera (w klasycznej tablicy zależny jest od indeksu, który jest kluczem) O Indeks w tablicy z haszowaniem nie jest kluczem ale może posłużyć do obliczenia klucza
Tablice z haszowaniem O Zbiory z danymi (liczby, napisy) będziemy nazywać słownikami O Potrzebujemy trzech operacji na danych: O SEARCH(k) - wyszukiwanie elementu o kluczu k. O INSERT(d,k) dopisywanie elementu d o kluczu k O DELETE(d,k) usuwanie elementu d o kluczu k
Tablice z adresowaniem bezpośrednim O Skuteczna przy małej liczbie kluczy. O Załóżmy że mamy klucze w zbiorze (Uniwersum kluczy) U={0,1,,m-1} wówczas możemy tablicę reprezentować jako tablicę T[0..m-1], W której każdej pozycji odpowiada klucz należący do zbioru U. Na pozycji k w tablicy znajduje się wskaźnik do elementu o kluczu k. Jeśli do zbioru nie należy żaden element o kluczu k, to T[k]=NIL. O Przy dużym uniwersum kluczy U przechowywanie w pamięci komputera tablicy T o rozmiarze U może okazać się nie możliwe.
Operacje Każda z tych operacji działa w czasie O(1).
Tablice z haszowaniem O Element o kluczu k umieszcza się na pozycji h(k) gdzie h to funkcja haszująca, która oblicza pozycję klucza k. O Funkcja ha odwzorowuje uniwersum kluczy U w zbiór pozycji tablicy z haszowaniem T[0..m-1] w sposób: h:u {0,1,,m-1}, O gdzie przeważnie rozmiar m tablicy z haszowaniem jest znacznie mniejszy niż U. O Mówimy, że element o kluczu k jest haszowany na pozycję h(k); mówimy także, że h(k) jest wartością haszującą klucza k.
Tablice z haszowaniem kolizja
Kolizja O Kiedy funkcja haszująca przypisuje to samo miejsce w tablicy dwóm różnym kluczom. O Metody rozwiązania: 1. Unikanie kolizji 2. Metoda łańcuchowa 3. Adresowanie otwarte
1. Unikanie kolizji O Dobry wybór funkcji haszującej, czyli taki by funkcja wydawała się losowa ale była deterministyczna (czyli że dla danego k zawsze dawała ten sam wynik h(k)) O Ponieważ U >m to zawsze się znajdzie przypadek, gdzie funkcja haszująca da ten sam wynik dla dwóch różnych kluczy, czyli całkowite uniknięcie kolizji w tej metodzie jest niemożliwe
2. Metoda łańcuchowa O Wszystkie elementy, którym odpowiada ta sama pozycja umieszczamy na jednej liście, O Pozycja w tablicy przechowuje teraz wskaźnik do początku listy
Metoda łańcuchowa operacje słownikowe
Metoda łańcuchowa analiza O wydajności Niech będzie dana tablica T o m pozycjach, w której znajduje się n elementów. Wtedy jej współczynnik zapełnienia możemy zapisać wzorem: = n/m O O O - oznacza średnią liczbę elementów przechowywanych w tablicy Najgorszy przypadek: kiedy wszystkie n kluczy jest odwzorowanych na tę samą pozycję w tablicy, tworząc listę o długości n. Pesymistyczny czas wyszukiwania wynosi: Θ(n) +O(1) (czas na obliczenie wartości funkcji haszującej) Jeżeli losowo wybrany element z jednakowym prawdopodobieństwem trafia na każdą z m pozycji, niezależnie od tego, gdzie trafiają inne elementy to nazywa się to prostym równomiernym haszowaniem.
3. Adresowanie otwarte O W metodzie adresowania otwartego wszystkie elementy przechowuje się wprost w tablicy. O Każda pozycja w tablicy zawiera wiec albo element zbioru albo wartość NIL. O Wyszukiwanie elementu polega na systematycznym przeszukiwaniem tablicy element po elemencie. Efektem będzie znaleziony element lub informacja że go nie ma w tablicy. O Brak jest dodatkowych list oraz przechowywania elementów poza tablicą. O W adresowaniu otwartym, współczynnik zapełnienia nie może nigdy przekroczyć 1, aby nie nastąpiło przepełnienie tablicy.
Adresowanie otwarte definicja funkcji haszującej O Funkcja haszującą będzie miała postać: h:u {0,1,,m-1} {0,1,,m-1} O o własności takiej, że dla każdego klucza k ciąg pozycji (ciąg kontrolny klucza k) <h(k,0), h(k,1),, h(k,m-1)> jest permutacją pozycji <0,1,, m-1>.
Adresowanie otwarte dodawanie
Adresowanie otwarte wyszukiwanie
Adresowanie otwarte - usuwanie O Nie można usunąć klucza z pozycji i wpisać w nią adres NIL. Groziłoby by odcięciem dostępu do kluczy k. O Problem można rozwiązać wpisując na tę pozycję specjalną stałą DELETED zamiast NIL. Wówczas gdy procedura HASH-SEARCH natknie się na pozycję DELETED powinna dalej kontynuować poszukiwania, natomiast procedura HASH-INSERT może potraktować pozycję jako wolną i wstawić w nią nowy klucz.
Funkcje haszujące idealne cechy O Powinna spełniać założenie prostego równomiernego haszowania: losowo wybrany klucz jest z jednakowym prawdopodobieństwem odwzorowywany na każdą z m pozycji (W praktyce trudno spełnić ten warunek gdyż rzadko znamy rozkład prawdopodobieństwa pojawiania się kluczy). O Powinna być wybrana tak by jej wartości były maksymalnie niezależne od tendencji mogących występować w danych. O Czasami wymaga się aby niewiele różniącym się wartościom kluczy odpowiadały znacznie od siebie oddalone wartości funkcji haszującej. O Większość funkcji haszujących ma dziedzinę będącą zbiorem liczb naturalnych N={0,1,2, }. Zatem jeśli klucze nie są liczbami naturalnymi to należy ustalić ich odwzorowanie w zbiór liczb naturalnych.
Haszowanie modularne O Niech U = N = {0,1,2, }, będzie zbiorem liczb naturalnych. Wówczas funkcję haszującą możemy zapisać wzorem: h(k)=k mod m. O Liczba m musi być dobrze wybrana O Zły wybór: jeśli mi m będzie potęgą 2 czyli m=2 p lub m=2 p -1 (w pierwszym przypadku h(k) będzie liczbą, która powstaje z p najmniej znaczących bitów liczby k w drugim permutacja znaków w k nie zmienia wartości funkcji haszującej) O Dobry wybór: m jako liczba pierwsza odległa od potęgi 2.
Haszowanie modularne - przykład O Cel: Przechowanie w tablicy z haszowaniem 2000 ciągów znaków. Dopuszczamy maksymalnie 3 kolizje dla klucza (czyli α=3) O Rozwiązanie: Szukamy rozmiaru tablicy m O Ponieważ 2000/α = 2000/3 666 O To najbliższa liczba pierwsza bliska tej wartości i daleka od potęg dwójki to 701. O Zatem wzór funkcji haszującej będzie następujący: h(k)=k mod 701
Haszowanie przez mnożenie O Wykonujemy w dwóch krokach: 1. mnożymy klucz k przez stałą A z przedziału 0<A<1 i wyciągamy część ułamkową iloczynu ka 2. mnożymy uzyskaną wartość przez m a wynik zaokrąglamy w dół. O Możemy zapisać to wzorem: h(k)= m(ka mod 1) gdzie ka mod 1 to część ułamkowa ka, czyli ka- ka. O Wartość m można wybrać dowolnie. Zwykle, ze względu na łatwość implementacji komputerowej, wybiera się ją jako pewną potęgę 2, czyli m=2 p dla pewnej liczby naturalnej p.
Haszowanie przez mnożenie O Niech słowo maszynowe ma długość w bitów oraz k mieści się w jednym słowie. Natomiast niech A będzie ułamkiem postaci s/2 w, gdzie s jest liczbą całkowitą z przedziału 0<s<2 w. W pierwszej kolejności mnoży się k przez w-bitową liczbę całkowitą s=a*2 w. Wynik stanowi 2wbitowa liczba r 1 2 w +r 0, gdzie r 1 jest bardziej znaczącym, a r 0 mniej znaczącym słowem iloczynu. Szukana p-bitowa wartość funkcji haszującej składa się z p najbardziej znaczących bitów liczby r 0.
Haszowanie przez mnożenie - ilustracja w bitów k x s=a*2 w r 1 r 0 p bitów h(k)
Sposoby obliczania ciągów kontrolnych 1. Adresowanie liniowe, 2. Adresowanie kwadratowe 3. Haszowanie dwukrotne.
Adresowanie liniowe O Funkcja haszująca dana jest wzorem: h(k,i)=(h (k)+i) mod m O Gdzie h to zwykła funkcja haszująca h :U {0,1,,m- 1}, zwana pomocniczą funkcją haszującą, dla i=0,1,,m-1. O Dla danego klucza k otrzymujemy ciąg: T[h (k)], T[h (k)+1],, T[m-1], T[0], T[1],, T[h (k)-1]. O Zaleta: łatwość realizacji O Wada: tendencja do grupowania się pozycji zajętych(tzw. grupowanie pierwotne). Długie, spójne ciągi zajętych pozycji szybko się powiększają, co spowalnia operacje poszukiwania.
Adresowanie kwadratowe O Funkcję haszująca dana jest wzorem: h(k,i)=(h (k)+c 1 i+c 2 i 2 ) mod m, O gdzie h jest pomocniczą funkcją haszującą, c 1 i c 2 są pewnymi dodatnimi stałymi, a i=0,1,,m-1. O Pierwszą odwiedzoną pozycją jest T[h (k)] a kolejne pozycje są oddalone od początkowej o wielkość zależną od kwadratu numeru pozycji i w ciągu kontrolnym. O Należy dobrze ustalić wartości: c 1, c 2 i m. O Wada: pojawia się grupowanie wtórne czyli gdy klucze o tej samej pozycji początkowej dają takie same ciągi kontrolne.
Haszowanie dwukrotne O Funkcja haszująca dana jest wzorem: h(k,i)=(h 1 (k)+ih 2 (k)) mod m, O gdzie h 1 i h 2 są pomocniczymi funkcjami haszującymi. O Pierwszą pozycją w ciągu kontrolnym klucza k jest T[h 1 (k)]; kolejna pozycja jest oddalona od poprzedniej o h 2 (k) modulo m. O Aby mieć gwarancję, że przeszukana będzie cała tablica, wartość h 2 (k) powinna być względnie pierwsza z rozmiarem tablicy m. Jeżeli dwie liczby całkowite a i b nie mają żadnego naturalnego dzielnika oprócz 1, to liczby takie nazywamy liczbami względnie pierwszymi.
Podsumowanie
Bibliografia Literatura O Cormen Thomas; Leiserson Charles; Rivest Ronald; Stein Clifford, Wprowadzenie do Algorytmów, Wydawnictwo Naukowe PWN, Warszawa 2012, O Wróblewski Piotr, Algorytmy, Struktury Danych i Techniki Programowania, Wydawnictwo Helion, Gliwice 2010 O Banachowski Lech, Diks Krzysztof, Rytter Wojciech, Algorytmy i Struktury danych, Wydawnictwa Naukowo- Techniczne, Warszawa 1996. O http://www.math.edu.pl/liczby-wzglednie-pierwsze, O Dostęp: 20.11.2017 Rysunki O opracowanie własne