我想要一个随机数生成器来模拟抛硬币,下面是我做的
public class CoinToss
{
public static void main(String args[])
{
int num=(int)(1000*Math.random());
if(num<500)
System.out.println("H");
else
System.out.println("T");
}
}
结果令人沮丧,我在20分中得到了16个正面和4个反面。这并不是看起来是随机的。这是可能的,但我想要一个普遍的意见,如果程序是正确的?我是不是在数学上遗漏了什么?
稍微修改了一下代码,它似乎足够随机。
代码:
int h = 0;
int t = 0;
for (int i = 0; i < 1000; i++) {
int num = (int) (1000 * Math.random());
if (num < 500) {
h++;
} else {
t++;
}
}
System.out.println("T:" + t);
System.out.println("H:" + h);
输出:
T:506
H:494
我想这就是随机性的事情^^
20分的样本量不够大,无法评估它的随机性。可以这样想:如果你跑了4次,得到了4个人头,你会想,"哇,这根本不是随机的。"但事实上,如果你拿了4个硬币,翻了16次,你会期望至少得到一次所有的4个人头。因此,如果你进行了少量的跑步,你得到的结果在头部和尾部之间并不均等,这并不意味着这不是随机的。
或者这样看:如果你写一些代码,只打印"头"、"尾"、"头"等等,你就会得到半头半尾。但这根本不是随机的!这只是一个重复的模式。
因此,当随机结果在短期内看起来不均衡时,故事的寓意并不奇怪。试着重新编写你的代码,这样它就可以计算出有多少头和有多少尾,让它翻转大约100万个,看看你是否每个都没有得到大约50万个。它应该多一点或少一点,因为随机并不能给出确切的结果,但应该更接近。
您的代码似乎是正确的,尽管您可以更容易地实现它:
Random r = new Random();
int num = r.nextInt(2);
if (num == 0)
System.out.println("H");
else
System.out.println("T");
Random#nextInt(int i)
返回0
和i-1
之间的随机整数
伪随机数生成器(PRNG),也称为确定性随机位生成器(DRBG),是一种用于生成其性质近似于随机数序列性质的数字序列的算法。
PRNG生成的序列并不是真正随机的,因为它完全由一组相对较小的初始值决定,称为PRNG的种子
尽管可以生成更接近真正随机的序列
当然,任何考虑产生随机数字的算术方法的人都是处于罪恶状态。约翰·冯·诺依曼
您需要更多的输入才能获得相等数量的输入。对于如此少量的输出,有时你会让它们在数量上相互接近,有时一方会比另一方"显示"得更多。实际上,拥有4
尾部和16
头部的概率是0.462%
,这在某种程度上是"现实的"。。。试着在更高的跑动次数下更多地使用它,看看它的表现如何。
顺便说一句,想想这个输入:
6 6 6 6 6 6 6 6 6 6
这似乎不是随机的,对吧?但它存在于π
的小数点,所以它是随机级数的一部分。这只是一个级数大小的问题,所以当你处理随机数时,你必须这样想。更多地考虑随机生成器而不是结果。您使用的是正确的函数,因为它是基于System.nanoTime()的,所以生成器是正确的,但结果太小了。