使用随机数字的硬币投掷看起来并不是完全随机的



我想要一个随机数生成器来模拟抛硬币,下面是我做的

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)返回0i-1之间的随机整数

伪随机数生成器(PRNG),也称为确定性随机位生成器(DRBG),是一种用于生成其性质近似于随机数序列性质的数字序列的算法。

PRNG生成的序列并不是真正随机的,因为它完全由一组相对较小的初始值决定,称为PRNG的种子

尽管可以生成更接近真正随机的序列

当然,任何考虑产生随机数字的算术方法的人都是处于罪恶状态。约翰·冯·诺依曼

您需要更多的输入才能获得相等数量的输入。对于如此少量的输出,有时你会让它们在数量上相互接近,有时一方会比另一方"显示"得更多。实际上,拥有4尾部和16头部的概率是0.462%,这在某种程度上是"现实的"。。。试着在更高的跑动次数下更多地使用它,看看它的表现如何。

顺便说一句,想想这个输入:

6 6 6 6 6 6 6 6 6 6

这似乎不是随机的,对吧?但它存在于π的小数点,所以它是随机级数的一部分。这只是一个级数大小的问题,所以当你处理随机数时,你必须这样想。更多地考虑随机生成器而不是结果。您使用的是正确的函数,因为它是基于System.nanoTime()的,所以生成器是正确的,但结果太小了。

最新更新