对于我实现minhashing算法,我需要进行许多随机排列的整数,这将通过使用随机散列函数(尽可能多)进行模拟。目前我使用以下形式的哈希函数:
h(x) = (a*x + b) % c
其中a和b是随机生成的数字,c是大于b的最高值的素数。无论如何,代码运行方式太慢并且在合理的运行时间内不可能使用超过15个这样的哈希函数。任何人都可以推荐在Python中使用随机散列函数进行整数的其他方法吗?在其他帖子中,我遇到了使用按位改组和 XOR 操作的建议,但我还没有完全理解应该如何实现这样的事情(I&#39 ;相对较新的Python)。
答案 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
如果需要,您可以尝试使用其中的变体。如果您将b
和d
设置为零并将中间16
更改为13
,那么您将获得MurmurHash3终结器构造,该构造足够接近理想状态大多数用途,只要您选择好a
和c
(遗憾的是,它们不能只是随机的)。