简体   繁体   English

使用java中的蒙特卡洛模拟找到x类中n个人共享同一生日的概率

[英]find probability of n people in a class of x share the same birthday using monte carlo simulation in java

As the problem states, i must use monte carlo(randomness) to solve the question given.正如问题所述,我必须使用蒙特卡洛(随机性)来解决给定的问题。 I am running the simulation 1,000,000 times.我正在运行模拟 1,000,000 次。

import java.util.*;

public class MonteCarlo {
    public static void main(String[] args) {
       Scanner sc = new Scanner(System.in);
       System.out.println("Please enter size of the class: ");
       int classSize = sc.nextInt();
       System.out.println("Please enter the amount of people who share the same birthday: ");
       int birthPpl = sc.nextInt();
       System.out.println("calculate the probability that "+birthPpl+" people share the same Birthday in a class size of "+classSize);
      
       sc.close();
       
       int birthdays [] = new int[classSize];
       int simulations = 0;
       int success=0;
       for(int i=0; i<1000000; i++){
            simulations++;
            if(Collision(birthdays)>=birthPpl){
                success++;
            }
       }
       System.out.println(success+" "+simulations);
       System.out.println("Answer: "+ (success*100)/simulations + "%");
    }

    public static int Collision(int birthday[]){
        Random rand = new Random();
        for(int i=1; i<birthday.length; i++){
            birthday[i]= rand.nextInt(365);
        }

        int count = 0;
        for(int i=0; i<birthday.length; i++){
            for(int j= i+1; j<birthday.length; j++){
                
                if(birthday[i]==birthday[j]){
                    count++;
                }
            }
        }
        return count;
    }
}

As per a couple of psuedo code solutions i have seen online i have tried looping through the size of the class x and inserting in a random birthday.根据我在网上看到的几个伪代码解决方案,我尝试遍历 x 类的大小并插入随机生日。 then comparing birthdays, reducing the birthdays i look through by 1 each time.然后比较生日,每次将我浏览的生日减 1。 I then check the number of collisions against the amount sof ppl who should a birthday, if it is greater or equal to it than i increase the count.然后我检查碰撞次数与应该过生日的人的数量,如果它大于或等于它,我会增加计数。 i have been given sample imput 20 and 2 which should give 41 % but my program gives eithe 7 or 8 %我得到了样本输入 20 和 2,它们应该给出 41%,但我的程序给出了 7 或 8%

What's the problem, and how can it be fixed?问题是什么,如何解决?

import java.util.*;
import java.lang.Math.*;
public class birthday{
 public static void main (String [] args){
  Scanner sc = new Scanner(System.in);
    int n = sc.nextInt(); //class size
    int x = sc.nextInt(); //people who share the same birthday
    double tests= 1000000;
    double success=0;


    //fills array of birthdays and breaks out when x amount of people share 
    //a birthday. then we find the % of successes.
    for(int i=0; i<tests; i++){
        int [] year = new int[365];
        for(int j =0; j<n; j++){
            int birthday = (int)(Math.random()*365);
            year[birthday]++;
            if(year[birthday]>=x){
                success++;
                break;
            }
        }
    }
    System.out.println(Math.round(success*100/tests));
  }
} 

You could also make use the Random and HashMap classes.您还可以使用RandomHashMap类。 Map.merge will take the key, a birthday in this case, then a default value of 1 , and continues to add 1 to the existing value which is returned and compared to x . Map.merge将采用键,在本例中为生日,然后是默认值1 ,并继续将1添加到返回的现有值并与x进行比较。 Then success is appropriately updated.然后适当更新成功。 The Random class provides a variety of methods to return random numbers and is usually preferred over Math.random. Random 类提供了多种返回随机数的方法,通常优于Math.random.

double success = 0;
int tests = 1_000_000;

// instantiate a Random class for selecting the next birthday
Random r = new Random();

// a map to hold the frequency count of same birthdays
Map<Integer,Integer> birthdays = new HashMap<>();


int n = 23;
int x = 2;

for(int i=0; i< tests; i++) {
   for (int j = 0; j < n; j++) {
       if (birthdays.merge(r.nextInt(365), 1, Integer::sum) >= x) {
           success++;
           break;
       }
   }
   // clear the map for the next run
   birthdays.clear();
}

Using System.out.printf facilitates formatting the output.使用System.out.printf有助于格式化输出。

System.out.printf("probability = %4.1f%%%n", (success/tests) * 100);

prints something like the following:打印如下内容:

probability = 50.7%

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM