Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/398.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 生日悖论_Java_Paradox_Birthday Paradox - Fatal编程技术网

Java 生日悖论

Java 生日悖论,java,paradox,birthday-paradox,Java,Paradox,Birthday Paradox,我想用java模拟生日悖论。出于某种原因,我的输出(概率)一直非常接近1,例如模拟(10)->09268。在开始时,你可以看到我的模拟应该接近的概率。我已经在我的代码中寻找一个错误很久了,所以我希望你们中的任何人都能帮助我。我查阅了生日悖论的其他代码,但似乎没有一个能帮助我处理奇怪的输出。 p、 你可以忽略//TODO,我会在代码启动并运行后修复它。 感谢是前进 static final int DAYS_IN_YEAR = 365; static final int NUMBER_OF_SIM

我想用java模拟生日悖论。出于某种原因,我的输出(概率)一直非常接近1,例如模拟(10)->09268。在开始时,你可以看到我的模拟应该接近的概率。我已经在我的代码中寻找一个错误很久了,所以我希望你们中的任何人都能帮助我。我查阅了生日悖论的其他代码,但似乎没有一个能帮助我处理奇怪的输出。 p、 你可以忽略//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();
}
年内的静态最终整数天=365;
模拟的静态最终整数=500;
LCG随机;
HashSet birthdaySet=新HashSet();
生日问题2(){
birthdaySet.clear();
random=new LCG();//0到1之间的随机数
}
int generateBirthday(){//生成随机生日
return(int)Math.round(Math.random()*年内天数);//TODO使用LGC
}
双迭代(int numberOfStudents){//模拟中的一次迭代
int sameberthdays=0;
for(int i=0;iP=%.4f\n”,numberofstudent,probabilitySum/numberofu模拟);
}
私有void start(){
模拟(10);//应该大约为0.1
模拟(20);//应该是0.4左右
模拟(23);//应该大约为0.5
模拟(35);//应该是0.8左右
}
公共静态void main(字符串[]argv){
新的生日问题2().start();
}

}

您没有在迭代之间清除
生日集。将它从一个字段更改为一个局部变量将防止出现这样的错误,因为为什么首先需要它作为一个字段

另一方面,
generateBirthday
应使用
Random.nextInt(一年中的天数)
Random
的实例是as字段的主要候选项。什么是
LCG随机行吗

更新

方法
iteration()
应返回布尔值,用于判断是否有学生的生日相同。返回的真值数除以调用数等于概率

由于一年中的天数相对较少,布尔数组将比
集合
快,因此更新代码如下:

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);
}
用于n=10->P=0.1200
对于n=20->P=0.4120
对于n=23->P=0.5260
对于n=35->P=0.8140
用于n=10->P=0.1260
对于n=20->P=0.3920
对于n=23->P=0.5080
对于n=35->P=0.7920
将模拟的数量增加到5个:

用于n=10->P=0.1167
对于n=20->P=0.4113
对于n=23->P=0.5075
对于n=35->P=0.8145
用于n=10->P=0.1168
对于n=20->P=0.4113
对于n=23->P=0.5072
对于n=35->P=0.8142

您没有在迭代之间清除
生日集。将它从一个字段更改为一个局部变量将防止出现这样的错误,因为为什么首先需要它作为一个字段

另一方面,
generateBirthday
应使用
Random.nextInt(一年中的天数)
Random
的实例是as字段的主要候选项。什么是
LCG随机行吗

更新

方法
iteration()
应返回布尔值,用于判断是否有学生的生日相同。返回的真值数除以调用数等于概率

由于一年中的天数相对较少,布尔数组将比
集合
快,因此更新代码如下:

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);
}
用于n=10->P=0.1200
对于n=20->P=0.4120
对于n=23->P=0.5260
对于n=35->P=0.8140
用于n=10->P=0.1260
对于n=20->P=0.3920
对于n=23->P=0.5080
对于n=35->P=0.7920
将模拟的数量增加到5个:

用于n=10->P=0.1167
对于n=20->P=0.4113
对于n=23->P=0.5075
对于n=35->P=0.8145
用于n=10->P=0.1168
对于n=20->P=0.4113
对于n=23->P=0.5072
对于n=35->P=0.8142

因为andreas已经声明,在迭代之间应该清除生日集,否则该集将包含来自上一次模拟的数据

然而,您的设计中还有另一个致命缺陷,请查看wikipedia页面:

在概率论中,生日问题或生日悖论涉及到在一组n个随机选择的人中,其中一些人的生日相同的概率。

有可能至少有两个人生日相同。这意味着只要2等于1,就应该返回1

我在下面的代码中总结了它

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

public class BirthdayProblem2 {
    static final int DAYS_IN_YEAR = 365;
    static final int NUMBER_OF_SIMULATIONS = 500;

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

    BirthdayProblem2() { random = new Random(); }

    int generateBirthday() { return random.nextInt(DAYS_IN_YEAR); }

    double iteration(int numberOfStudents) { //one iteration from the simulation
        birthdaySet.clear();

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

            if (birthdaySet.contains(bd)) {
                return 1.0;
            }

            birthdaySet.add(bd);
        }

        return 0.0;
    }

    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... whatever) { new BirthdayProblem2().start(); }
}
import java.util.HashSet;
导入java.util.Random;
公共课生日问题2{
年内的静态最终整数天=365;
模拟的静态最终整数=500;
随机;
HashSet birthdaySet=新HashSet();
生日问题2(){random=new random();}
int generateBirthday(){return random.nextInt(DAYS_IN_YEAR);}
双迭代(int numberOfStudents){//模拟中的一次迭代
birthdaySet.clear();
for(int i=0;i