java

kcwpcxri  于 2021-07-06  发布在  Java
关注(0)|答案(2)|浏览(210)

这个问题在这里已经有答案了

为什么人们说在使用随机数生成器时存在模偏差(10个答案)
上个月关门了。
所以我的问题是java,但它可以是任何编程语言。有以下声明:

Random rnd = new Random();

我们想得到一个从0到x的随机数
我想知道以下两者之间是否存在数学上的差异:

rnd.nextInt() % x;

rnd.nextInt(x)

主要的问题是,这些解决方案中的一个比另一个更随机吗?一种解决方案比另一种更合适还是更“正确”?如果他们相等的话,我很乐意看到数学证明

rbl8hiat

rbl8hiat1#

欢迎来到“数学洞察”与“绘画小姐”。
因此,从统计学的Angular 来看,这将取决于生成的数字的分布。首先,我们将把任何一个数字出现的概率视为一个独立事件(即丢弃种子,即rng等)。然后,一个模数只是取一系列的数字(例如。 aN ,在哪里 0 <= a < N ),并基于除数( xa % 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 对于某些特定场景来说,这只是一个半途而废的步骤。对于你老师的观点,我认为在使用模方法时,你更可能看到一些特定的数字子集,而不是更少。

ijnw1ujt

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。

相关问题