C++ 正在查找哈希函数/Ordered Int/to/Shuffled Int/

C++ 正在查找哈希函数/Ordered Int/to/Shuffled Int/,c++,algorithm,hash,C++,Algorithm,Hash,我在寻找常数时间算法,可以将一个有序的整数索引值变成一个随机散列索引。如果是可逆的就好了。我需要哈希键对于每个索引都是唯一的。我知道这可以通过在一个大文件中查找表来完成。也就是说,创建所有整数的有序集,然后随机洗牌,并以随机顺序写入文件。然后,您可以根据需要将它们读回。但这需要搜索一个大文件。我想知道是否有一种简单的方法可以根据需要使用伪随机生成器来创建序列 路旁 线性反馈移位寄存器的类型看起来是正确的。我刚试过,但它产生重复和洞 问候 David Allan Finch假设您的目标是在整个范围

我在寻找常数时间算法,可以将一个有序的整数索引值变成一个随机散列索引。如果是可逆的就好了。我需要哈希键对于每个索引都是唯一的。我知道这可以通过在一个大文件中查找表来完成。也就是说,创建所有整数的有序集,然后随机洗牌,并以随机顺序写入文件。然后,您可以根据需要将它们读回。但这需要搜索一个大文件。我想知道是否有一种简单的方法可以根据需要使用伪随机生成器来创建序列

路旁 线性反馈移位寄存器的类型看起来是正确的。我刚试过,但它产生重复和洞

问候
David Allan Finch

假设您的目标是在整个范围内分散分组值,
似乎按某种预定义的顺序洗牌位就可以了。
i、 e.给定8位ABCDEFGH,将其像EGDBHCFA或类似模式一样排列


代码只是一个简单的掩码、移位和加法序列。

Mmm。。。根据您是否有很多数字,您可以使用普通stl列表,并按照“随机”标准对其排序

bool
非排序(整数i,整数j)
{
返回random()&31>16?真:假;
}
std::列表li;
//插入元素
li.排序(非排序);

然后,您可以使用普通迭代器获得所有整数。记住使用srand()和时间或任何其他伪随机值初始化random。

您可以尝试构建一个合适的。它们通常用于加密(例如DES),但至少有64位,因此您可能需要自己构建一个适合您需要的。它们通过构造是可逆的。

现在的问题是,你是需要一个真正的随机映射,还是仅仅需要一个“弱”置换。假设是后者,如果在2的补码运算中使用无符号32位整数(比如说),那么与任意奇数相乘就是一个双射可逆映射。当然,XOR也是如此,所以您可以尝试使用一个简单的模式,例如

unsigned int hash(int x) {
   return (((x ^ 0xf7f7f7f7) * 0x8364abf7) ^ 0xf00bf00b) * 0xf81bc437;
}
这些数字没有什么神奇之处。所以你可以改变它们,甚至可以随机化。唯一的问题是被乘数必须是奇数。您必须使用回滚进行计算(忽略溢出)。这是可以颠倒的。要进行反演,您需要能够计算正确的互补被乘数A和B,然后进行反演

unsigned int rhash(int h) {
    return (((x * B) ^ 0xf00bf00b) * A) ^ 0xf7f7f7f7;
}
您可以用数学方法计算A和B,但对您来说,更简单的方法是运行一个循环并搜索它们(即离线后)


该方程使用混合乘法的异或使映射非线性。

对于约束集,实际上没有解。尝试将32位无符号散列为32位无符号将导致冲突,除非您执行简单的操作,如1对1映射。每个数字都是它自己的散列。

是的,这是我一直在想的事情,但我希望可能会有更随机的事情。我不知道你可以用排序来做这件事,对于较小的值,我认为这是一个很好的解决方案。但我考虑的是一个完整范围的无符号长-长-长的大小。我认为这是正确的答案,但我需要一些时间来弄清楚如何实现Feistel网络。我认为这里没有足够的信息来提出一个好的解决方案。需要散列多少个整数?那个整数列表中会有重复的吗?你的列表中的值的范围是什么?有序整数允许为负吗?我打算使用无符号长或长(即32位或64位)的完整范围。只是好奇——“遗传算法”标签是如何出现的?我键入的算法与我想要的一样。这个自动完成的程序加入了“遗传算法”。如果标签是错误的,我很乐意删除它。有趣的是A和B不是反向A=1/0x8364abf7,或者存在舍入问题。不,不,从这个意义上说,它们不是反向。它们是模2**32的有限乘法群中的逆。这与有理数领域中的倒数无关。我快速搜索了前10万个数,结果看起来很好,速度也很快。我希望明天有更多的时间用一组更大的数字来测试它。是的,它既好又快:)唯一的问题是最低阶位是非常线性的。。。但在您的应用程序中,这很可能不会造成伤害。如果您想打破这一点,可以在第一次乘法后将((x19))添加到等式中。相反的情况是显而易见的。
unsigned int rhash(int h) {
    return (((x * B) ^ 0xf00bf00b) * A) ^ 0xf7f7f7f7;
}