不發生沖突的Hash函數,你信喵?


不發生沖突的Hash函數,你信喵?

  不發生沖突的Hash函數,你信喵?不管你信不信,反正我第一次看到時候是不信的喵~

  其實人家有個專門的名字叫作“完美哈希函數”——就是完全不會沖突的哈希函數。

  我想大家每次Hash-table的時候一定很討厭沖突的存在,這時候你肯定是會想盡辦法去避免過多沖突的出現。依我個人的經驗,到最后很可能就是直接借用別人使用的hash函數了。

 

  要自己設計一個hash函數容易,但推導或證明其發生沖突的概率滿足要求,這個就比較麻煩了喵~更何況這里是要求得到一個完全不沖突的函數。這簡直是想都不敢想的事情了喵(我第一次看見完美hash函數時就是這種感覺)

 

  喵~說了這么多沒營養的話喵~來點實用的喵~

  先來幾個概念

哈希函數(Hash Function

  任意函數h(x)都可以說哈希函數,一般來說,一個良好的哈希函數可以盡量避免重復。x的集合是參數域,h(x)的集合是值域。

完美哈希函數(Perfect Hash Function

  完美哈希函數,就是完全不會沖突的哈希函數,這要求函數的值域不小於參數域

最小完美哈希函數(Minimal Perfect Hash Function

  最小完美哈希函數,就是指函數的值域和參數域的大小完全相等,一個也不多

保序最小完美哈希函數(Order Preserving Minimal Perfect Hash Function

  保序的意思就是指這個哈希之后順序是不變的,同時還能滿足其他兩個條件。可以這樣理解原來在前面的元素,哈希之后它也在前面。就和排序的穩定性是一個意思哦喵~

 

分析

  對於一個給定的數據集,我們可以構造出一個保序最小完美哈希函數(OPMPHF

  我們定義該函數為h(t):+n:在n的模域下進行加法)

  

  其中函數g(x)是需要我們去構造的,另兩個函數h1(t)與h2(t)就是一般的哈希函數了。

  現在我們的目的就是去構造出一個函數g(x)使得h(t)成為一個保序最小完美哈希函數了喵~

  一種形像的理解就是:

    第0個元素t0經過h(t)后輸出就為0

    第1個元素t1經過h(t)后輸出就為1

    第x個元素tx經過h(t)后輸出就為x

  那么具體怎喵構造這個函數呢?

  看上面那個式子,我們對於每個元素tx,我們已經通過兩個哈希函數得到了它的兩個哈希值,然后我們建一個圖:
  對於有n個元素的序列,這個圖里有n條邊分別對應每個數據。邊權值對應該元素在原序列中的序號,邊的兩個端點為該元素經過兩個哈希函數之后的值。

即E(h1(tx), h2(tx)) = x

 

  正如大家所看到的一樣,如果我們給每個點標記一個權值g(x),對於邊E(a,b)

  我們要求的就是使得g(x)對於所有邊,滿足g(a) +n g(b) == E(a,b)

  對於一個一般圖點標號問題來說,確實比較麻煩,但如果這個圖有一個很好性質:無環。那么標號就變得異常的簡單了喵~

  所以如果你不幸建個了一個有環圖,那就重新選兩個哈希函數再建一次圖,直到建成無環圖為止喵~這一句話看上去不怎喵靠譜吧喵~要建多少次才會出現無環圖呢?我也覺得不怎喵靠譜的樣子喵,可人家證明這樣建圖是可以接受的。

  然后剩下的問題就比較簡單了喵~遍歷圖中所有頂點,當遍歷到未標號頂點時,就以該點為根遍歷該子樹,並標號。(無環圖就可以看作森林了喵~)

 

算法綜述(生成一個完美哈希函數):

  1、隨機選兩個哈希函數

  2、生成一個圖G=(V,E)

  3、判環與計算映射函數g(x)

  4、如果未得成功計算出g(x)(有環存在且破壞了g(x)函數),則重新執行該算法。

 

 

生成無環圖的期望次數

 

參考:

  《深入搜索引擎》(Managing Gigabytes即MG)

  最小完美哈希函數簡介

  “萬里挑一”的最小完美哈希函數

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM