为什么人们说在使用随机数生成器时会出现模数偏差?

329

我看过很多人提出这个问题,但从未看到一个真正具体的答案。所以我要在这里发布一个帖子,希望能帮助人们理解为什么在使用随机数生成器(如C++中的rand())时会出现“模块偏差”。

11个回答

-3

我刚刚编写了一段代码,用于 Von Neumann 的无偏硬币翻转方法,理论上应该消除任何随机数生成过程中的偏差。更多信息可以在(http://en.wikipedia.org/wiki/Fair_coin)找到。

int unbiased_random_bit() {    
    int x1, x2, prev;
    prev = 2;
    x1 = rand() % 2;
    x2 = rand() % 2;

    for (;; x1 = rand() % 2, x2 = rand() % 2)
    {
        if (x1 ^ x2)      // 01 -> 1, or 10 -> 0.
        {
            return x2;        
        }
        else if (x1 & x2)
        {
            if (!prev)    // 0011
                return 1;
            else
                prev = 1; // 1111 -> continue, bias unresolved
        }
        else
        {
            if (prev == 1)// 1100
                return 0;
            else          // 0000 -> continue, bias unresolved
                prev = 0;
        }
    }
}

1
这并没有解决模数偏差的问题。这个过程可以用来消除位流中的偏差。然而,要从位流得到一个从0到n均匀分布的结果,其中n不是2的幂次减1,需要解决模数偏差的问题。因此,这个解决方案无法消除随机数生成过程中的任何偏差。 - Rick
3
@Rick 嗯。Von Neumann的方法在生成1到100之间的随机数时,消除取模偏差的逻辑延伸将是:A)调用 rand() % 100 100次。B)如果所有结果都不同,则取第一个结果。C)否则,返回步骤A。这种方法可以使用,但预计需要约10^42次迭代,所以您需要非常耐心和长寿。 - Mark Amery
@MarkAmery确实应该可以。不过,看一下这个算法,它没有正确实现。第一个else应该是:else if(prev==2) prev= x1; else { if(prev!=x1) return prev; prev=2;} - Rick

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接