Выполнение анализа Монте-Карло парадокса дня рождения с использованием HashSet

ОТКАЗ ОТ ОТВЕТСТВЕННОСТИ: Я НЕ ХОЧУ ОТВЕТА НА ЭТУ ПРОБЛЕМУ. МНЕ ПРОСТО НУЖЕН НЕКОТОРОЕ РУКОВОДСТВО.

Я хочу выполнить анализ Монте-Карло печально известного парадокса дней рождения (определение вероятности того, что по крайней мере 2 человека в данной группе имеют один и тот же день рождения), используя HashSet.

Теперь, когда я запускаю это, collisionCount НАМНОГО ниже, чем я ожидал. Во-первых, я ожидал, что collisionCount для группы из 10 человек будет 11446 (или вероятность 0,11446). Затем к тому времени, когда я дошел до 100 человек, я ожидал, что CollisionCount будет 100 000 (с вероятностью 1,0). Но вместо этого для каждых 10 человек столкновение считается только на 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);
    }
  }  
 }

Я предполагаю, что мой вопрос: я что-то не так делаю с любым из моих циклов for, чтобы заставить collisionCount правильно считать?

Я новичок в изучении Java, я новичок в сообществе Stack Overflow и все еще изучаю веревки. Любая помощь/совет/подсказка приветствуется.


person Brandon Dusch    schedule 10.04.2015    source источник


Ответы (2)


Ваша проблема заключается в том, что вам не хватает одной из ваших петель.

Обратите внимание, что ваш цикл runs прерывается при первом столкновении. Это означает, что ваше значение никогда не будет больше 1.

Кроме того, вы никогда не используете свою переменную people внутри внутреннего цикла, кроме как при выводе результатов.

Что вам нужно сделать, так это запустить симуляцию 100_000 раза. Чтобы сделать это, поместите логику в ваш цикл runs, который проверяет, будет ли у people людей столкновение в день рождения, а затем итерирует ваш счетчик столкновений.

person k_g    schedule 10.04.2015
comment
У меня было ощущение, что мне нужно сделать больше с моей переменной людей. Итак, вы говорите, что мне нужно добавить третий цикл в мой цикл прогонов (где я каким-то образом реализую переменную people), чтобы на самом деле выполнить все 100 000 прогонов? - person Brandon Dusch; 10.04.2015
comment
ну, нет, вам нужно добавить еще один цикл, чтобы убедиться, что вы действительно считаете всех своих людей. Прямо сейчас вы делаете один забег со 100 000 человек, если это поможет. - person k_g; 10.04.2015
comment
Вы имели в виду 100000 пробега? Я думал, что внешний цикл for будет охватывать не более 100 человек? - person Brandon Dusch; 10.04.2015
comment
нет, вы пытались получить новый день рождения 100 000 раз, и это потерпело неудачу в первые 365 раз по очевидным причинам, что привело к единственному двойному счету. - person k_g; 10.04.2015
comment
Итак, я должен переместить этот случайный день рождения из этого внутреннего цикла for? - person Brandon Dusch; 10.04.2015
comment
нет, он должен оставаться внутри. Я отредактирую свой ответ, включив в него еще несколько деталей, вернитесь через 5 минут. - person k_g; 10.04.2015
comment
@BrandonDusch это было отредактировано. Должно быть немного легче - person k_g; 10.04.2015
comment
Я попытался использовать третий цикл for, который перебирал бы 10, 20, 30 и т. д. людей, и цикл выполнения выполнялся 100 000 раз. Однако выходные данные теперь показывают, что было 100 000 столкновений с набором из 10 человек и до 1 000 000 столкновений для 100 человек. Предполагается, что это будет 11446 столкновений на 10 человек и до 100 000 столкновений на 100 человек. Разве я не повторяю количество столкновений, верно? - person Brandon Dusch; 11.04.2015

Я думаю, что 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

Я пытаюсь помочь вам, делая что-то вроде псевдокода. Надеюсь, что это поможет вам немного.

С Уважением

Артуро.

person Arturo Iglesias    schedule 10.04.2015
comment
Я думаю, что people должен быть контролируемой переменной - person k_g; 10.04.2015
comment
Я думаю, что то же самое и в этом случае, несколько дней назад я проделал работу, используя моделирование Монте-Карло, и я сделал это таким образом. Я не говорю, что я прав, но я не вижу ошибки в этом. - person Arturo Iglesias; 10.04.2015