这个问题在这里已经有答案了:
为什么人们说在使用随机数生成器时存在模偏差(10个答案)
上个月关门了。
所以我的问题是java,但它可以是任何编程语言。有以下声明:
Random rnd = new Random();
我们想得到一个从0到x的随机数
我想知道以下两者之间是否存在数学上的差异:
rnd.nextInt() % x;
和
rnd.nextInt(x)
主要的问题是,这些解决方案中的一个比另一个更随机吗?一种解决方案比另一种更合适还是更“正确”?如果他们相等的话,我很乐意看到数学证明
2条答案
按热度按时间rbl8hiat1#
欢迎来到“数学洞察”与“绘画小姐”。
因此,从统计学的Angular 来看,这将取决于生成的数字的分布。首先,我们将把任何一个数字出现的概率视为一个独立事件(即丢弃种子,即rng等)。然后,一个模数只是取一系列的数字(例如。
a
从N
,在哪里0
<=a
<N
),并基于除数(x
在a % x
). 虽然从技术上讲,这些数字来自离散总体(整数),但概率质量函数的整数范围将非常大,最终看起来就像一个连续的图形。让我们考虑一系列数字的概率分布函数图:如果你的随机数生成器没有生成一个均匀分布的数(也就是说,任何一个数都有可能出现另一个数),那么模将(可能)分解非均匀分布的结果。当您将这些范围内的单个整数视为离散(和单个)结果时,任何数字的概率
i
(0<=i<x)结果是个体概率的乘积(i_1
*i_2
* ... *i_(N/x)
). 从另一个Angular 来看,如果我们覆盖范围的细分,很明显,在非对称分布中,模很可能不会产生同样可能的结果:记住,结果的可能性
i
在上面的图表中,可以通过乘以个体数的可能性来实现(i_1
, ...,i_(N/x)
)在范围内N
这可能导致i
. 为进一步说明,如果N
不会被模除数平均除x
,总会有一些数字N % x
这将有一个额外的整数,可以产生他们的结果。这意味着大多数模因子不是2
(同样,不是其除数倍数的范围)可能会向其较低的结果倾斜,无论是否具有均匀分布:总结一下,
Random#nextInt(int bound)
拿走所有这些东西(还有更多!)考虑到,并将始终产生一个结果与统一的概率范围内bound
.Random#nextInt() % bound
对于某些特定场景来说,这只是一个半途而废的步骤。对于你老师的观点,我认为在使用模方法时,你更可能看到一些特定的数字子集,而不是更少。ijnw1ujt2#
new Random(x)
只是创造了Random
具有给定种子的对象,它不会自行生成随机值。我想你是在问
nextInt() % x
以及nextInt(x)
.区别如下。
下一个(x)
nextInt(x)
产生一个随机数n,其中0≤ n<x,均匀分布。nextint()%x
nextInt() % x
产生一个整数范围为1的随机数,然后应用模x。整个整数范围包含负数,因此结果也可能是负数。换句话说,范围是−x<n<x。此外,在大多数情况下,分布并不均匀。
nextInt()
有232个可能性,但是,为了简单起见,假设它有24=16个可能性,我们选择x不是16或更大。假设x是10。所有的可能性都是0,1,2,…,14,15,16。应用模10后,结果是0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5。这意味着一些数字比其他数字发生的可能性更大。这也意味着一些数字的变化发生两次已经增加。
如我们所见,
nextInt() % x
有两个问题:范围不符合要求。
分布不均。
所以你应该明确使用
nextInt(int bound)
在这里。如果要求是“仅获取唯一数字”,则必须排除已从数字生成器中提取的数字。另请参见在java中生成唯一随机数。1根据javadoc。