MIT 6.1220 — Lecture 7

Hash Functions (Part II)

Here's another way to handle key collisions.

Solution. (Open Addressing) Every key kUk \in \mathcal{U} is assigned not just one hash value in {0,1,,m1}\{0, 1, \dots, m - 1\}, but rather a permutation of {0,1,,m1}\{0, 1, \dots, m - 1\} called a probing sequence:

h:U×{0,1,,m1}{0,1,,m1}  such that  k  has probing sequence (h(k,0),h(k,1),,h(k,m1)).h: \mathcal{U} \times \{0, 1, \dots, m - 1\} \to \{0, 1, \dots, m- 1\} ~ \text{ such that } ~ k ~ \text{ has probing sequence } (h(k, 0), h(k, 1), \dots, h(k, m - 1)).

We implement our desired operations as follows:

Remark. Some CYU questions:

Claim. Suppose that every key receives an independently generated uniformly random sequence.

Then the expected number of pp we will need to check is O(11α)O\left(\frac{1}{1 - \alpha}\right), where α:=nm<1\alpha := \frac{n}{m} < 1.

Proof: Handwaving… a guess for pp succeeds with probability 1α1 - \alpha, so the EV # of tries is 11α\frac{1}{1 - \alpha}.   \blacksquare

The rigorous proof goes Eh[X]=j=1mjPrh[X=j]=j=1mPrh[Xj]j=1mαj111α\underset{h}{\mathbb{E}}[X] = \displaystyle\sum_{j = 1}^m j \cdot \underset{h}{\mathrm{Pr}}[X = j] = \displaystyle \sum_{j = 1}^m \underset{h}{\mathrm{Pr}}[X \geq j] \leq \displaystyle\sum_{j = 1}^m \alpha^{j - 1} \leq \frac{1}{1 - \alpha}, hooray.   \blacksquare

Even more formally, we need to justify Prh[Xj]αj1\underset{h}{\mathrm{Pr}}[X \geq j] \leq \alpha^{j - 1}, so we should be writing something like the following, where EiE_i is the event that the ithi^{\text{th}} probe finds an occupied slot:

Prh[Xj]=Prh[E1E2Ej1]=Prh[E1]×Prh[E2E1]××Prh[Ej1E1E2Ej2].\underset{h}{\mathrm{Pr}}[X \geq j] = \underset{h}{\mathrm{Pr}}[E_1 \wedge E_2 \wedge \dots \wedge E_{j - 1}] = \underset{h}{\mathrm{Pr}}[E_1] \times \underset{h}{\mathrm{Pr}}[E_2 \mid E_1] \times \dots \times \underset{h}{\mathrm{Pr}}[E_{j - 1} \mid E_1 \wedge E_2 \wedge \dots \wedge E_{j - 2}].

And the th\ell^{\text{th}} term in this product is upper-bounded by n+1m+1nm=α\frac{n - \ell + 1}{m - \ell + 1} \leq \frac{n}{m} = \alpha, as desired.   \blacksquare

Generating probing sequences uniformly at random is hard, so in practice, we implement like so.

Solution. (Probing Methods) Pick any two hash functions h1,h2:U{0,1,,m1}h_1, h_2: \mathcal{U} \to \{0, 1, \dots, m - 1\}. We can use:

Now for something new. Let's try to implement…

Problem. (Static Dictionaries & Perfect Hashing) We are given {(k1,v1),,(kn,vn)}\{(k_1, v_1), \dots, (k_n, v_n)\} up front, after which point only Search(k)\textsc{Search}(k) may be called. We would like the following:

Expected Pre-Processing Time: O(n)    Space: O(n)    Search Operations: O(1) always\text{Expected Pre-Processing Time: } O(n) ~~ \mid ~~ \text{Space: } O(n) ~~ \mid ~~ \text{Search Operations: } O(1) \text{ always}

In particular, we require perfect hashing: no collisions occur at all!

Here's a naive solution that passes all constraints except the space requirement.

Solution. (Suboptimal-Space Solution) Consider a universal hash family H\mathcal{H}, and take mn2m \geq n^2.

Then pick hHh \in \mathcal{H}, and use kih(ki)k_i \mapsto h(k_i). If the first hHh \in \mathcal{H} fails, pick another hHh \sim \mathcal{H} until success.

Proof: This works in expected O(n)O(n) pre-processing time because PrhH[no collisions]12\underset{h \sim \mathcal{H}}{\mathrm{Pr}}[\text{no collisions}] \geq \frac{1}{2} by Union Bound—try it yourself! (When does universality of H\mathcal{H} get used?)   \blacksquare

Here's the smart solution by Fredman-Komlos-Szemeredi (1984) that passes the space requirement.

Solution. (Optimal-Space Solution) Sample a hash function h1H1h_1 \in \mathcal{H}_1 that goes h1:U{0,1,,n1}h_1: \mathcal{U} \to \{0, 1, \dots, n - 1\}.

Our data structure is then a two-dimensional array: nn buckets, the th\ell^{\text{th}} of which has N2N_{\ell}^2 slots to hash into.

Proof: It's easy to see that this has O(1)O(1) search time, and that we only need O(n)O(n) pre-processing time once h1h_1 is chosen.

The hard part is achieving O(n)O(n) space. If we choose h1h_1 unluckily, we won't actually get O(n)O(n) space! However,

Claim.     PrhH1[(=0n1N2)>4n]<12.\textbf{Claim.} ~~~~~ \underset{h \sim \mathcal{H}_1}{\mathrm{Pr}} \left [ \left(\sum_{\ell = 0}^{n - 1} N_{\ell}^2\right) > 4n \right ] < \dfrac{1}{2}.

To prove this, note that by Markov's inequality, it suffices to show EhH1[=0n1N2]<2n\underset{h \sim \mathcal{H}_1}{\mathbb{E}}\left [ \sum_{\ell = 0}^{n - 1} N_{\ell}^2 \right ] < 2n. This takes some clever work:

EhH1[=0n1N2]= EhH1[=0n1(N+jj1[h(kj)=h(kj)=])]= EhH1[=0n1N]+EhH1[=0n1jj1[h(kj)=h(kj)=]]= n+jj(PrhH1[h(kj)=h(kj)]) n+n(n1)n<2n.\begin{align*}\underset{h \sim \mathcal{H}_1}{\mathbb{E}} \left [ \sum_{\ell = 0}^{n - 1} N_{\ell}^2 \right ] = \ & \underset{h \sim \mathcal{H}_1}{\mathbb{E}} \left [ \sum_{\ell = 0}^{n - 1} \left ( N_{\ell} + \sum_{j \neq j'} \mathds{1}\left [ h(k_j) = h(k_{j'}) = \ell \right ] \right ) \right ] \\ = \ & \underset{h \sim \mathcal{H}_1}{\mathbb{E}}\left [ \sum_{\ell = 0}^{n - 1} N_{\ell} \right ] + \underset{h \sim \mathcal{H}_1}{\mathbb{E}} \left [ \sum_{\ell = 0}^{n - 1} \sum_{j \neq j'} \mathds{1}\left [ h(k_j) = h(k_{j'}) = \ell \right ] \right ] \\ = \ & n + \sum_{j \neq j'} \left(\underset{h \sim \mathcal{H}_1}{\mathrm{Pr}}[h(k_j) = h(k_{j'})] \right) \\ \leq \ & n + \frac{n(n - 1)}{n} < 2n.\end{align*}

Thus, we can guarantee O(n)O(n) space in expected O(n)O(n) time by repeatedly resampling h1h_1 until the space is less than 4n4n.   \blacksquare