You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

生日悖论概率计算结果为0,求教模拟实现方法及代码修正

问题诊断与解决方案

你的代码逻辑完全偏离了“23人中至少两人生日相同”的统计目标,现在的逻辑是拿第一个随机生日,和另外23个随机生日对比,统计和它重复的次数,最后算的是“随机23人和某特定人生日相同的比例”——这和你要的概率根本不是一回事,而且这种情况的概率本来就很低(约23/365≈6%),出现0的结果很正常。

正确的模拟思路

要计算目标概率,你需要重复做大量实验:

  • 每次实验生成23个随机生日
  • 检查这23个生日里是否存在至少一对重复的
  • 统计有重复的实验次数,除以总实验次数就是近似概率

修改后的代码

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

public class BirthdayProblem {
    // 全局Random实例,避免重复创建导致的随机性问题
    private static final Random rand = new Random();

    // 生成1-365的随机生日(用1-365更符合直觉,不影响结果)
    public static int generateBirthday() {
        return rand.nextInt(365) + 1;
    }

    // 判断一组23个生日中是否存在重复
    public static boolean hasDuplicateBirthday() {
        HashSet<Integer> birthdays = new HashSet<>();
        for (int i = 0; i < 23; i++) {
            int bd = generateBirthday();
            // HashSet添加失败说明生日已存在,直接返回true
            if (!birthdays.add(bd)) {
                return true;
            }
        }
        // 循环结束无重复,返回false
        return false;
    }

    public static void main(String[] args) {
        int totalExperiments = 10000; // 实验次数越多,结果越接近理论值
        int duplicateCount = 0;

        for (int i = 0; i < totalExperiments; i++) {
            if (hasDuplicateBirthday()) {
                duplicateCount++;
            }
        }

        double probability = (double) duplicateCount / totalExperiments;
        System.out.printf("23人中至少两人生日相同的模拟概率:%.4f%n", probability);
        System.out.println("理论概率约为:0.5073");
    }
}

关键细节解释

  • HashSet检测重复:HashSet不允许存储重复元素,add()方法在元素已存在时会返回false,这是检测重复最高效的方式之一,比逐个对比所有元素更简洁。
  • 复用Random实例:每次生成生日时复用同一个Random对象,避免短时间内多次创建Random导致的种子重复(默认种子为当前系统毫秒时间),保证随机性的均匀性。
  • 实验次数:10000次实验足够让结果接近理论值(约0.5073),你可以调整totalExperiments的数值,比如改为100000,结果会更精准,但运行时间会略有增加。

内容的提问来源于stack exchange,提问作者Prometheus

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 18:55:03