阅读this问题后。我想知道是否有可能使用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;
}
}
答案 0 :(得分:3)
您可以尝试其他方法。
GCD(P, N) == 1
GCD(P,
N)
P
为N
GCD(70, 42) == 14
和GCD(24, 35) == 1
K[i] ::= (P * i) mod N + 1
的任意整数P(例如i
,
1
)。N
K[i]
,K[N + 1] == K[1]
P
列举了所有数字
1和N没有重复(实际上{{1}}但这不是问题,因为我们只需要前N个数字。)如果你可以有效地生成具有均匀分布的数字{{1}}(例如具有良好的随机函数),并使用greatest common divisor来计算O(log(N))复杂度中的GCD,那么你将得到什么你想要的。
答案 1 :(得分:1)
如果没有一些随机性,就不可能生成“随机”排列。它甚至没有意义。您的代码每次都会产生相同的排列。
我怀疑你打算每次都选择不同的两个随机哈希函数。但即使这样也不会像你一样使用散列函数(a +/- k%b
用于a,b随机选择),因为你需要O(n log n)
位随机性来指定排列。
答案 2 :(得分:0)
我不确定问题是什么。如果你想随机排列, 你想要一个随机数发生器,而不是一个哈希函数。哈希 函数是(并且必须是)确定性的,因此它不能用于a “随机”排列。哈希是不任何东西的排列。
我不认为随机排列可以是O(1)空间。你有 跟踪已经使用过的元素。