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

时间:2015-01-20 23:33:16

标签: java arrays math random

我对数组有一个非常简单的问题。我一直在看一些教程,并且无法理解为什么下面的代码将频率输出作为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 个答案:

答案 0 :(得分:4)

这实际上是一个数学问题,而不是一个编程问题!

掷骰子有六种可能的结果,你掷骰子1000次。这意味着如果你想看到的数字不是“100和X”的形式,你需要看到一个数字中的200个或更多,或者一个数字中的99个或更少。您将看到每个数字的预期次数是1000/6 = 166.7,因此,为了查看200或更多的数字,您需要偏离真实值+33.3或-66.7。这可能发生;这种情况并不常见。

我写了一个模拟滚动骰子的程序,直到你得到这些类型的卷之一并计算你需要掷骰子的次数。在做了1000次之后,我发现平均来说,你需要掷骰子53次才能看到一个不是一百的数字。这是代码:

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;
                }
            }
        }
    }
}

所以你的问题的答案是“你可能会看到它,但这不太可能,你必须运行 lot 程序才能看到它。”

希望这有帮助!

答案 1 :(得分:0)

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

答案 2 :(得分:0)

由于您循环1000次这一事实,偏差非常小。

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

答案 3 :(得分:0)

输出是在每个“骰子滚动”中找到数字的次数。就你使用伪随机数生成而言,数字生成被认为是“公平的”,因此你有一个“公平骰子滚动”,这意味着平均而言,每个数字在每个滚动上都有相同的机会出现。

因此,每个数字平均应出现在总卷数的近1/6倍,这就是您现在的结果。

如果增加总辊数,每个数字之间的偏差为1/6将会更大,并且与辊的数量类似。

答案 4 :(得分:0)

我猜你的原始问题是为什么你没有得到低于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以查看任何方。