在Python中为整数创建不同的哈希函数?

时间:2016-10-17 10:38:00

标签: python-2.7 random hash integer minhash

对于我实现minhashing算法,我需要进行许多随机排列的整数,这将通过使用随机散列函数(尽可能多)进行模拟。目前我使用以下形式的哈希函数:

h(x) = (a*x + b) % c

其中a和b是随机生成的数字,c是大于b的最高值的素数。无论如何,代码运行方式太慢并且在合理的运行时间内不可能使用超过15个这样的哈希函数。任何人都可以推荐在Python中使用随机散列函数进行整数的其他方法吗?在其他帖子中,我遇到了使用按位改组 XOR 操作的建议,但我还没有完全理解应该如何实现这样的事情(I&#39 ;相对较新的Python)。

1 个答案:

答案 0 :(得分:0)

my answer借用类似问题,并快速浏览Python文档以尝试猜测有效语法......

你发布的代码是正常的,但它可能需要以比最佳方式更长的精度计算,并且它涉及一个分区,这也会使事情变慢。

为了加快速度,你可以用2的幂来修复c,你可以使用二进制&(和)而不是模数,这样就可以了:

h(x) = (a * x + b) & ((1 << 32) - 1)

与:

相同
h(x) = (a * x + b) & (4294967296 - 1)

与:

相同
h(x) = (a * x + b) % 4294967296

并且您必须确保a是一个奇数(当c是2的幂时,这就是使它与c共同所需的全部内容)。此示例将输出范围限制为32位整数。您可以根据需要更改它。我不知道Python的限制是什么。

如果你想要更多的参数化,或者你发现结果不够“随机”(它会很快失败统计测试,但这通常无关紧要),那么你可以添加更多的操作;但是你不能添加更多那些操作,因为添加和乘法链总是简化为只有一对加法和乘法,所以额外的操作不会修复任何东西。

你可以做的是使用bit shifts and exclusive-or来打破线性;像这样:

def h(x):
  x = x ^ (x >> 16)
  x = (a * x + b) & ((1 << 32) - 1)
  x = x ^ (x >> 16)
  x = (c * x + d) & ((1 << 32) - 1)
  x = x ^ (x >> 16)
  return x

如果需要,您可以尝试使用其中的变体。如果您将bd设置为零并将中间16更改为13,那么您将获得MurmurHash3终结器构造,该构造足够接近理想状态大多数用途,只要您选择好ac(遗憾的是,它们不能只是随机的)。