假设我们有一个随机生成器函数 rand5
,该函数在1到5之间生成一个随机数,包括。我已经看到,如果您想使用它来生成1到7之间的随机数,则应重复计算
(5 * (rand5() - 1) + rand5())
要在1到30之间生成一个随机数,包含在内,然后重复此过程,直到生成1至21个数字,然后以结果mod七。
。为什么不使用此公式直接直接计算1到7之间的随机数?
(rand5() + rand5() + rand5()) % 7 + 1
这是一个更简单的,相关的问题。假设您想生成1到8之间的数字,并且要有一对六面骰子。如果您尝试通过滚动一对骰子,将结果mod八进行滚动,然后添加一个,会发生什么?也就是说,如果您做类似以下操作会发生什么?
int value = (rand6() + rand6()) % 8 + 1;
这将在正确的范围内生成一个随机数,但是它不会均匀地生成它们。具体而言,在骰子卷上获得不同总数的概率并不统一:
2: 1 / 36
3: 2 / 36
4: 3 / 36
5: 4 / 36
6: 5 / 36
7: 6 / 36
8: 5 / 36
9: 4 / 36
10: 3 / 36
11: 2 / 36
12: 1 / 36
获取这些数字,将它们调整了8个,将它们添加一个,然后将它们分组在一起,给出以下概率,即在1至8之间生成每个数字:
1: 5 / 36 (have to roll 8)
2: 4 / 36 (have to roll 9)
3: 4 / 36 (have to roll 2 or 10)
4: 4 / 36 (have to roll 3 or 11)
5: 4 / 36 (have to roll 4 or 12)
6: 4 / 36 (have to roll 5)
7: 5 / 36 (have to roll 6)
8: 6 / 36 (have to roll 7)
请注意,这些概率并不统一;您比其他任何东西都更有可能获得1、7或8。
这个示例并不是您的建议,但这是同一想法。将多个统一的随机值和其总和范围内的均匀分布构成,因此,如果您从这样的不均匀分布开始,并使用mod来尝试将其挤入较小的范围,那么您将返回<<em> a 分布在该范围内,但不一定是均匀 One。
更复杂的公式 - 顺便说一句,这是一种拒绝采样 - 在某个范围内生成一个均匀的随机数(1-30)重复此过程,直到获得1之间的某些内容-21。然后保证在该范围内产生的值是统一的,并且由于21是7的倍数,因此MIDDING的倍数可以保证1-7之间的均匀随机值。