概率论中生日问题的代码实现

一:组合理论

生日问题是一个经典的概率论问题,它探讨的是在一定数量的人中,至少有两个人在同一天生日的概率。这个问题的直观答案往往与实际计算结果大相径庭,因此被称为“悖论”。

具体来说,生日问题是这样的:在一个房间里,需要至少有多少人,才能使得至少有两人在同一天生日的概率超过50%?

直观上,人们可能会认为需要接近一年中的一半人数,即大约182人(因为一年有365天,所以182是365的一半多一点),才能达到50%的概率。但实际上,这个数字要小得多。

通过计算可以得出,当房间里有23人时,至少有两个人在同一天生日的概率就超过了50%。这个结果通常让人感到惊讶,因为它远低于直觉上的预期。

生日问题的计算通常按照以下步骤进行:

1. 计算第一个人不与其他人生日相同的概率。
2. 计算第二个人不与前面所有人生日相同的概率。
3. 将这些概率相乘,得到所有人生日都不相同的概率。
4. 然后用1减去这个概率,得到至少有两个人生日相同的概率。

这个问题在概率论和统计学中经常被用来说明直觉在概率估计中的不可靠性。

对生日问题的结果进行可视化分析是一个很好的想法。我们可以通过绘制一个图表来展示随着群体人数的增加,至少有两个人生日相同的概率是如何变化的。这样的图表可以帮助我们更直观地理解这个概率是如何随着人数的增加而迅速上升的。

要使用Python进行生日问题的概率计算并可视化展示,可以使用matplotlib库来绘制概率随人数增加而变化的图表。

import matplotlib.pyplot as plt
from scipy.special import comb

# 一年中的天数
DAYS_IN_YEAR = 365

# 计算至少有两个人在同一天生日的概率
def birthday_probability(n):
    # 计算没有人有相同生日的概率
    prob_no_match = 1
    for i in range(n):
        prob_no_match *= (DAYS_IN_YEAR - i) / DAYS_IN_YEAR
    # 至少有两个人有相同生日的概率
    prob_match = 1 - prob_no_match
    return prob_match

# 绘制图表
def plot_probability():
    # 人数范围
    people = range(1, 100)
    # 计算每个人数下的概率
    probabilities = [birthday_probability(n) for n in people]

    # 绘制概率随人数增加的变化
    plt.plot(people, probabilities, marker='o')
    plt.title('Birthday Paradox Probability')
    plt.xlabel('Number of People')
    plt.ylabel('Probability of Shared Birthday')
    plt.axhline(0.5, color='r', linestyle='--')
    plt.axvline(23, color='g', linestyle='--')
    plt.text(23, 0.5, '50% Probability', color='red')
    plt.text(23, 0.5, '23 People', color='green')
    plt.grid(True)
    plt.show()

# 运行绘图函数
plot_probability()

可视化结果如下:

这个图表显示了随着人数增加,至少有两个人在同一天生日的概率是如何变化的。图表中还包括了一条红色虚线,表示50%的概率阈值,以及一条绿色虚线,表示达到这个阈值所需的人数(23人)。

二:生成随机数

import matplotlib.pyplot as plt
import random

group_sizes = range(2, 101)
probabilities = []

def simulate_birthday_problem(num_people, num_trials):
    same_birthday_count = 0

    for _ in range(num_trials):
        birthdays = set()
        for _ in range(num_people):
            birthday = random.randint(1, 365)
            if birthday in birthdays:
                same_birthday_count += 1
                break
            birthdays.add(birthday)

    return same_birthday_count / num_trials

for size in group_sizes:
    probability = simulate_birthday_problem(size, 10000)
    probabilities.append(probability)

plt.figure(figsize=(10, 6))
plt.plot(group_sizes, probabilities, marker='o')
plt.title("Birthday Problem: Probability of at Least Two People Having the Same Birthday")
plt.xlabel("Number of People in the Group")
plt.ylabel("Probability")
plt.grid(True)
plt.show()

这段代码用于模拟生日问题。主函数接受两个参数:num_people(组中的人数)和num_trials(模拟试验的次数)。

  • same_birthday_count变量用于记录在所有模拟试验中,至少有两个人生日相同的次数。
  • 外层循环执行了num_trials次试验。
  • 内层循环为组中的每个人随机生成一个生日(用一个1到365之间的随机整数表示)。
  • 如果生成的生日已经在birthdays集合中,说明有两个人生日相同,这时增加same_birthday_count的计数,并退出内层循环。
  • 如果没有重复,就将这个生日添加到集合中。
  • 函数返回的是在所有试验中至少有两个人生日相同的频率,即same_birthday_count除以num_trials

可视化结果如下:

从这个折线图中,我们可以清楚地看到随着群体人数的增加,至少有两个人生日相同的概率是如何迅速上升的。特别值得注意的是,当群体人数达到大约23人时,这个概率已经超过了50%。这个可视化结果直观地展示了生日问题中的概率变化,帮助我们更好地理解这个经典的概率论问题。

想要探索更多元化的数据分析视角,可以关注之前发布的相关内容。

  • 7
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值