[英]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.您还可以使用Random和HashMap类。 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.