Random.nextInt 返回连续的相同值整数(经常)



我在运行 81 次时看到如下结果scala.util.Random().nextInt(3)(Java 开发人员,请参阅edit以了解其相关性):

200010202002112102222211012021020111220022001021101222222022210222220100000100010

请注意大型连续块:000222221112222222222222200000000

直观地说,序列似乎不是自然/"现实世界的硬币翻转"随机。

例如,要实现6x连续2,只有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 分之后,你连续五次再得到 2 次的几率约为 0.04%,这在 81 次掷骰子中确实不太可能。但是在得到 2 分之后,你再得到4分的几率是(正如你所说)1.23% ——可能性要大得多,这在 81 次掷骰子中并不奇怪。

我自己运行下面的程序,我经常在 81 卷的批次中运行三卷,并且经常运行四次,但很少运行五次,很少运行六次。所有这些都在很大程度上符合我的期望。

测量PRNG的随机性是一个相当复杂的话题。简单的度量是运行数百万次,然后查看您是否在 ~0.33333333% 的时间内得到了每个值。但是,当然,这可能是一百万个0,然后是一百万个1,然后是一百万个2,这将是一个可疑的随机结果。:-)但是,如果您想测试您的设置,您可以尝试该维基百科文章中讨论的几种方法。或者订阅像 https://www.random.org/这样的真正随机性来源。或者一个随机的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());
}
}
}

最新更新