2009-11-05 84 views
3

我想寫一些代碼,將做「模糊散列」。那就是:我需要幾個輸入來哈希到相同的輸出,以便我可以快速輕鬆地進行搜索等。如果A散列爲1,C散列爲1,那麼發現A相當於C將是微不足道的。故意散列衝突

設計這樣的哈希函數似乎很難,所以我想知道是否有人有CMPH經驗或GPERF並可以引導我創建一個可以產生這個散列函數的函數。

在此先感謝! 斯特凡

@Ben

在這種情況下,布爾型的矩陣,但我可以很容易收拾他們進入64個整數。輸入中的旋轉,翻譯等無關緊要,需要清理。因此:

000 
111 
000 

是相當於

111 
000 
000 

001 
001 
001 

(簡化)

@Kinopiko

我最好的選擇迄今爲止是要確定一些所以rt「典型」表示和設計代碼,當變換達到這樣的表示時(例如......封裝底部的所有位)終止。但這很慢,我正在尋找更好的方法。我的數據集很大。

@Jason

這兩個不會哈希到相同的值。

000 
010 
000 

000 
011 
000 
+0

如果您正在尋找對摘要進行搜索,也許您應該尋找索引算法而不是散列函數。什麼類型的數據是你散列的,什麼是典型的搜索? –

+0

這取決於你的數據。到目前爲止,你有什麼? – 2009-11-05 16:20:28

+0

你在尋找類似布盧姆過濾器的東西嗎? http://en.wikipedia.org/wiki/Bloom_filter – Hasturkun

回答

2

讓我們SOUNDEX,作爲說明你可能會尋找...

  • 它哈希不同,但類似的按鍵具有相同值什麼
  • 它將允許斷言實體A (比方說, 「麥當勞」)是可能相同實體C( 「MacDonnel」)SOUNDEX的

一個特徵是它工作得很好(名稱,特定姓氏),並利用規則與[英語語言的發音相關聯,並通過擴展許多相同來源的語言]相關聯。

你的哈希(或者它幾乎是一種索引的形式?)算法只有在存在(或可被發現)一組[相對簡單的]規則來表示考慮的項目/記錄的「相同性」時纔會成功。例如,如果底層數據庫屬於汽車,並且「相同性」的標準是規模和一般性能的標準,則哈希算法應該基於記錄的屬性,如價格(轉換爲範圍),數量氣瓶,門的數量,也許估計的汽油里程(也轉換爲一個範圍)。

簡而言之,我希望上面的例子說明需要將算法修改爲我們希望與散列值標識(或鄰近...因此看起來越來越像索引...)相關聯的語義。以及這些語義在項目的可用數據中表示。

項目在許多維度上可能相似。定義這些維度是如何將這個維度上的屬性用作散列函數的關鍵字是一個問題。

在CMPH和的gperf ...
這些都是完美的,可選mimimal,散列函數的實現。這種功能可以讓你防止衝突。這裏不需要什麼(我認爲)

1

您可以檢查出最小哈希,這對其中項目是由集成員定義的情況下,probablistic方法。

我知道你想設計自己的散列函數,但也許這就是你要找的。

0

散列必須是無碰撞(根據誤報)?

什麼:

  1. 排序號碼,然後運行該序列標準的哈希?
  2. 或者,將每個行/列視爲一個集合,並使用加法散列每個內容。然後對這些結果進行排序並在排序的總和中運行標準散列?
  3. 或者1的產品和2

例如,在這裏它是Java(快速&髒,但你的想法):

進口的java.util。*;

/** 
* 
* @author Mark Bolusmjak 
*/ 
public class MatrixTest { 


    LinkedList<LinkedList<Integer>> randomMatrix(int size){ 
    LinkedList<LinkedList<Integer>> rows = new LinkedList<LinkedList<Integer>>(); 
    for (int i=0; i<size; i++){ 
     LinkedList<Integer> newRow = new LinkedList<Integer>(); 
     for (int j=0; j<size; j++){ 
     newRow.add((int)(5*Math.random())); 
     } 
     rows.add(newRow); 
    } 
    return rows; 
    } 

    LinkedList<LinkedList<Integer>> trans(LinkedList<LinkedList<Integer>> m){ 
    if (Math.random()<0.5){ //column translation 
     for (LinkedList<Integer> integers : m) { 
     integers.addFirst(integers.removeLast()); 
     } 
    } else { //row translation 
     m.addFirst(m.removeLast()); 
    } 
    return m; 
    } 

    LinkedList<LinkedList<Integer>> flipDiagonal(LinkedList<LinkedList<Integer>> m){ 
    LinkedList<LinkedList<Integer>> flipped = new LinkedList<LinkedList<Integer>>(); 
    for (int i=0; i<m.size(); i++){ 
     flipped.add(new LinkedList<Integer>()); 
    } 

    for (LinkedList<Integer> mRows : m) { 
     Iterator<Integer> listIterator = mRows.iterator(); 
     for (LinkedList<Integer> flippedRows : flipped) { 
     flippedRows.add(listIterator.next()); 
     } 
    } 
    return flipped; 
    } 


    public static void main(String[] args) { 
    MatrixTest mt = new MatrixTest(); 
    LinkedList<LinkedList<Integer>> m = mt.randomMatrix(4); 
    mt.display(m); 

    System.out.println(mt.hash1(m)); 
    System.out.println(mt.hash2(m)); 

    m = mt.trans(m); 
    mt.display(m); 
    System.out.println(mt.hash1(m)); 
    System.out.println(mt.hash2(m)); 

    m = mt.flipDiagonal(m); 
    mt.display(m); 
    System.out.println(mt.hash1(m)); 
    System.out.println(mt.hash2(m)); 

    m = mt.trans(m); 
    mt.display(m); 
    System.out.println(mt.hash1(m)); 
    System.out.println(mt.hash2(m)); 

    m = mt.flipDiagonal(m); 
    mt.display(m); 
    System.out.println(mt.hash1(m)); 
    System.out.println(mt.hash2(m)); 

    } 


    private void display(LinkedList<LinkedList<Integer>> m){ 
    for (LinkedList<Integer> integers : m) { 
     System.out.println(integers); 
    } 
    System.out.println(""); 
    } 

    int hash1(LinkedList<LinkedList<Integer>> m){ 
    ArrayList<Integer> sorted = new ArrayList<Integer>(); 

    for (LinkedList<Integer> integers : m) { 
     for (Integer integer : integers) { 
     sorted.add(integer); 
     } 
    } 
    Collections.sort(sorted); 
    return sorted.hashCode(); 
    } 

    int hash2(LinkedList<LinkedList<Integer>> m){ 
    List<Integer> rowColumnHashes = new ArrayList<Integer>(); 
    for (LinkedList<Integer> row : m) { 
     int hash = 0; 
     for (Integer integer : row) { 
     hash += integer; 
     } 
     rowColumnHashes.add(hash); 
    } 

    m = flipDiagonal(m); 
    for (LinkedList<Integer> row : m) { 
     int hash = 0; 
     for (Integer integer : row) { 
     hash += integer; 
     } 
     rowColumnHashes.add(hash); 
    } 

    Collections.sort(rowColumnHashes); 
    return rowColumnHashes.hashCode(); 
    } 



} // end of class 
0

在你的榜樣矩陣,旋轉和平移等在我看來,以覆蓋幾乎所有這樣你的算法會說,所有矩陣都是平等的。你能給出一組不同的矩陣的例子嗎?

此外,它看起來像你正在做一些類似的圖像搜索 - 識別圖像相同,但可能縮放,旋轉(可能任意),翻轉等算法。我不太瞭解任何這東西,但也許你可以看看那個研究領域的靈感。

另外,我似乎記得Vector Calc的一些關於特徵值的東西,您可能會發現它很有用。

0

通過CMPH可以做K-完美的哈希,我認爲它實現的冠心病算法正是你在找什麼:

http://cmph.sourceforge.net/chd.html

然而,這將是更好地瞭解你的意思是什麼「大量輸入」。如果您正在談論數十萬條條目,則有更直接的解決方案。如果你有數億人,那麼chd可能是你最好的選擇。