使用随机数抛硬币并不完全随机

Coin toss using random numbers does not appear exactly random

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

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 次反面。 这 看起来 并不是随机的。这是可能的,但如果程序是正确的,我想要一个普遍的意见?我在数学上遗漏了什么吗?

您的代码似乎是正确的,尽管您可以更轻松地实现它:

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) returns 0i-1

之间的随机整数

您需要更多的输入才能获得相同数量的输入。对于如此少量的输出,有时您会使它们在数量上彼此接近,有时一侧 "show" 比另一侧多。实际上,4 反面和 16 正面的概率是 0.462%,这有点 "realistic" 发生......尝试更多地玩更多的跑步,看看它的行为方式。

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

6 6 6 6 6 6 6 6 6 6

看起来不是随机的,对吧?但它在某些时候以数字 π 的小数形式存在,因此它是随机序列的一部分。这只是一个序列大小的问题,所以当你处理随机数时,你必须以这种方式思考。更多地考虑随机生成器而不是结果。您正在使用正确的函数,因为它基于 System.nanoTime(),因此生成器是正确的,但您的结果太小了。

20 次运行的样本量不足以评估它的随机性。可以这样想:如果你跑了 4 次,得到 4 个正面,你会想,"Wow, that's not random at all." 但实际上,如果你拿了 4 个硬币,并掷了 16 次,你会期望得到所有 4 个正面至少一次。因此,如果您进行少量运行,并且得到的结果在正面和反面之间的分配不均,这并不意味着它不是随机的。

或者这样看:如果你写了一些代码,先打印 "Heads" 然后 "Tails" 然后 "Heads" 等等,你会得到一半的正面和一半的正面尾巴。但这根本不是随机的!这只是一个重复的模式。

因此,当随机结果在短期内看起来不均衡时,故事的寓意是不足为奇的。试试 re-writing 你的代码,让它计算有多少正面和多少反面,让它翻转大约 100 万左右,看看你是否每次都得到大约 500,000。应该多一点或者少一点,因为random不能给你准确的,但是应该比较接近。

A pseudorandom number generator (PRNG), also known as a deterministic random bit generator (DRBG), is an algorithm for generating a sequence of numbers whose properties approximate the properties of sequences of random numbers.

The PRNG-generated sequence is not truly random, because it is completely determined by a relatively small set of initial values, called the PRNG's seed

Although sequences that are closer to truly random can be generated

Anyone who considers arithmetical methods of producing random digits is, of course, in a state of sin. John von Neumann

稍微修改了你的代码,看起来很随机。

代码:

    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

我猜这就是随机性吧^^