为什么这个生成随机数的程序不断生成数百个数字?

Why does this program that generates random numbers keep generating numbers in the hundreds?

我有一个关于数组的非常简单的问题。我一直在看一些教程,但不明白为什么下面的代码将频率输出作为 1** 的随机组合。它从不给出 5、67、541 等数字,它总是给出 150、175、183 等数字。我希望我说清楚了。非常感谢!

代码:

    Random rand = new Random();
    int freq[] = new int[7];

    for(int roll=1; roll<=1000; roll++){

        ++freq[1+rand.nextInt(6)];
    }

    System.out.println("Face\tFrequency");

    for(int face=1; face<freq.length; face++){
            System.out.println(face + "\t" + freq[face]);
    }

示例输出:

Face       Frequency

1        176

2        171

3        157

4        159

5        164

6        173

这是正常的。频率为 5 是非常不寻常的,因为这意味着该数字在 1000 次中仅滚动了 5 次。您得到的数字大约是 1000 次滚动总数的 1/6,因此六个数字中的每一个都滚动了一次第六次。

因为循环1000次所以偏差很小

如果你只循环 10 次,但在循环中将数字增加 100,你会得到更高的偏差。

这实际上更像是一道数学题,而不是编程题!

掷骰子有六种可能的结果,您掷骰子 1,000 次。这意味着,如果您想查看一个不属于 "one hundred and X," 形式的数字,您需要查看一个数字的 200 或更多或一个数字的 99 或更少。您将看到每个数字的预期次数为 1000 / 6 = 166.7,因此为了看到 200 或更多的数字,您需要偏离真实值 +33.3 或 -66.7。这可能发生;只是不常见。

我编写了一个程序来模拟像这样掷骰子,直到您获得其中一种类型的掷骰并计算您需要掷骰子的次数。这样做 1000 次后,我发现平均而言,您需要掷骰子 53 次才能看到一个不在 100 以内的数字。这是代码:

import java.util.*;

public class DiceRolls {
    /* The number of trials to run. */
    private static final int NUM_TRIALS = 1000;

    public static void main(String[] args) {
        Random rand = new Random();

        int totalRuns = 0;
        for (int i = 0; i < NUM_TRIALS; i++) {
            totalRuns += runsUntilEvent(rand);
        }
        System.out.println(totalRuns / (double)NUM_TRIALS);
    }

    private static int runsUntilEvent(Random rand) {
        /* Track how many tries we needed. */
        int numTries = 0;
        while (true) {
            numTries++;

            /* Rather than indexing from 1 to 6, I'm indexing from 0 to 5. */
            int freq[] = new int[6];            
            for(int roll = 0; roll < 1000; roll++){
                ++freq[rand.nextInt(6)];
            }

            /* See if this isn't in the hundreds. */
            for(int face = 0; face < freq.length; face++){                
                if (freq[face] >= 200 || freq[face] <= 99) {
                    return numTries;
                }
            }
        }
    }
}

所以你的问题的答案是"you may see it, but it's unlikely and you'd have to run the program a lot to see it."

希望对您有所帮助!

输出的是一个数在每个"dice roll"中出现的次数。就您使用伪随机数生成而言,数字生成被视为 "fair",因此您有一个 "fair dice roll",这意味着平均而言,每个数字在每次掷骰中出现的机会均等。

因此,每个数字的出现次数平均应该是总掷数的近1/6次,这就是你现在的结果。

如果增加总roll的个数,每个数字之间1/6的偏差会更大,并且随着roll的数量递增

我猜你原来的问题是为什么你没有得到低于 100(小于 10%)或大于 500(大于 50%)这样的低值。

简答,你不够幸运。由于您创建随机生成器的方式,您必须 运行 您的程序多次才能观察到这些值。

让我们计算一下如果您 运行 您的程序只出现一次,任何结果(频率)在超过 50% 的情况下发生的概率: 如果我们成对滚动(例如 1000 卷是 500 对),这可以很容易地估计出来

对于每一对,某些特定边(例如 6)的概率是合格结果的数量除以结果总数:

合格结果(第 6 面出现 50% 或更多):

16, 26, 36, 46, 56, 66, 
61, 62, 63, 64, 65 

总结果:6^2 = 36

所以 11 个合格结果除以总数得出一方出现 50% 或更多次数的概率,即 11/36

现在我们需要这种情况连续发生 N/2 次,所以我们应该将配对概率乘以 N/2 次:(11/36)^(N/2)

Wolfram alpha 给我们 3.5 * 10^-258 这意味着你需要 运行 你的程序 2.85 * 10^257 次来期望(一次)一个特定边的频率 500 次或更多。

将其除以 6 以查看 任何 一侧。