我做了一个着名的生日悖论的小实现,试图第一次找到两个随机生日(这里是1到365之间的整数)之间的碰撞。 但它总是返回一个值,比如40和70,这根本不符合统计数据。 我的算法或随机int生成器都有问题吗?感谢您的反馈。
以下是代码:
public static void main(String[] args){
int[] birthday = new int[200];
for(int i = 0; i<20;i++){
Collision(birthday);
}
}
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++;
}
}
}
System.out.print(count+" ");
return count;
}
以下是ex:
的输出45 50 60 52 53 53 50 49 37 68 52 53 51 43 49 51 46 43 45 35
答案 0 :(得分:5)
编辑:
你在算法中基本上做的是你生成200个随机生日并计算它们之间存在多少碰撞。
你知道你可以通过使用Set
来简化事情,Set
在开头是空的。然后在一个简单的while循环生成生日(数字最多365),尝试在Set
中添加它们,并在第一次发生碰撞时 - 该数字已经在Random rand = new Random();
for (int t = 0; t < 20; t++)
{
Set<Integer> b = new HashSet<Integer>();
while (true)
{
int n = rand.nextInt(365);
if (!b.add(n))
break;
}
System.out.print(b.size() + " ");
}
- 你有你的回答(答案是Set的大小)。
也就是说,如果您的目标确实是在最少数量的生日中找到碰撞。
,例如:
15 30 24 4 8 19 10 40 32 31 30 14 41 30 15 7 15 52 24 27
产地:
ajax
答案 1 :(得分:3)
您的数字看起来相当合理。
但是你反复实例化一个新的Random
实例。这破坏了发电机的统计特性。在程序开始时执行一次。
(最终你也需要考虑2月29日,但这非常有二阶效应。)
答案 2 :(得分:0)
您的算法似乎没问题且结果合理。
仅供参考,你可以使用溪流非常有效地完成所有繁重的工作:
private static Random rand = new Random();
public static int collision(int size) {
return size - Stream.generate(() -> rand.nextInt(365)).limit(size).distinct().count();
}
一线主打:
public static void main(String[] args){
Stream.of(200).map(MyClass::collision).forEach(System.out::println);
}