Java生日悖论算法

时间:2016-02-08 10:50:26

标签: java algorithm random

我做了一个着名的生日悖论的小实现,试图第一次找到两个随机生日(这里是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

3 个答案:

答案 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);
}