0

Javaで誕生日のパラドックスをシミュレートしたい. 何らかの理由で、出力 (確率) が 1 に非常に近くなり続けます (例: シミュレーション (10)->0,9268)。最初に、シミュレーションが近いはずの確率を確認できます。私はかなり長い間コードの間違いを探していたので、あなたの誰かが私を助けてくれることを願っています. 私は誕生日のパラドックスの他のコードを調べましたが、どれも私の奇妙な出力を助けることができないようです. ps //TODO は無視してかまいません。コードを立ち上げて実行すると問題が解決します。よろしくお願いします!

static final int DAYS_IN_YEAR = 365;
static final int NUMBER_OF_SIMULATIONS = 500; 

LCG random;
HashSet<Integer> birthdaySet = new HashSet<Integer>();

BirthdayProblem2(){
    birthdaySet.clear();
    random = new LCG(); //random numbers between 0 and 1
}

int generateBirthday(){ //generates random birthday
    return (int) Math.round(Math.random()*DAYS_IN_YEAR); //TODO use LGC
}

double iteration(int numberOfStudents){ //one iteration from the simulation
    int sameBirthdays = 0;

    for (int i = 0; i < numberOfStudents; i++){
        int bd = generateBirthday();

        if (birthdaySet.contains(bd)){
            sameBirthdays++;
        } else {
            birthdaySet.add(bd);
        }           
    }
    return (double) sameBirthdays/numberOfStudents; //probability of two students having the same birthday
}

void simulation(int numberOfStudents){
    double probabilitySum = 0;
    for (int i = 0; i < NUMBER_OF_SIMULATIONS; i++){
        probabilitySum += iteration(numberOfStudents);
    }
    System.out.printf("For n=%d -> P=%.4f \n", numberOfStudents, probabilitySum/NUMBER_OF_SIMULATIONS);
}

private void start() {

    simulation(10); //should be about 0.1
    simulation(20); //should be about 0.4
    simulation(23); //should be about 0.5
    simulation(35); //should be about 0.8
}

public static void main(String[] argv) {
    new BirthdayProblem2().start();
}

}

4

2 に答える 2

4

birthdaySet反復間をクリアしていません。フィールドからローカル変数に変更すると、そのようなエラーを防ぐことができます。そもそもなぜフィールドとして必要なのですか?

別の注意として、generateBirthday使用する必要がありますRandom.nextInt(DAYS_IN_YEAR)。のインスタンスRandomは、フィールドとして最有力候補です。いったい、そのLCG random;線は何なのだろうか?

アップデート

iteration()同じ誕生日の生徒がいるかどうかについて、メソッドはブール値を返す必要があります。返される真の値の数を呼び出しの数で割ると、確率が等しくなります。

1 年の日数は比較的少ないため、ブール配列は よりも高速になるSetため、更新されたコードは次のとおりです。

private static final int DAYS_IN_YEAR = 365;
private static final int NUMBER_OF_SIMULATIONS = 500;
private Random rnd = new Random();
private int generateBirthday() {
    return this.rnd.nextInt(DAYS_IN_YEAR);
}
private boolean iteration(int numberOfStudents) { //one iteration from the simulation
    boolean[] present = new boolean[DAYS_IN_YEAR];
    for (int i = 0; i < numberOfStudents; i++) {
        int birthday = generateBirthday();
        if (present[birthday])
            return true;
        present[birthday] = true;
    }
    return false;
}
void simulation(int numberOfStudents){
    int count = 0;
    for (int i = 0; i < NUMBER_OF_SIMULATIONS; i++)
        if (iteration(numberOfStudents))
            count++;
    System.out.printf("For n=%d -> P=%.4f%n", numberOfStudents, (double)count/NUMBER_OF_SIMULATIONS);
}

サンプル出力

For n=10 -> P=0.1340
For n=20 -> P=0.4120
For n=23 -> P=0.5080
For n=35 -> P=0.8160
For n=10 -> P=0.1200
For n=20 -> P=0.4120
For n=23 -> P=0.5260
For n=35 -> P=0.8140
For n=10 -> P=0.1260
For n=20 -> P=0.3920
For n=23 -> P=0.5080
For n=35 -> P=0.7920

NUMBER_OF_SIMULATIONSに増加5_000_000:

For n=10 -> P=0.1167
For n=20 -> P=0.4113
For n=23 -> P=0.5075
For n=35 -> P=0.8145
For n=10 -> P=0.1168
For n=20 -> P=0.4113
For n=23 -> P=0.5072
For n=35 -> P=0.8142
于 2016-01-06T22:06:05.593 に答える