Java:生日悖论

时间:2017-01-11 04:15:41

标签: java probability birthday-paradox

我正在尝试制作代表生日悖论的程序。我理解这个悖论,我很确定我的代码是错的,但我不确定我哪里出错了。我查看了相关帖子,但我没有发现任何有用的信息。我年轻的时候写了代码,很抱歉,如果有点乱。我知道还有其他方法可以做到这一点,我理解为什么这些工作。我只是想知道为什么我的代码不起作用。谢谢!

编辑:对不起,已经很晚了。忘了提出我的实际问题。我运行它是如何的,并期望得到约50.5%,这是理论值。但是,相反,我得到了大约21.1%。

public class Main {
    static int trialsSucceeded = 0; // Stores number of successful trials
    static final int TRIALS = 1000000; // 1,000,000 is a good number :) Biggest I've tried: 2,147,483,647, which is Integer.MAX_VALUE
    static int numberOfPeople = 23; // The 'n' value for the birthday paradox

public static void main(String[] args) {
    ArrayList<Integer> birthdays = new ArrayList<Integer>(); // Stores people's birthdays

    // Runs until desired trials are completed
    for (int trialNumber = 0; trialNumber < TRIALS; trialNumber++) {
        // Provides progress updates to user
        if (trialNumber % 1000 == 0)
            System.out.printf("%.1f%% complete\n", (double) trialNumber * 100 / TRIALS);

        // Populates the birthdays array
        for (int personNumber = 0; personNumber < numberOfPeople; personNumber++) {
            birthdays.add(getRandInt(1, 365));
        }

        // Used later to see if current trial should end
        int prevTrialsSucceeded = trialsSucceeded;

        // Checks each person's birthday against everyone else's
        for (int i = 0; i < birthdays.size(); i++) {
            for (int j = i + 1; j < birthdays.size(); j++) {
                // If birthdays match, marks trial as a success jumps to next trail
                if ((birthdays.get(i) == birthdays.get(j))) {
                    trialsSucceeded += 1;
                    break;
                }
            }
            // Jumps to next trial if this one has already succeeded
            if (prevTrialsSucceeded != trialsSucceeded) {
                break;
            }
        }
        // Clears list of birthdays to get ready for next trial
        birthdays.clear();
    }
    // Tells user ratio of successful trials to total trials
    System.out.println(((double) trialsSucceeded / TRIALS * 100) + "% of trials succeeded");
}

private static int getRandInt(int lowerBound, int upperBound) {
    // Returns random integer between lowerBound and upperBound
    Random random = new Random();
    return random.nextInt(upperBound - lowerBound + 1) + lowerBound;
}

}

2 个答案:

答案 0 :(得分:2)

根本问题是这一行:

if ((birthdays.get(i) == birthdays.get(j))) {

这是比较Integer个对象以确保身份相同。你需要做的是比较价值平等:

if ((birthdays.get(i).equals(birthdays.get(j)))) {

这应该会给你正确的结果,略高于50%。

答案 1 :(得分:1)

正如其他人的想法一样,你的问题根源于比较参考文献......但即使在解决这个问题时,这里的解决方案既不高效也不容易掌握。

有一种更简单的方法可以检查:只需使用Set来存储随机数生日而不是列表。但在添加下一个数字之前,您可以使用Set.contains()来检查该数字是否已在该集合中。如果是这样,你找到了一场比赛......你可以在那里停下来!