如何从较小的概率集中生成更大的概率集?
这来自算法设计手册-Steven Skiena
问:
使用随机数生成器(rng04)以相同的概率生成{0,1,2,3,4}中的数字,以编写一个随机数生成器,以相等的概率生成从0到7(rng07)的数字?< / p>
我现在尝试了大约3个小时,主要是基于两个rng04
输出的总和。问题在于,在这种情况下,每个值的概率是不同的 - 4可以有5/24概率而0发生是1/24。我尝试了一些方法来掩盖它,但不能。
有人可以解决这个问题吗?
答案 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
,其中X
和Y
是两个随机数。这会给你一组像这样的结果
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 = 0
,8 mod 8 = 0
,16 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则完全相同一种生产方式。
我不知道如何解决这个问题,但我会尝试为你减少一点。需要考虑的一些要点:
这样做的一种方法是,想象一下根据您的输入构建的基数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