Java Random.nextInt返回连续的相同值整数(经常)
当运行Java Random.nextInt返回连续的相同值整数(经常),java,scala,random,statistics,Java,Scala,Random,Statistics,当运行scala.util.Random().nextInt(3)81次时,我看到如下结果(Java开发人员,请参阅edit,了解这两者之间的关系): 20001020201210222211012021020111220022001021101222222202221022010000100010 请注意大型连续块: 000,22222,111,2222222,22222,22222,00000,000 从直觉上看,这个序列似乎不是自然的/真实世界的抛硬币随机的 例如,要实现6x连续2s,只有
scala.util.Random().nextInt(3)
81次时,我看到如下结果(Java开发人员,请参阅edit
,了解这两者之间的关系):
20001020201210222211012021020111220022001021101222222202221022010000100010
请注意大型连续块:
000
,22222
,111
,2222222
,22222
,22222
,00000
,000
从直觉上看,这个序列似乎不是自然的/真实世界的抛硬币随机的
例如,要实现6x
连续2
s,只有0.4%
机会(AFAIK),对于5x
连续值,有1.2%
机会。。。因此,我似乎不太可能在输出中继续看到这样的模式
在现实世界中,三面硬币会发生这种情况吗?或者,当使用Java的random.nextInt(exclusiveMax)
方法时,这是对“真正随机”的预期偏差吗
编辑:
实际上,我一直在使用
scala.util.Random.nextInt(int)
,它通过new java.util.Random()创建了一个新的全局java.util.Random
这不是一个玩笑:我会在现实世界中尝试它(用两个硬币可能最简单:两个正面=0,混合=1,两个反面=2)。我想你也会看到同样的结果
你只有三个值,所以2的概率总是1:3。你说得很对,得了2分后,你连续5次得2分的几率约为0.04%,这在81卷中确实不太可能。但在得到2分后,你再得到4分的几率是(正如你所说)1.23%——可能性要大得多,而且在81分中也不足为奇
在我下面运行程序时,我通常在81卷的批次中运行三次,经常运行四次,但很少运行五次,也很少运行六次。所有这些基本上符合我的预期
这是一个相当复杂的话题。最简单的方法是将其运行数百万次,然后查看是否每次都得到了约0.33333333%的值。但当然,这可能是100万个0、100万个1、100万个2,这将是一个可疑的随机结果。:-)但是,如果您想测试您的设置,您可以尝试Wikipedia文章中讨论的几种方法。或者订阅真实随机性的来源,比如。或者一个随机的USB设备(尽管我会对其中一个进行大量的尽职调查)
我的节目:
import java.util.*;
public class E {
public static void main(String[] args) {
Random r = new Random();
Map<Integer,Integer> runs = new TreeMap<>();
int last = -1;
int run = 0;
for (int i = 0; i < 81; ++i) {
int v = r.nextInt(3);
if (v != last) {
if (i != 0) {
if (runs.containsKey(run)) {
runs.put(run, runs.get(run) + 1);
} else {
runs.put(run, 1);
}
System.out.println(" (" + run + ")");
}
last = v;
run = 0;
}
++run;
System.out.print(v);
}
System.out.println("\n****");
for (Map.Entry e : runs.entrySet()) {
System.out.println(e.getKey() + ": " + e.getValue());
}
}
}
import java.util.*;
公共E类{
公共静态void main(字符串[]args){
随机r=新随机();
映射运行=新建树映射();
int last=-1;
int run=0;
对于(int i=0;i<81;++i){
int v=r.nextInt(3);
如果(v!=最后一个){
如果(i!=0){
if(运行。容器(运行)){
runs.put(run,runs.get(run)+1);
}否则{
运行。放置(运行,1);
}
System.out.println(“(“+run+”);
}
last=v;
run=0;
}
++运行;
系统输出打印(v);
}
System.out.println(“\n****”);
对于(Map.Entry e:runs.entrySet()){
System.out.println(e.getKey()+“:”+e.getValue());
}
}
}
我们无法为您提供无法看到的代码。没有Random.nextInt(int)
,因此问题中唯一的代码显然不是您的实际代码(nextInt
是一个实例方法,而不是类方法)。请为该问题添加一个示例。最有可能的是,您正在使用相同的种子创建Random
实例。请记住,Random
如果从同一个种子开始,会产生相同的序列,这就是为什么它是一个psuedo随机数生成器。@T.J.Crowder谢谢,已经添加了说明。使用您的示例输出,在第一个之后的81个值中,47个与前一个不同,33个相同。在我看来,这并不是大错特错。(在一个完美的世界里,你会得到33%)只要样本量小,这是可信的。“如果你在数十万个结果后得到同样的比例,我会更担心。”JonSkeet在你建议的测试后,我看到33.33%的样本量更大。谢谢!那是我周日的下午:)@LawrenceWagerfield:LOL