Java中的随机数通常会产生相同的值

时间:2018-03-26 11:45:09

标签: java android random

enter image description here

我正在使用此功能生成513之间的值

 int randomGeneratedLevelValue = ThreadLocalRandom.current().nextInt(5, 13);

如何减少相同的匹配?

2 个答案:

答案 0 :(得分:8)

在不偏置随机数序列的情况下,无法减少真随机数序列中的重复次数。

因此,例如,在您的序列10, 5, 12, 12, 13, 13中,12跟随另一个12的概率为9;即与该范围内任何其他数字的概率相同。

现在有可能因为您正在使用Random / ThreadLocalRandom,您可能会看到线性同余生成器中固有的自相关效应。如果是这样,可以使用SecureRandom来消除这些影响。但是SecureRandom来电要贵得多。

另一种方法是故意偏向反对重复;例如(伪代码)

int random = rand.nextInt(...)
if (random == lastRandom) {
     random = rand.nextInt(...);
}
return random;

但要小心。引入偏见可能会产生意想不到/意外的后果。

答案 1 :(得分:2)

Birthday Paradox预测随机数重复的概率远高于您的想法。例如,它预测,只有23名随机的人,其中两人生日相同的概率大于50%。通过Pigeonhole Principle,需要367个人才有100%的重复次数,但是在此之前重复的可能性非常高。

这里是概率分布(来自维基百科): enter image description here

rule of thumb以估算重复概率达到sqrt(2m * p(n))之前必须生成的数字的数量,其中m是可能的随机数和p(n)是你正在寻找的概率。因此,例如,如果您在50个数字范围内生成随机数(例如,如果您从100到150中选择一个随机数),那么您只需要生成大约sqrt((2 * 50) * 0.5) = 7.07个随机数赔率之前的数字与没有重复的数字一样好。如果您在50个数字范围内生成8个随机数,则赔率优于不具有重复数。 (请注意,这仅适用于p(n)最多1/2的值。

在您的情况下,任何特定随机值(5,6,7,8,9,10,11,12)都有8个可能的值,因此您只需要在那之前生成sqrt(8) = 2.83个数字&# 39;你有50%的概率,你有重复。换句话说,生日悖论预测你只需要生成大约3个数字,这样就有可能比你没有重复更好。

另见this Q&A

还有一点:提防Gambler's Fallacy,人们会认为如果你随机生成一个10,那么下一个获胜的几率是10。实际上,考虑到你和#39;重新生成随机数,任何特定数字的几率为1/8,无论之前的数字是多少。换句话说,如果生成12,则下一个数字为10的概率为1/8。如果生成7,则下一个数字为10的几率为1/8。如果生成10,则下一个数字为10的概率仍为1/8。每个号码都是独立事件(即您迄今为止生成的号码不会影响未来号码的概率分布)。

TL; DR 如果您在小范围内生成随机数,则需要生成的数字远少于您之前认为的数字,而且可能会开始重复数据特别是数字(就像你一样)这个数字特别低。