哈希函数和随机排列
Hash functions and random permutation
看完这个问题。我想知道是否可以使用 O(1) 空间来生成序列 [1...n] 的随机排列,并使用双哈希之类的东西进行均匀分布?
我用序列 [1,2,3,4,5] 的一个小例子尝试了这个,它有效。但是对于较大的集合,它无法缩放。
int h1(int k) {
return 5 - (k % 7);
}
int h2(int k) {
return (k % 3) + 1;
}
int hash(int k, int i) {
return (h1(k) + i*h2(k)) % size;
}
int main() {
for(int k = 0; k < 10; k++) {
std::cout << "k=" << k << std::endl;
for(int i = 0; i < 5; i++) {
int q = hash(k, i);
if(q < 0) q += 5;
std::cout << q;
}
std::cout << std::endl;
}
}
您可以尝试另一种方法。
- 取任意整数 P,
GCD(P, N) == 1
其中GCD(P, N)
是P
和N
的最大公约数(例如GCD(70, 42) == 14
,GCD(24, 35) == 1
)。 - 获取序列
K[i] ::= (P * i) mod N + 1
,从1
到N
i
- 事实证明,序列
K[i]
枚举了1 和 N 没有重复(实际上是K[N + 1] == K[1]
但这不是问题,因为我们只需要前 N 个数字)。
如果你能有效地生成这样的数字,P
均匀分布(例如,使用良好的随机函数),使用欧几里得算法计算 O(log(N)) 复杂度的 GCD,你就会得到你想要的。
如果没有一些随机性,就不可能生成"随机"排列。 这甚至没有意义。 您的代码每次都会生成相同的排列。
我怀疑你打算每次都选择不同的两个随机哈希函数。 但即使这样使用哈希函数也不起作用,就像你所拥有的(a +/- k%b
随机选择的a,b),因为你需要O(n log n)
位随机性来指定排列。
我不确定问题是什么。 如果你想要一个随机排列,你想要一个随机数生成器,而不是一个哈希函数。 哈希函数是(并且必须是)确定性的,因此它不能用于"随机"排列。 哈希不是任何东西的排列。
我不认为随机排列可以是 O(1) 空间。 你有以某种方式跟踪已经使用的元素。
相关文章:
- 比较并显示使用最小值(a,b)和最大值(a、b)升序排列的4个数字
- 为什么随机数生成器不在void函数中随机化数字,而在main函数中随机化
- 为什么 Serial.println(<char[]>);返回随机字符?
- 为什么不;名字在地图上是按顺序排列的吗
- 字符串-C++后显示的随机字符
- C++优先级队列,按对象的唯一指针的特定方法升序排列
- 循环中的随机函数
- 在c++构造函数中使用随机字符串生成器
- 按对象的特定方法按升序排列的C++优先级队列
- 取消随机排列整数/字符数组
- 如何在C++中随机排列指针列表
- 哈希函数和随机排列
- 伪随机分布,它保证了值序列-C++的所有可能的排列
- 如何随机排列数组问题
- 对 C++ 中的数组执行随机排列
- 随机排列链表
- 在每台计算机上生成相同的随机排列
- 有效地计算随机排列中的第n项
- 随机排列具有特征矩阵的行/列
- 使用128位种子的伪随机排列