Random in Java often generating same value
。
我用这个来生成5到13之间的值。
1
| int randomGeneratedLevelValue = ThreadLocalRandom.current().nextInt(5, 13); |
如何减少相同的匹配?
- 试试这个
- 虽然您的方法相当聪明,但也有一些缺点(其中一些可能会导致您的问题),这里描述的是随机对线程局部随机
- 所以你不想要随机值?对于这样的范围,相同的值是很正常的…做一些数学计算同一个数字的概率
- en.m.wikipedia.org/wiki/birthday_问题
在一个真正的随机数序列中,没有办法减少重复次数而不偏倚随机数序列。
例如,在你的顺序中,10, 5, 12, 12, 13, 13后面跟另一个12的概率是1比9,也就是说,与范围内任何其他数字的概率相同。
现在,由于您使用的是Random/ThreadLocalRandom,您可能看到了线性同余生成器固有的自相关效应。如果是这样,可以使用SecureRandom来消除这些影响。但是,SecureRandom电话的价格要贵得多。
另一种方法是故意偏向重复;例如(伪代码)
1 2 3 4 5
| int random = rand.nextInt(...)
if (random == lastRandom) {
random = rand.nextInt(...);
}
return random; |
但要小心。引入偏见可能会产生意想不到的/意想不到的后果。
- 最后一个号码是什么??
- 从生成器中得到的最后一个随机数。这是伪代码
- 最后一个号码是什么??使用ThreadLocalRandom.current().nextInt(5, 13)?12(nextint(int least,int bound)返回给定的最小值(inclusive)和bound(exclusive)之间的伪随机、均匀分布的值。)但你问过如何减少相同的匹配?这个答案回答了那个问题
- @塞尔文-我想操作人员在问我的伪代码中lastRandom是什么意思。但这真的很难说。他的问题和评论很不清楚。
- 他用以东十一〔二〕回答自己,为什么我认为最后一个数是多少?是关于ThreadLocalRandom.current().nextInt(5, 13)返回的最后一个数字,而不是您代码中的lastRandom……我们这里的情况是无法沟通
- @塞尔文-你的理由是合理的…我们只能确定他是否解释了自己。
生日悖论预测随机数的重复概率比你想象的要高得多。例如,它预测,只有23个随机的人,其中两个生日相同的可能性超过50%。根据鸽子洞原理,需要367人才能有100%的复制机会,但复制的概率在这之前是非常高的。
这是概率分布(来自维基百科):。
在重复概率达到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个数字,就有可能有50%的重复。换句话说,生日悖论预测,你只需要生成大约3个数字,这样你就有可能得到一个副本。
另请参见本问答。
还有一点:当心赌徒的谬论,在这个谬论中,人们假设如果你随机生成一个10,那么下一个概率就不会是10。事实上,考虑到你生成的是随机数,任何一个特定数字的概率都是1/8,不管之前的数字是什么。换句话说,如果生成一个12,下一个10的概率是1/8。如果生成7,则下一个数字为10的几率为1/8。如果生成一个10,下一个10的概率仍然是1/8。每个数字都是一个独立的事件(即,到目前为止生成的数字对未来数字的概率分布影响最小)。
tl;dr您需要生成的数字比您认为的要少得多,然后才有可能开始复制-如果您在一个小范围内生成随机数,特别是(像您这样)这个数字特别低。