散列函数和随机排列

时间:2012-09-17 15:47:26

标签: c++ algorithm hash permutation

阅读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;
    }
}

3 个答案:

答案 0 :(得分:3)

您可以尝试其他方法。

  1. GCD(P, N) == 1 GCD(P, N) PN GCD(70, 42) == 14GCD(24, 35) == 1 K[i] ::= (P * i) mod N + 1的任意整数P(例如i1)。
  2. 从[{1}}到N
  3. 获取序列K[i]K[N + 1] == K[1]
  4. 事实证明,序列P列举了所有数字 1和N没有重复(实际上{{1}}但这不是问题,因为我们只需要前N个数字。)
  5. 如果你可以有效地生成具有均匀分布的数字{{1}}(例如具有良好的随机函数),并使用greatest common divisor来计算O(log(N))复杂度中的GCD,那么你将得到什么你想要的。

答案 1 :(得分:1)

如果没有一些随机性,就不可能生成“随机”排列。它甚至没有意义。您的代码每次都会产生相同的排列。

我怀疑你打算每次都选择不同的两个随机哈希函数。但即使这样也不会像你一样使用散列函数(a +/- k%b用于a,b随机选择),因为你需要O(n log n)位随机性来指定排列。

答案 2 :(得分:0)

我不确定问题是什么。如果你想随机排列, 你想要一个随机数发生器,而不是一个哈希函数。哈希 函数是(并且必须是)确定性的,因此它不能用于a “随机”排列。哈希是任何东西的排列。

我不认为随机排列可以是O(1)空间。你有 跟踪已经使用过的元素。