【问题标题】:Doing a Monte Carlo Analysis of the Birthday Paradox using a HashSet使用 HashSet 对生日悖论进行蒙特卡罗分析
【发布时间】:2015-06-15 14:36:31
【问题描述】:

免责声明:我不想要这个问题的答案。我只是需要一些指导。

我想使用 HashSet 对臭名昭著的生日悖论(确定给定组中至少 2 个人生日相同的概率)执行蒙特卡罗分析。

现在,当我运行此程序时,collisionCount 远低于我的预期。首先,我预计 10 人一组的 collisionCount 为 11446(或概率为 0.11446)。然后当我达到 100 人时,我预计碰撞计数为 100,000(概率为 1.0)。但是,对于每 10 人,collisionCount 仅按 1 计数(10 人:1 次碰撞,20 人:2 次碰撞,30 人:3 次碰撞,等等)。

这是我目前写的代码:

import java.util.HashSet;
import java.util.Random;
import java.util.Set;


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


    int tests = 100000;
    int collisionCount = 0;

    for(int people = 10; people <= 100; people += 10)
    {
        Set<Integer> birthdays = new HashSet<>(365);
        birthdays.add(rand.nextInt(365));
        for(int runs = 0; runs < tests; runs++)
        {
            int randomBirthday = rand.nextInt(365);

            if(birthdays.contains(randomBirthday))
            {
                collisionCount++;
                break;
            }
            birthdays.add(randomBirthday);
        }
        float prob = (float)collisionCount / tests;

            System.out.println("After " + tests + " tests there were " +
                               collisionCount + " occurrences of shared " +
                               " birthdays in a set of " + people + " people.");
            System.out.println("Probability : " + prob);
    }
  }  
 }

我想我的问题是:为了让 collisionCount 正确计数,我是否对我的任何一个 for 循环都没有做正确的事情?

我是学习 Java 的新手,我是 Stack Overflow 社区的新手,并且仍在学习中。非常感谢任何帮助/建议/提示。

【问题讨论】:

    标签: java for-loop hashset montecarlo birthday-paradox


    【解决方案1】:

    您的问题似乎是您缺少一个循环。

    请注意,您的 runs 循环因第一次碰撞而中断。这意味着你的值永远不会超过 1。

    此外,您永远不会在内部循环中使用您的 people 变量,除非在输出结果时。

    您需要做的是运行您的模拟100_000 次。这样做的方法是在您的 runs 循环中放置逻辑,检查 people 人是否会发生生日碰撞,然后迭代您的碰撞计数。

    【讨论】:

    • 我有一种感觉,我需要对人员变量做更多的事情。所以你是说我需要在我的运行循环中添加第三个循环(我以某种方式实现了 people 变量)才能真正完成所有 100,000 次运行?
    • 嗯,不,您需要添加另一个循环以确保您确实计算了所有人员。如果有帮助的话,现在你正在与 100,000 人一起跑步。
    • 您的意思是 100,000 次运行吗?我以为外部 for 循环不会超过 100 人?
    • 不,您所做的是试图获得 100,000 次新生日,但由于显而易见的原因,它在前 365 次的某个时候失败,导致一次重复计数。
    • 好的,所以我应该将 randomBirthday 移出内部 for 循环?
    【解决方案2】:

    我认为 java 解决方案不是最好的,这可能是您在模拟和数学值之间存在差异的问题。我对这个问题的理解是,您必须确定一组 10 人(在这种情况下)有多少人共享相同的生日。为此,您必须随机选择一个 10 的数组,其中数字从 0 到 365(一年中的天数),并计算其中有多少是相同的。您必须这样做几次(在您的情况下为 100000)。 我认为你必须颠倒 FOR 顺序。我的意思是..

    for(int runs = 0; runs < tests; runs++)
    {
        //initialize an array of 10
        for(int people = 0; people <= 10; people +=1)
        {
            //random birthdayDay
            //array [people] = rand.nextInt(365);
    
        }
        //check if there is a collision
        //If there is one you have to increase you success variable in 1   
     }
     //calculate the probability
    

    我试图帮助你,做一些伪代码。 希望对您有所帮助。

    问候

    阿图罗。

    【讨论】:

    • 我认为people应该是一个控制变量
    • 我认为在这种情况下是一样的,我前几天做了一个使用蒙特卡罗模拟的工作,我就是这样做的。我并不是说我是正确的,但我没有看到这样做的错误。
    猜你喜欢
    • 2020-01-28
    • 2021-11-27
    • 2017-09-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多