我怎样才能产生更大的概率从一个较小的概率集合设置?
这是从算法设计手册-Steven Skiena
问:
使用一个随机数发生器(rng04),其从{0,1,2,3,4}生成数以相等的概率来写的随机数生成器,其编号从0到7(rng07)以相等的概率是多少?
我试了3个小时左右,现在,主要是基于两个相加rng04
输出。 的问题是,在这种情况下每个值的概率是不同的 - 4可配有5/24的概率而发生0是1/24。 我尝试了一些方法来掩盖它,但不能。
谁能解决这个问题?
你必须找到一种方法,两组随机数的组合(第一和第二随机{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,六百二十五分之一将采取的3倍长等)。 但它会给你正确的概率。
真正的问题,当然,是一个事实,即在(在这种情况下4)的总和的中间数发生在许多组合(0 + 4,1 + 3等),而在0和8有一个确切的方式来来制造。
我不知道如何解决这个问题,但我会尽量减少它一下你。 几点考虑:
- 在0-7范围内有8个可能的值,所以最终的你的目标应当是可能的情况的总数必须是8的倍数。这样,你可以具有在该值域每值分布的整数倍。
- 当你(当你评价的总和,仅仅在输入不同的排列而言不一定不同)采用两种密度函数之和,可能的情况的数目等于每个输入组的尺寸的乘积。
- 因此,给定相加在一起的两个{0,1,2,3,4}集,则有5×5 = 25点的可能性。
- 这不会是可能从权力得到八的倍数(见第一点),5(见第二点,但外推到任意数量的套> 1),所以你需要有可能的情况下,过剩在你的功能,如果出现他们忽略其中的一些。
- 要做到这一点,据我可以在这一点上看到的最简单的方法,就是用两个{0,1,2,3,4}集(25种可能性)的总和,而忽略1(离开24,多的8)。
- 因此,目前的挑战已经降低到这一点:找到一种方法,以8个输出值中的剩余24点分发的可能性。 对于这一点,你可能不希望使用的总和,而只是输入值。
要做到这一点的方法之一是,想象从你输入构建基地5的数字。 忽略44(这是你的第25届,多余的值,如果你得到它,合成了一系列新的投入),并采取其他,模8,和(各3)你会得到你跨越0-7 24种不同的输入组合,其中是相等的分布。
我的逻辑是这样的:
rn07 = 0;
do {
num = rng04;
}
while(num == 4);
rn07 = num * 2;
do {
num = rng04;
}
while(num == 4);
rn07 += num % 2