區域性敏感雜湊 原始LSH C 實現

2021-07-09 14:53:35 字數 3935 閱讀 5005

之前專案中用到lsh演算法來做特徵檢索,對lsh演算法很好奇,最近看了lsh的**,依照自己的理解,初步寫了lsh**。測試效果不是特別理想,引數的選擇也基本靠嘗試,姑且先把**放上來,之後再改進吧(2016.01.24)
#include 

#include

#include

#include

using

namespace

std;

using

namespace cv;

/* 演算法思路

1. 確定引數 k(bitcount)、以及雜湊表個數l; (這裡設定固定值吧 不知道怎麼求最優質)

2. 生成一級雜湊函式;

3. 資料一級雜湊到bucket

4. 壓縮bucket.用二級雜湊函式把一級的bucket雜湊到二級雜湊表中(需要確定二級雜湊表的容量m);

*/const

int k = 700; //或者用展開成01串的特徵的長度來計算k

const

int l = 10;

const

int maxvalue = 255;//特徵為uchar型別

const

int m = 100; //二級雜湊表的容量

struct bucket

;struct table

;class mylsh

;~mylsh(){};

public:

int init( int m, int l, float ratio,int featuredims );

int train(mat featurtes);

int search(mat feature,int& name, int& dist);//輸入查詢特徵 返回特徵名 和距離

private:

//int creathashfamily();

int gethashfun_level1();//生成一級雜湊函式

int hash_level1( mat feature,int hashfunid,vector

char>& value );//輸入一級雜湊函式、原始特徵,得到原始特徵的對映value;這裡用的演算法避免了把數字展開成01串

int hash_level2( vector

char> value, int& bucketid );//輸入一級雜湊對映後的value,計算二級雜湊對映後的value(也就是二級雜湊表中的桶的id)

int calcdist( mat feature0, mat feature1,int& dist);

private:

int m_k;//隨機選取的位數

int m_d;//轉換成01串後的特徵維數;當然得注意,實際並沒有顯式的轉成01字串,m_d只是用到而已;

int m_l;//一級雜湊表的個數

int m_m;//二級雜湊表的容量

int m_featuredims;//影象特徵維數

vector

> m_hashfun_level1;//現在沒用到

vector

>> m_hashfun_level1subset;

vector

m_hashfun_level2;

table m_table;

//vector> m_hashfamily;

};#include "mylsh.h"

#include

int mylsh::init( int m, int l, float ratio,int featuredims)

for ( i = 0; i //初始化二級雜湊函式

}return1;}

int mylsh::train(mat featurtes)

nums = featurtes.rows;

for ( i = 0; i < nums; i++ )//every img

//二級hash

ret = hash_level2(value,bucketid);

if ( 0 == ret )

//把特徵以及特徵對應名稱存到桶中

m_table.bucket[bucketid].features.push_back(feature.clone());

m_table.bucket[bucketid].names.push_back(i);

m_table.bucket[bucketid].bucketsize = int(m_table.bucket[bucketid].names.size());}}

return1;}

//生成一級hash函式

int mylsh::gethashfun_level1()

}//m_hashfun_level1.push_back(temp);

}return1;}

int mylsh::hash_level1( mat feature,int hashfunid,vector

char>& value )

else

while ( one_nums > 0 )

while ( zero_nums > 0 )}}

return1;}

int mylsh::hash_level2( vector

char> value, int& bucketid )

bucketid = val % m_m;

return1;}

int mylsh::search(mat feature,int& name, int& dist)

dist = -1;

name = -1;

int ret,i,j,bucketid;

vector

char> value;

vector

buckets;

vector

tempfeature;

vector

tempname;

float mindist = 1000000;

for ( i = 0; i < m_l; i++ )

//二級hash

ret = hash_level2(value,bucketid);

if ( 0 == ret )

buckets.push_back(bucketid);

}//在buckets內的所有特徵中尋找距離最小的點 bruteforce

cout

<<"候選桶的數量為:"

<<(int)buckets.size()tempname = m_table.bucket[buckets[i]].names;

cout

<<"該候選桶內含點的數量為:"

<<(int)tempfeature.size()if ( dist < mindist )

}tempfeature.clear();

tempname.clear();

}dist = mindist;

return1;}

int mylsh::calcdist(mat feature0, mat feature1,int&dist)

dist = 0;

int i;

int dims = feature0.cols;

for ( i = 0; i abs(feature0.at(0,i) - feature1.at(0,i));

}return1;}

#include "mylsh.h"

#include

int main()

tempfeature.at(0,j) -= 10;

ret = lsh.search(tempfeature,name,dist);

if ( name == i )

}cout

<<"accuracy:"

1;}

區域性敏感雜湊LSH

參考資料 簡單介紹 在茫茫人海中發現相似的你 區域性敏感雜湊 lsh 基本思想 區域性敏感雜湊的基本思想類似於一種空間域轉換思想,lsh演算法基於乙個假設,如果兩個文字在原有的資料空間是相似的,那麼分別經過雜湊函式轉換以後的它們也具有很高的相似度 相反,如果它們本身是不相似的,那麼經過轉換後它們應仍...

區域性敏感雜湊演算法

該演算法是一種衡量文字相似度的演算法,下面介紹一下這個演算法的主要思想。假設我們有三段文字 1,我愛你中國。2,我愛北京天安門。3,我愛吃蘋果 一,分詞,形成如下矩陣 文字 1 文字 2 文字 3 我 1 1 1 愛 1 1 1 你 1 0 0 中國 1 0 0 北京 0 1 0 天安門 0 1 0...

區域性敏感雜湊之分層法與雜湊碼法

學到現在越來越感覺計算機網路 作業系統的重要性,組成原理到沒感覺出來,求推薦資料,我想要的是描述性解釋,教材不是我想要的,謝謝!感覺自己的知識很老舊,在沒有出國也沒去高水平大學的條件下,只能通過網路學習了,感謝。在檢索技術中,索引一直需要研究的核心技術。當下,索引技術主要分為三類 基於樹的索引技術 ...