Κατακερματισμός
Το Πρόβλημα του Λεξικού – Λύσεις Διατήρηση με αποδοτικό τρόπο ενός συνόλου κλειδιών ώστε οι εξής 3 πράξεις να υποστηρίζονται αποδοτικά: Εύρεση ενός στοιχείου στο σύνολο Ένθεση ενός νέου στοιχείου στο σύνολο Διαγραφή ενός υπάρχοντος στοιχείου από το σύνολο Λύνουν και το πρόβλημα του προηγούμενου στοιχείου (predecessor) Ανέφερε διαφορές μεταξύ τους. Κατακερματισμός Δέντρα
Άμεση Διευθυνσιοδότηση Υποθέσεις: Τα στοιχεία είναι ανά δύο διαφορετικά Κάθε στοιχείο προκύπτει από ένα σύμπαν U = {0, 1, . . . , u - 1} Ιδέα: Αποθήκευση των στοιχείων σε πίνακα με βάση το κλειδί Αναπαράσταση: Ένας πίνακας T[0 . . . u - 1] Κάθε κάδος (θέση) του T αντιστοιχεί σε ένα κλειδί του U Για ένα στοιχείο x, ένας δείκτης στο (ή το ίδιο το x) αποθηκεύεται στην θέση T[x] Αν δεν υπάρχουν στοιχεία x στο σύνολο S, το T[x] είναι άδειο, (NIL)
Άμεση Διευθυνσιοδότηση Πρόβλημα; Άμεση Διευθυνσιοδότηση U (σύμπαν στοιχείων) k1 k4 k1 S (σύνολο κλειδιών) k4 k2 k2 k3 k3 Μεγάλο U u - 1
Πίνακες Κατακερματισμού Όταν το S είναι μικρότερο του U, ένας πίνακας κατακερματισμού απαιτεί λιγότερο χώρο από την άμεση διευθυνσιοδότηση. Μείωση του χώρου σε |S| Ακόμα έχουμε O(1) χρόνος εύρεσης, αλλά στη μέση περίπτωση (και στη χειρότερη σε κάποιες περιπτώσεις όπως θα δούμε)
Πίνακες Κατακερματισμού Ιδέα: Χρήση της h για υπολογισμό του κάδου Αποθήκευση του στοιχείου στο κάδο h(k) Μία συνάρτηση κατακερματισμού h μετατρέπει ένα στοιχείο σε διεύθυνση στον πίνακα T[0…m-1]: h : U → {0, 1, . . . , m – 1}
Παράδειγμα: Πίνακες Κατακερματισμού Πρόβλημα; Παράδειγμα: Πίνακες Κατακερματισμού U (σύμπαν κλειδιών) h(k1) h(k4) k1 S (σύνολο κλειδιών) k4 k2 h(k2) = h(k5) k5 k3 h(k3) m - 1
Αποφυγή Συγκρούσεων Εν τάχει: Αλυσίδες (chaining) Ανοικτή διευθυνσιοδότηση (Open addressing) Linear probing Cuckoo Hashing Universal Hashing Perfect Hashing
Συγκρούσεις με Αλυσίδες
Κατακερματισμός με Αλυσίδες: Ανάλυση Πόσο χρειάζεται για την εύρεση ενός στοιχείου; Χειρότερη περίπτωση: Τα n στοιχεία πέφτουν στον ίδιο κάδο Χρόνος χειρότερης περίπτωσης (n), συν το χρόνο για υπολογισμό της συνάρτησης κατακερματισμού. m - 1 T αλυσίδα
Κατακερματισμός με Αλυσίδες: Ανάλυση Μέση Περίπτωση: Εξαρτάται από πόσο καλά κατανείμει η συνάρτηση τα n στοιχεία στους m κάδους Υπόθεση: απλός ομοιόμορφος κατακερματισμός Κάθε στοιχείo έχει ίδια πιθανότητα να πέσει σε οποιονδήποτε από τους m κάδους (η πιθανότητα σύγκρουσης Pr(h(x)=h(y)), είναι 1/m) Μήκος λίστας: T[j] = nj, j = 0, 1, . . . , m – 1 Πλήθος κλειδιών στον πίνακα: n = n0 + n1 +· · · + nm-1 Μέσο μήκος nj: E[nj] = α = n/m n0 = 0 nm – 1 = 0 T n2 n3 nj nk
Περίπτωση 1: Ανεπιτυχής Αναζήτηση Θεώρημα Μία ανεπιτυχής αναζήτηση απαιτεί Θ(1+α) αναμενόμενο χρόνο με βάση την υπόθεση του απλού ομοιόμορφου κατακερματισμού. Απόδειξη: Ανεπιτυχής αναζήτηση για το στοιχείο k Απαιτείται αναζήτηση μέχρι το τέλος της λίστας T[h(k)] Μέσο μήκος αλυσίδας: E[nh(k)] = α = n/m Μέσο πλήθος στοιχείων είναι ίσο με α Συνολικός χρόνος: O(1) (υπολογισμός συνάρτησης ) + α Θ(1+α)
Συναρτήσεις Πότε μία συνάρτηση είναι καλή; (1) Εύκολα υπολογίσιμη (2) Προσεγγίζει μία τυχαία συνάρτηση: για κάθε είσοδο κάθε έξοδο έχει ίδια πιθανότητα (απλός ομοιόμορφος κατακερματισμός) Στην πράξη είναι δύσκολο να ικανοποιηθεί αυτή η υπόθεση. Δεν ξέρουμε συνήθως την κατανομή των δεδομένων των στοιχείων
Χαρακτηριστικά Καλών Συναρτήσεων Ελαχιστοποίηση πιθανότητας να πέσουν δύο κοντινά στοιχεία στον ίδιο κάδο Οι λέξεις pt και pts θα πρέπει να απεικονίζονται σε άλλους κάδους Θέλουμε μία hash τιμή ανεξάρτητη των μοτίβων που μπορεί να υπάρχουν στα στοιχεία του S.
Κοινές Συναρτήσεις Κατακερματισμού Στην πράξη: D.E. Knuth: The Art of Computer Programming Μέθοδος διαίρεσης Για αλφαριθμητικά της μορφής s = s0s1 . . . sk-1: π.χ. B = 131 και w = μήκος λέξης (bits) (w = 32 ή w = 64).
Η Μέθοδος της Διαίρεσης Ιδέα: Απεικόνισε το στοιχείο k σε έναν από τους m κάδους: h(k) = k mod m Πλεονέκτημα: Γρήγορο, μόνο μία πράξη Μειονέκτημα: Μερικές τιμές του m είναι κακές Δυνάμεις του 2 Σύνθετοι αριθμοί Οι δύο μέθοδοι που θα ακολουθήσουν είναι περισσότερο ευρετικοί με την έννοια ότι δεν αποδεικνύουμε τίποτα για αυτούς
Παράδειγμα m97 m 100 Αν m = 2p, τότε το h(k) είναι τα p λιγότερο σημαντικά bits του k p = 1 m = 2 h(k) = {0,1}, 1ο LSB του k p = 2 m = 4 h(k) = {0,1,2,3}, 2 λιγότερα σημαντικά ψηφία του k Επιλογή m ως πρώτου αριθμού, όχι κοντά σε δύναμη του 2 Στήλη 2: k mod 97 Στήλη 3: k mod 100 Συνήθως υπάρχει μία κανονικότητα στα δεδομένα αφού αυτά αναπαρίστανται σε δυαδικό ή δεκαδικό σύστημα.
Η Μέθοδος Πολλαπλασιασμού Ιδέα: Πολλαπλασιασμός k με μία σταθερά A, όπου 0 < A < 1 (ο Knuth προτείνει το χρυσό λόγο φ) Εξάγουμε το κλασματικό μέρος του kA Πολλαπλασιάζουμε με m h(k) = m (k A mod 1) Μειονέκτημα: Πιο αργό από την μέθοδο διαίρεσης (;;;) Πλεονέκτημα: Η τιμή του m δεν είναι κρίσιμη (τυπικά m=2p) Ο Leiserson λέει στο video ότι μία συγγενής υλοποίηση της μεθόδου είναι πιο γρήγορή από την διαίρεση
Ανοικτή Διευθυνσιοδότηση Αν (m > n) αποθήκευση κλειδιών στον πίνακα μόνο Όχι λίστες Ιδέα: Ένθεση: αν ένας κάδος είναι γεμάτος, δοκίμασε κάποιον άλλον μέχρι να βρεθεί ένας άδειος Αναζήτηση: ίδια ακολουθία ελέγχων Διαγραφή: πιο δύσκολη Ο χρόνος αναζήτησης εξαρτάται από την ακολουθία ελέγχων! Ένθεση 14
Γενίκευση Συνάρτησης Κατακερματισμού: Μία συνάρτηση με 2 παραμέτρους: (i) Στοιχείο, και (ii) Ακολουθία ελέγχου h(k,p), p=0,1,...,m-1 Ακολουθία ελέγχων <h(k,0), h(k,1), ..., h(k,m-1)> Πρέπει να είναι αναδιάταξη <0,1,...,m-1> Υπάρχουν m! διαφορετικές αναδιατάξεις Οι καλές συναρτήσεις θα έπρεπε να παράγουν όλες τις m! αναδιατάξεις Ένθεση 14 <1, 5, 9>
Κοινές Μέθοδοι Ανοικτής Διευθυνσιοδότησης Γραμμικός Έλεγχος Τετραγωνικός Έλεγχος Διπλός Κατακερματισμός κ.α. Note: None of these methods can generate more than m2 different probing sequences!
Γραμμικός Έλεγχος: Ένθεση Ιδέα: όταν υπάρχει σύγκρουση, έλεγξε την επόμενη διαθέσιμη θέση στον πίνακα (έλεγχος) h(k,i) = (h1(k) + i) mod m i = 0,1,2,... Πρώτος κάδος: h1(k) Δεύτερος κάδος: h1(k) + 1 Τρίτος κάδος: h1(k)+2, κοκ. Can generate m probe sequences maximum, why? Ακολουθία ελέγχων: < h1(k), h1(k)+1 , h1(k)+2 , ....> Επιστρέφει στην αρχή
Γραμμικός Έλεγχος: Αναζήτηση Τρεις περιπτώσεις: (1) Η θέση στον πίνακα περιέχει το στοιχείο που αναζητάμε (2) Η θέση είναι άδεια (3) Η θέση περιέχει ένα διαφορετικό στοιχείο Περίπτωση (2): έλεγξε τα επόμενα κελιά μέχρι να φτάσουμε σε (1) ή σε (3) h(k1) h(k4) h(k2) = h(k5) h(k3) The process wraps around to the beginning of the table m - 1
Γραμμικός Έλεγχος: Διαγραφή Πρόβλημα: Δεν μπορούμε να κάνουμε το κελί άδειο Αδύνατο να βρούμε τα κλειδιά που εντέθηκαν αφού ο κάδος αυτός γέμισε. Λύση: Μάρκαρε τον κάδο ως διαγραμμένο. Ο διαγραμμένος κάδος μπορεί να χρησιμοποιηθεί για ένθεση Η αναζήτηση εκτελείται κανονικά m - 1
Γραμμικός Έλεγχος: Κόστος Ανεπιτυχής αναζήτηση: Επιτυχής αναζήτηση:
Ας Προχωρήσουμε πιο Βαθιά Καθολικός Κατακερματισμός Τέλειος Κατακερματισμός Bloom Φίλτρα
Καθολικός Κατακερματισμός (Universal Hashing) Στην πράξη, τα στοιχεία δεν είναι ομοιόμορφα κατανεμημένα Κάθε καθορισμένη συνάρτηση μπορεί να δώσει Θ(n) χρόνο Στόχος: Συναρτήσεις που παράγουν τυχαίες διευθύνσεις στον πίνακα ανεξάρτητα από τα κλειδιά Ιδέα: Επέλεξε μία συνάρτηση τυχαία, από μία προκαθορισμένη οικογένεια συναρτήσεων
Καθολικός Κατακερματισμός Πίνακας Κατακερματισμού Σύνολο συναρτήσεων κατακερματισμού Τυχαία επιλογή συνάρτησης h1( ) h2( ) … hk( ) hi( ) (στην αρχή της εκτέλεσης)
Καθολικές Συναρτήσεις Κατακερματισμού H={ h(k): U {0,1,..,m-1} } Η H είναι καθολική αν για κάθε x y: H
Γιατί αυτή η ιδιότητα είναι χρήσιμη; Ποια είναι η πιθανότητα σύγκρουσης σε αυτή την περίπτωση; Είναι ίση με την πιθανότητα επιλογής μία συνάρτησης h H έτσι ώστε x y h(x) = h(y) που είναι ίση με:
Καθολικός Κατακερματισμός Με τον καθολικό κατακερματισμό η πιθανότητα σύγκρουσης μεταξύ διαφορετικών στοιχείων k και l δεν είναι παραπάνω από 1/m αν οι θέσεις h(k) και h(l) επιλέχθηκαν τυχαία και ανεξάρτητα από το σύνολο {0, 1, …, m – 1}
Σχεδιάζοντας μία Οικογένεια Καθολικών Συναρτήσεων Επέλεξε έναν πρώτο αριθμό p αρκετά μεγάλο ώστε κάθε στοιχείο k να είναι στο διάστημα [0 ... p – 1] Zp = {0, 1, …, p - 1} και Zp* = {1, …, p - 1} Ορίζουμε τη συνάρτηση ha,b(k) = ((ak + b) mod p) mod m, a Zp* και b Zp Η οικογένεια όλων αυτών των συναρτήσεων είναι Hp,m = {ha,b: a Zp* και b Zp} a , b: επιλέγονται τυχαία στην αρχή της εκτέλεσης
Παράδειγμα p = 17, m = 6 ha,b(k) = ((ak + b) mod p) mod m h3,4(8) = ((38 + 4) mod 17) mod 6 = (28 mod 17) mod 6 = 11 mod 6 = 5
Άλλη Καθολική Οικογένεια Συναρτήσεων Έστω m πρώτος. Αναπαριστούμε το στοιχείο k με r + 1 ψηφία σε βάση m. Έστω k = 〈k0, k1, …, kr〉, όπου 0 ≤ ki < m. Επιλέγουμε a = 〈a0, a1, …, ar〉, όπου κάθε ai επιλέχθηκε τυχαία από το σύνολο {0, 1, …, m–1}. Εσωτερικό γινόμενο
Πλεονεκτήματα Καθολικού Κατακερματισμού Δίνει καλά αποτελέσματα στη μέση περίπτωση ανεξαρτήτως των στοιχείων που αποθηκεύονται Εγγυάται ότι καμία είσοδος δεν θα προκαλεί συμπεριφορά χειρότερης περίπτωσης Κακή απόδοση έχουμε μόνο όταν η τυχαία επιλογή επιστρέφει μία κακή συνάρτηση κατακερματισμού (μικρή πιθανότητα)
Τέλειος Κατακερματισμός Οι λύσεις που είδαμε μέχρι τώρα λύνουν το πρόβλημα σε O(n) χώρο αλλά με O(1) αναμενόμενο χρόνο για αναζήτηση. Μπορούμε καλύτερα; Μία τέλεια συνάρτηση κατακερματισμού για ένα σύνολο S είναι μία συνάρτηση χωρίς συγκρούσεις. Με μία τέλεια συνάρτηση για το S έχουμε O(1) χρόνο χειρότερης περίπτωσης για την αναζήτηση για το στατικό πρόβλημα του λεξικού στο S. (Γιατί;)
Στατικό Λεξικό Συνδυασμός δύο λύσεων για στατικό κατακερματισμό με χρήση καθολικού κατακερματισμού: Μία λύση που χρησιμοποιεί πολύ χώρο χωρίς συγκρούσεις. Μία λύση με λίγο χώρο αλλά πολλές συγκρούσεις. Λύση δύο επιπέδων: Χρήση λίγου χώρου στο επίπεδο 1 Επίλυση συγκρούσεων στο επίπεδο 1 με χρήση λύσης χωρίς συγκρούσεις στο επίπεδο 2 lookup(x): αναζήτηση στο επίπεδο 1 για την εύρεση του σωστού επιπέδου 2. Αναζήτηση μετά στο επίπεδο 2.
Όταν Χρησιμοποιούμε Πολύ Χώρο Χρήση μίας καθολικής συνάρτησης για απεικόνιση σε πίνακα μεγέθους N2. Ποιο είναι το αναμενόμενο πλήθος συγκρούσεων; Αποδεικνύεται ότι είναι ½. Με πιθανότητα ½ παίρνουμε μία τέλεια συνάρτηση κατακερματισμού που υποστηρίζει αναζητήσεις σε O(1) χρόνο χειρότερης περίπτωσης αν ο χώρος είναι O(N2). Επαναλαμβάνουμε την εύρεση μίας συνάρτησης μέχρι να βρούμε την τέλεια.
Όταν Χρησιμοποιούμε Λίγο Χώρο Χρήση μίας καθολικής συνάρτησης για απεικόνιση σε πίνακα μεγέθους N. Ποιο είναι το αναμενόμενο πλήθος συγκρούσεων; Είναι ίσο με ½Ν.
Λύση 2 Επιπέδων Λύση 2 επιπέδων: Στο επίπεδο 1 κάνουμε χρήση της λύσης με O(N) συγκρούσεις. Επιλύουμε τις συγκρούσεις στο επίπεδο 2 με την λύση τετραγωνικού χώρου χωρίς συγκρούσεις.
Παράδειγμα S = {1,16,41,54,66,96} Επίπεδο 1: S1 = {1, 41}, S4 = {54}, S6 = {16, 66, 96} Επίπεδο 2: πληροφορία για συνάρτηση αποθηκεύεται με τον κάδο O(1) χρόνος χειρότερης περίπτωσης. Χώρος; Αποδεικνύεται O(n) αναμενόμενος
Bloom Φίλτρα
Το Κύριο Σημείο Όταν έχετε ένα σύνολο ή μία λίστα, και ο χώρος είναι θέμα (και δεν σας πειράζει να έχετε false positives) τότε το Bloom φίλτρο είναι μία καλή εναλλακτική.
Πρόβλημα Δοθέντος ενός συνόλου S = {x1,x2,…,xn}, σχεδιάστε μία δομή για να απαντά ερωτήματα της μορφής “Είναι το y στο S?” Η δομή θα πρέπει να είναι: Γρήγορη (πιο γρήγορη από την αναζήτηση στο S). Μικρή (μικρότερη από μία ρητή αναπαράσταση). Για να πετύχουμε τα παραπάνω επιτρέπουμε μία πιθανότητα λάθους: False positives: y S αλλά αναφέρουμε ότι y S False negatives: y S αλλά αναφέρουμε ότι y S
Bloom Φίλτρα B B B B Ξεκινάμε με έναν πίνακα με m bit, γεμάτος 0. B Απεικονίζουμε κάθε στοιχείο xj στο S k φορές. Αν Hi(xj) = a, τότε B[a] = 1. 1 B Για να ελέγξουμε αν το y είναι στο S, ελέγχουμε το B στα Hi(y). Όλες οι k τιμές θα πρέπει να είναι 1. 1 B Πιθανό να έχουμε false positive; όλες οι k τιμές είναι 1, αλλά το y δεν ανήκει στο S. 1 B n στοιχεία m = cn bits k συναρτήσεις κατακερματισμού
Παράδειγμα m/n = 8 Βέλτιστο k = 8 ln 2 = 5.45... n στοιχεία m = cn bits k συναρτήσεις
Cuckoo Κατακερματισμός
Cuckoo Κατακερματισμός Pagh και Rodler (2001) Εξαιρετικά απλό: 2 πίνακες: T1 και T2 Μεγέθους r = (1+ε)n 2 συναρτήσεις: h1 και h2 Αναζήτηση: Ελέγχουμε στο T1 και T2 d . . . T1 . . . T2 t h2(x) c y h1(x) x x b a Που είναι το x? z
Cuckoo Κατακερματισμός: Ένθεση Για την ένθεση του x, καλούμε Insert(x, 1) Insert(x, i): 1. Τοποθετούμε το x στη θέση hi(x) του Ti 2. Αν το Ti[hi(x)] ήταν άδειο, επέστρεψε 3. Αν το Ti[hi(x)] περιείχε το y, Insert(y, 3–i) Παράδειγμα: d ... T1 ... T2 t c y h2(y) = h2(a) x b h1(e) = h1(a) a e h1(y) z
Cuckoo Κατακερματισμός: Ιδιότητες Πολλές καλές ιδιότητες: Η αναζήτηση και διαγραφή με 2 προσπελάσεις στη χειρότερη περίπτωση Μπορεί να γίνει παράλληλα Η ένθεση απαιτεί Ο(1) επιμερισμένο αναμενόμενο χρόνο Καλή χρήση μνήμης Όχι δυναμική δέσμευση μνήμης Πολλές επεκτάσεις με καλύτερη χρήση μνήμης Fotakis, Pagh, Sanders, Spirakis Panigrahy Dietzfelbinger, Weidling Lehman-Panigrahy Logn-wise independent hash functions Mitzenmacher’s survey ESA 2009