Math 有意散列冲突
我正在尝试编写一些代码来进行“模糊哈希”。也就是说:我希望将多个输入散列到同一个输出中,以便快速、轻松地执行搜索等操作。如果A散列为1,C散列为1,那么我很容易发现A与C是等价的 设计这样一个散列函数似乎很难,所以我想知道是否有人有CMPH或GPERF的经验,并能指导我创建一个函数,从而生成这个散列函数 提前谢谢! 斯特凡 @本 在本例中,矩阵是布尔数,但我可以轻松地将它们打包为64位整数。输入中的旋转、平移等是不相关的,需要剔除。因此:Math 有意散列冲突,math,hash,Math,Hash,我正在尝试编写一些代码来进行“模糊哈希”。也就是说:我希望将多个输入散列到同一个输出中,以便快速、轻松地执行搜索等操作。如果A散列为1,C散列为1,那么我很容易发现A与C是等价的 设计这样一个散列函数似乎很难,所以我想知道是否有人有CMPH或GPERF的经验,并能指导我创建一个函数,从而生成这个散列函数 提前谢谢! 斯特凡 @本 在本例中,矩阵是布尔数,但我可以轻松地将它们打包为64位整数。输入中的旋转、平移等是不相关的,需要剔除。因此: 000 111 000 相当于 111 000 000
000
111
000
相当于
111
000
000
及
(简化)
@基诺皮科
到目前为止,我的最佳选择是确定某种“规范化”表示和设计代码,当转换达到这种表示时,这些代码将终止(例如……将所有位打包到底部)。然而,这是缓慢的,我正在寻找一个更好的方式。我的数据集很大
@杰森
这两个值不会散列为相同的值
000
010
000
000
011
000
您可以查看MinHash,这是一种概率方法,适用于项目由集合成员定义的情况 我知道您想设计自己的哈希函数,但也许这就是您想要的。让我们举个例子,说明您可能想要的是什么
- 它会散列具有相同值的不同但相似的键
- 这将允许断言实体A(比如“麦当劳”)可能与实体C(“麦克唐纳”)相同
这些是完美的、可选的最简单的散列函数的实现。这种功能允许您防止碰撞。这里不需要什么(我想)散列必须有多无冲突(就误报而言) 那么:
/**
*
* @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
/**
*
*@markbolusmjak作者
*/
公共类矩阵测试{
LinkedList随机矩阵(整数大小){
LinkedList行=新建LinkedList();
对于(int i=0;i,在你的例子中,矩阵、旋转和平移等似乎涵盖了几乎所有的内容,因此你的算法会说所有矩阵都是相等的。你能给出一个不同矩阵集的例子吗
此外,看起来你正在做一些类似于图像搜索的事情——识别相同但可能缩放、旋转(可能任意)、翻转等图像的算法。我对这些东西了解不多,但也许你可以从该研究领域获得灵感
此外,我似乎还记得Vector Calc中关于特征值的一些内容,您可能会发现这些内容很有用。cmph实现的chd算法可以进行k-完美散列,我认为这正是您想要的:
不过,最好知道“大量投入”是什么意思。如果你说的是数十万条,有更简单的解决方案。如果你有数亿条,那么chd可能是你最好的选择。如果你想在摘要上执行搜索,也许你应该寻找索引算法,而不是散列函数。你在散列什么类型的数据这将是一个典型的搜索?这取决于你的数据。到目前为止你有什么?你在寻找类似Bloom过滤器的东西吗?
/**
*
* @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