散列数字向量的方法?

时间:2008-11-12 06:24:06

标签: algorithm math hash vector

是否有任何已知的哈希算法输入int的向量并输出一个与内积相似的int?

换句话说,我正在考虑在C ++中可能看起来像这样的哈希算法:

// For simplicity, I'm not worrying about overflow, and assuming |v| < 7.
int HashVector(const vector<int>& v) {
  const int N = kSomethingBig;
  const int w[] = {234, 739, 934, 23, 828, 194};  // Carefully chosen constants.
  int result = 0;
  for (int i = 0; i < v.size(); ++i) result = (result + w[i] * v[i]) % N;
  return result;
}

我对此感兴趣,因为我正在撰写一篇关于算法的论文,该算法将受益于之前关于类似哈希的任何工作。特别是,如果知道像这样的散列算法的碰撞属性,那将会很棒。

我感兴趣的算法会散列整数向量,但浮点向量的东西也会很酷。

澄清

哈希旨在用于哈希表中以进行快速键/值查找。这里没有安全问题。

所需的答案类似于一组常量,这些常量对于像这样的散列特别有用 - 类似于乘法器和模数,它比其他常量数字生成器更好。

例如,已知线性同余伪随机发生器的一些常数选择可提供最佳周期长度并具有易于计算的模数。也许有人做过研究,表明在向量散列中有一组乘法常数和模数常量可以减少邻近整数向量之间碰撞的几率。

4 个答案:

答案 0 :(得分:3)

我做了一些(未发布的,实用的)实验,测试了各种字符串哈希算法。 (事实证明,Java的Strings默认哈希函数很糟糕。)

简单的实验是对英语词典进行哈希,并比较算法A与算法B的碰撞次数。

您可以构建一个类似的实验:随机生成长度为7或更短的$ BIG_NUMBER个可能的向量。在算法A上哈希,在算法B上哈希,然后比较冲突的数量和严重程度。

在你能够做到这一点之后,你可以使用模拟退火或类似的技术找到适合你的“魔术数字”。在我的工作中,对于给定的感兴趣的词汇表和严格限制的散列大小,我们能够通过改变“魔术数字”使通用算法适用于几种人类语言。

答案 1 :(得分:2)

根据常量的大小,我不得不说输入向量中的混沌程度会对结果产生影响。但是,对您的帖子进行快速定性分析会表明您有一个良好的开端:

  • 您的输入成倍增加,因此每次迭代增加相似输入值之间的分离程度(例如,65 + 66远小于65 * 66),这很好。
  • 这是确定性的,除非你的向量应该被认为是一个集合而不是一个序列。为清楚起见,v = {23,30,37}是否应与v = {30,23,37}不同?
  • 分布的均匀性将根据v中输入值的范围和混乱而变化。但是,对于广义整数散列算法也是如此。

出于好奇,为什么不使用现有的哈希算法进行整数并对结果进行一些有趣的数学运算呢?

答案 2 :(得分:1)

Python用于以这种方式散列元组(source):

class tuple:
    def __hash__(self):
        value = 0x345678
        for item in self:
            value = c_mul(1000003, value) ^ hash(item)
        value = value ^ len(self)
        if value == -1:
            value = -2
        return value

在您的情况下,item将始终是一个整数,它使用此算法:

class int:
    def __hash__(self):
        value = self
        if value == -1:
            value == -2
        return value

这确实与内在产品无关,但是......所以也许它没什么帮助。

答案 3 :(得分:0)

虽然我可能完全误解了你,但也许将一个矢量视为一个字节流并在其上做一些知道哈希是个好主意,即SHA1MD5

只是为了澄清,已知这些哈希具有良好的哈希属性,我相信没有理由重新发明自行车并实现新的哈希。另一种可能性是使用已知的CRC算法。