最小完美哈希函数简介
http://www.yankay.com/introduction-to-opmphf/
什么是保序最小完美哈希函數
我曾經花了很多腦筋來找一個很好很完美的哈希算法,但都沒有想到,最近看到了,掩不住一陣激動分享下。最小完美哈希函數是什么,要從定義說起,這個名字很長,一步步解釋。
算法實現
該算法的實現方法是這樣的。先構造兩個普通的哈希函數h1(x)和h2(x),還有一個用數組實現的函數g(x)。使得?h(x)=g(h1(x))+g(h2(x))modn?,其中n是參數的總個數,H(x)就是最終的有序最小完美哈希函數了。
以上是定義,說不清楚,舉個例子就明白了。取一個n為12的數據集。
首先構造這三個函數:
函數h1和h2:
| x | h1函數 | h2函數 |
| jezebel | 5 | 9 |
| jezer | 5 | 7 |
| ... | ... | ... |
函數g:
| x | g函數 |
| 5 | 0 |
| 7 | 1 |
| 9 | 0 |
| ... | ... |
| x | h計算步驟 | h值 |
| jezebel | g(5)+g(9) | 0 |
| jezer | g(5)+g(7) | 1 |
| ... | ... | ... |
這里的h就可以最小完美哈希函數算出的值了,很神奇,不是嗎?
大致的流程走了一遍,現在最最關鍵的是h1(x),h2(x)和g(x)是怎么得來的。
h1(x)和h2(x)比較簡單,可以使用一個很簡便的方法獲得:先定義一個權重數組w[i],這個數據是一系列隨機的數。?h1=(t[1]?w[1]+t[2]?w[2]+...+t[i]?w[i])modm?。其中t[i]指得的字符串x的第i個字符,m值得的函數的值域。只要更換一個權重數組,就可以重新構造一個新函數。有很多方法可以構造這兩個函數。
g(x)的獲得就比較復雜。可以是湊出來的。就如同上面的例子,因為?g(5)+g(9)mod12=0?,?g(5)+g(7)mod12=1?。所以我們可以湊出?g(5)=0,g(7)=1,g(9)=0?這樣就可以滿足上面的兩個條件了。需要一個數組來存儲函數g的結果,當然湊也不能瞎湊,是有方法的,下面專門講湊的步驟。
算法函數生成
首先隨意設定一個數,比如是7,設為?g(7)=1?,因為我們已知?g(5)+g(7)mod12=1?,所以可以推論出?g(5)=0。因為?g(5)+g(9)mod12=0?,所以可以推出?g(9)=0?,以此類推就可以了。但要注意的是千萬不能重復設定一個數兩次,這樣就會形成一個環,永遠也推不完。所以遇到已經推算過的數的時候,要檢測環的存在。這樣下去,就可以猜出全部的值了。
現在需要的就是分析這個湊的過程的運行效率問題。這個就要涉及到h1,h2這兩個函數的值域大小,如果越大,越容易湊出一個g函數,但是g函數的參數域就會比較大,存儲這個g函數的數據就需要占用更多的空間。相反如果值域越小,在湊的時候就非常容易出現環,需要更長的時間才能湊出這個g函數。
怎么辦呢?
我們可以使用3個的h函數來降低形成環的可能,就是這樣?h(x)=g(h1(x))+g(h2(x))+g(h3(x))modn?,這樣雖然推理g函數的過程會復雜一些,但是很有效,有實驗分析表明,當h函數的值域大約參數域的1.23倍的時候,這個g函數的創建嘗試次數是常數。
至此,這個算法介紹完了。這個方法是從《Managing Gigabytes》這本書看到的,這里的講述更淺顯一些。
結語
這個哈希函數是一個靜態Hash函數,可以非常有效的縮減索引所需要的空間。《Managing Gigabytes》一書中有一個對比,如果直接使用字符串數組,100萬個術語需要28MB的空間,而是要這樣的哈希函數,可以縮減到12MB。要知道索引小一點,磁盤就能讀得快一點,查詢就能快一點。所以這個哈希函數對于提高性能是非常給力的。
但是他是靜態的,就意味著事前必須知道需要哈希哪些數據。同時生成的算法比較復雜,需要很長的時間來建立索引。沒有辦法實時添加更新。給他的應用范圍提了個極大的限制。竊以為輸入法的詞庫,數據倉庫的查詢索引,還有一些不需要更新且對性能有要求的場景,這個算法是適用的。
總結
以上是生活随笔為你收集整理的最小完美哈希函数简介的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: vim ps
- 下一篇: 由浅入深了解Thrift(三)——Thr