使用一个概率集来生成另一个

时间:2009-08-12 18:51:50

标签: probability

如何从较小的概率集中生成更大的概率集?
这来自算法设计手册-Steven Skiena
问:

  

使用随机数生成器(rng04)以相同的概率生成{0,1,2,3,4}中的数字,以编写一个随机数生成器,以相等的概率生成从0到7(rng07)的数字?< / p>

我现在尝试了大约3个小时,主要是基于两个rng04输出的总和。问题在于,在这种情况下,每个值的概率是不同的 - 4可以有5/24概率而0发生是1/24。我尝试了一些方法来掩盖它,但不能。

有人可以解决这个问题吗?

3 个答案:

答案 0 :(得分:4)

你必须找到一种方法来组合两组随机数(第一个和第二个随机{0,1,2,3,4})并使n*n具有不同的可能性。基本上问题是,通过添加你会得到类似这样的东西

        X
      0 1 2 3 4

  0   0 1 2 3 4
Y 1   1 2 3 4 5
  2   2 3 4 5 6
  3   3 4 5 6 7
  4   4 5 6 7 8

哪个有重复,这不是你想要的。组合这两组的一种可能方式是Z = X + Y*5,其中XY是两个随机数。这会给你一组像这样的结果

        X
       0  1  2  3  4

  0    0  1  2  3  4
Y 1    5  6  7  8  9
  2   10 11 12 13 14
  3   15 16 17 18 19
  4   20 21 22 23 24

所以现在你有一组更大的随机数,你需要反过来使它变小。此集具有25个不同的值(因为您从5开始,并使用了两个随机数,因此5*5=25)。您想要的集合有8个不同的值。一种天真的方法是

x = rnd(5)  // {0,1,2,3,4}
y = rnd(5)  // {0,1,2,3,4}
z = x+y*5   // {0-24}
random07 = x mod 8

这确实会有{0,7}的范围。但值{1,7}将出现3/25次,值0将出现4/25次。这是因为0 mod 8 = 08 mod 8 = 016 mod 8 = 0 24 mod 8 = 0

要解决此问题,您可以将上面的代码修改为此。

do {
  x = rnd(5)  // {0,1,2,3,4}
  y = rnd(5)  // {0,1,2,3,4}
  z = x+y*5   // {0-24}
while (z != 24)

random07 = z mod 8

这将取消丢失概率的一个值(24)并丢弃它。如果你得到一个像这样的“坏”值,那么生成一个新的随机数将使你的算法运行得更长(在这种情况下,运行时需要2倍的时间的1/25,1/625需要3倍的时间)等等)。但它会给你正确的概率。

答案 1 :(得分:3)

当然,真正的问题在于总和中间的数字(在这种情况下为4)以多种组合(0 + 4,1 + 3等)出现,而0和8则完全相同一种生产方式。

我不知道如何解决这个问题,但我会尝试为你减少一点。需要考虑的一些要点:

  • 0-7范围有8个可能的值,因此最终您应该瞄准的可能情况的总数必须是8的倍数。这样,​​您可以在该codomain中为每个值分配一个完整的分布数。
  • 当您取两个密度函数的总和时,可能情况的数量(在评估总和时不一定是不同的,仅根据输入的不同排列)等于每个输入的大小的乘积集。
  • 因此,假设两个{0,1,2,3,4}组合在一起,你有5 * 5 = 25种可能性。
  • 不可能从5的幂获得8的倍数(见第一点)(参见第二点,但将其外推到任意数量的集合> 1),所以你需要有剩余的您的函数中可能存在的情况,如果它们发生,则忽略它们中的一些。
  • 就此而言,最简单的方法就是使用两个{0,1,2,3,4}组(25种可能性)的总和而忽略1(离开24) ,8)的倍数。
  • 因此,现在的挑战已经减少到:找到一种方法在8个输出值中分配剩余的24种可能性。为此,您可能不想使用总和,而只想使用输入值。

这样做的一种方法是,想象一下根据您的输入构建的基数5中的数字。忽略44(这是你的第25个,多余的值;如果你得到它,合成一组新的输入)并取其他的,模8,你将得到你的0-7跨24种不同的输入组合(每组3个),是平等分配。

答案 2 :(得分:2)

我的逻辑是:

rn07 = 0;
do {
  num = rng04;
}
while(num == 4);

rn07 = num * 2;
do {
  num = rng04;
}
while(num == 4);

rn07 += num % 2