2009-12-31 125 views
9

你有一个有偏倚的随机数发生器,产生1概率为p,0为概率(1-p)。你不知道p的价值。使用它可以产生一个无偏的随机数发生器,其产生1的概率为0.5,0的概率为0.5。无偏随机数发生器使用偏倚的随机数发生器

注意:这个问题是从介绍由Cormen,Leiserson,维斯特,斯坦算法的练习题(CLRS)

+1

我猜测答案与标准方法使用偏置发生器有关,并且一次作为反函数,这样你就有一次0的概率,第二次迭代的0(1-p)概率,并混合这两个结果来平衡分配。我不知道背后的确切数学。 – 2009-12-31 19:50:13

+0

埃里克 - 是的,如果你做了(兰特()+(1兰特()))/ 2,你可以合理地期望获得一个无偏见的结果。请注意,在上面你应该调用rand()两次,否则你总是得到。5 – JohnE 2009-12-31 19:57:21

+0

@JohnE:基本上这就是我的想法,但是这不会让你得到一个0或1的直线,这是要求的。我认为保罗用他的回答击中了头部。 – 2009-12-31 20:02:48

回答

17

事件(P)(1-p)和(1-P)。 (p)是等概率的。将它们分别作为0和1,并丢弃另外两对结果,得到一个无偏的随机生成器。

在代码中,这是为做容易,因为:

int UnbiasedRandom() 
{ 
    int x, y; 

    do 
    { 
     x = BiasedRandom(); 
     y = BiasedRandom(); 
    } while (x == y); 

    return x; 
} 
+3

完美。从历史上看,这种设备是由于我们都熟悉的冯诺依曼(可能没有意识到)。 – jason 2009-12-31 20:19:35

+0

如果偏差本身在一段时间内变化,这是否仍然有效? – 2501 2016-09-20 21:50:05

2

您需要从RNG画对值直到你得到不同值的序列,即,零后面紧跟着一个或一个零。然后,您获取该序列的第一个值(或最后一个,无关紧要)。

(只要引出的一对或者是两个零或两个1即重复)这背后的数学很简单:0然后1序列具有非常相同的概率为1,则零序。通过总是将这个序列的第一个(或最后一个)元素作为新的RNG的输出,我们有机会得到一个零或一个。

1

下面是一种方法,可能不是最有效的。咀嚼一堆随机数,直到得到[0 ...,1,0 ...,1]形式的序列(其中0 ...是一个或多个0)。计数0的数量。如果第一个序列较长,则生成一个0,如果第二个序列较长,则生成一个1.(如果它们相同,则再试一次。)

这就像HotBits从放射性生成随机数粒子衰变:

由于任何给定衰变的时间是随机的,因此两个连续衰变之间的间隔也是随机的。我们所做的是测量一对这样的间隔,并根据两个间隔的相对长度发出一个零位或一位。如果我们测量两个衰变相同的间隔,我们丢弃测量并再次尝试

HotBits: How It Works

4

归因于冯·诺伊曼同时获得两个比特的特技,具有01对应于0和10到1,重复00或11已经出现。使用此方法需要提取以获取单个位的位的预期值为1/p(1-p),如果p特别小或大,则该位可能会变得非常大,因此值得问一问该方法是否可以改进,特别是因为它是它显然会抛出很多信息(全部是00和11)。

谷歌搜索“冯·诺伊曼特技偏置”产生this paper,开发针对该问题的更好的解决方案。这个想法是,你仍然需要一次两位,但如果前两次尝试只产生00秒和11秒,你把一对0作为单个0和一对1作为一个1,并且应用冯诺依曼的技巧对这些对。如果这也不起作用,那么在这个级别的对上继续类似的组合,等等。

此外,本文将此发展为从偏置源生成多个无偏位,本质上使用两种不同的方法从位对生成位,并给出一个草图,表明这是最优的,原始序列在其中熵的位数。

4

produce an unbiased coin from a biased one的程序首先归因于Von Neumann(一个在数学和许多相关领域做了大量工作的人)。程序非常简单:

  • 投掷硬币两次。
  • 如果结果一致,重新开始,忘记两个结果。
  • 如果结果不同,请使用第一个结果,忘记第二个结果。

这个算法工作的原因是因为越来越HT的概率p(1-p),这是与获取TH (1-p)p。因此两个事件同样可能。

我也在读这本书,它会询问预计的运行时间。两次投掷不相等的概率为z = 2*p*(1-p),因此预计运行时间为1/z


前面的例子看起来令人鼓舞的(毕竟,如果你有一个偏见硬币的p=0.99偏见,你需要把你的硬币大约50倍,这是没有那么多)。所以你可能会认为这是一个最佳算法。可悲的是,事实并非如此。

这是它与Shannon's theoretical bound(图片取自answer)的比较。它表明算法很好,但远不是最优的。

enter image description here

你能想出的改善,如果你会考虑HHTT将通过该算法被丢弃,但其实它具有相同的概率TTHH。所以你也可以在这里停下来并返回H.HHHHTTTT也是如此。使用这些情况可以改善预期的运行时间,但不会使其在理论上最佳。


而在最后 - Python代码:

import random 

def biased(p): 
    # create a biased coin 
    return 1 if random.random() < p else 0 

def unbiased_from_biased(p): 
    n1, n2 = biased(p), biased(p) 
    while n1 == n2: 
     n1, n2 = biased(p), biased(p) 

    return n1 

p = random.random() 
print p 

tosses = [unbiased_from_biased(p) for i in xrange(1000)] 
n_1 = sum(tosses) 
n_2 = len(tosses) - n_1 
print n_1, n_2 

这是不言自明的,这里有一个例子结果:

0.0973181652114 
505 495 

正如你看到的,但是我们有0.097的偏差,我们得到大约相同数量的10

+0

如果偏差本身随时间变化,这是否仍然有效? – 2501 2016-09-20 21:50:28

+0

@ 2501不,它不是 – 2016-09-20 22:48:39

+0

感谢您的回复。显然,概率不再一样了。我想知道现实生活中的生成器如何处理这个问题。 – 2501 2016-09-21 12:53:53