如何解决 Python 中的生日悖论问题?
How to tackle the Birthday Paradox Problem in Python?
我正在练习 Python 中的生日悖论问题。我已经 运行 多次了, 改变生日的随机数 和 **循环 运行 数字 **,但是 概率是 0 或 100%,我无法获得其他概率,如 50% 等。有人可以帮我查看我的代码,看看我做错了什么吗?非常感谢!!
from random import randint
from datetime import datetime, timedelta
first_day_of_year = datetime(2017, 1, 1)
num_of_ppl = 45
birthdays = []
# get 45 random birthdays list
for i in range(num_of_ppl):
new_birthday = first_day_of_year + timedelta(days = randint(0, 365))
birthdays.append(new_birthday)
# find if there's matched birthdays, run 10000 times
dups = 0
duplicates = set()
for i in range(10000):
for bday in birthdays:
if birthdays.count(bday) > 1:
duplicates.add(bday)
if len(duplicates) >= 1:
dups += 1
# calculate the probability
probability = dups/10000 * 100
print(probability)
如果每次都生成生日列表,概率是符合预期的。此外,我没有看到需要使用 datetime
或 set
对象,我只是用 int
s 和 bool
s 替换了它们而没有改变任何功能。此外,您可以使用列表推导式在一行中生成生日列表:
from random import randint
num_iterations = 10000
num_people = 45
num_duplicates_overall = 0
# generate a random birthday for each person, check if there was a duplicate,
# and repeat num_iterations times
for i in range(num_iterations):
# start with a new, empty list every time.
# get a list of random birthdays, of length num_people.
birthdays = [randint(0, 365) for _ in range(num_people)]
# Keep track of whether or not there was a duplicate for this iteration
was_duplicate = False
for bday in birthdays:
if birthdays.count(bday) > 1:
# We found a duplicate for this iteration, so we can stop checking
was_duplicate = True
break
if was_duplicate:
num_duplicates_overall += 1
probability = num_duplicates_overall / num_iterations
print(f"Probability: {probability * 100}%")
输出 num_iterations = 1000000
和 num_people = 23
:
Probability: 50.6452%
编辑:或者,有 this method 检查重复项,据说速度更快(但主要是我喜欢它,因为它在一条线上):
if len(birthdays) != len(set(birthdays)):
num_duplicates_overall += 1
因此,您的代码可能看起来像这样简单:
from random import randint
num_iterations = 10000
num_people = 45
num_duplicates_overall = 0
for i in range(num_iterations):
birthdays = [randint(0, 365) for _ in range(num_people)]
if len(birthdays) != len(set(birthdays)):
num_duplicates_overall += 1
probability = num_duplicates_overall / num_iterations
print(f"Probability: {probability * 100}%")
我正在练习 Python 中的生日悖论问题。我已经 运行 多次了, 改变生日的随机数 和 **循环 运行 数字 **,但是 概率是 0 或 100%,我无法获得其他概率,如 50% 等。有人可以帮我查看我的代码,看看我做错了什么吗?非常感谢!!
from random import randint
from datetime import datetime, timedelta
first_day_of_year = datetime(2017, 1, 1)
num_of_ppl = 45
birthdays = []
# get 45 random birthdays list
for i in range(num_of_ppl):
new_birthday = first_day_of_year + timedelta(days = randint(0, 365))
birthdays.append(new_birthday)
# find if there's matched birthdays, run 10000 times
dups = 0
duplicates = set()
for i in range(10000):
for bday in birthdays:
if birthdays.count(bday) > 1:
duplicates.add(bday)
if len(duplicates) >= 1:
dups += 1
# calculate the probability
probability = dups/10000 * 100
print(probability)
如果每次都生成生日列表,概率是符合预期的。此外,我没有看到需要使用 datetime
或 set
对象,我只是用 int
s 和 bool
s 替换了它们而没有改变任何功能。此外,您可以使用列表推导式在一行中生成生日列表:
from random import randint
num_iterations = 10000
num_people = 45
num_duplicates_overall = 0
# generate a random birthday for each person, check if there was a duplicate,
# and repeat num_iterations times
for i in range(num_iterations):
# start with a new, empty list every time.
# get a list of random birthdays, of length num_people.
birthdays = [randint(0, 365) for _ in range(num_people)]
# Keep track of whether or not there was a duplicate for this iteration
was_duplicate = False
for bday in birthdays:
if birthdays.count(bday) > 1:
# We found a duplicate for this iteration, so we can stop checking
was_duplicate = True
break
if was_duplicate:
num_duplicates_overall += 1
probability = num_duplicates_overall / num_iterations
print(f"Probability: {probability * 100}%")
输出 num_iterations = 1000000
和 num_people = 23
:
Probability: 50.6452%
编辑:或者,有 this method 检查重复项,据说速度更快(但主要是我喜欢它,因为它在一条线上):
if len(birthdays) != len(set(birthdays)):
num_duplicates_overall += 1
因此,您的代码可能看起来像这样简单:
from random import randint
num_iterations = 10000
num_people = 45
num_duplicates_overall = 0
for i in range(num_iterations):
birthdays = [randint(0, 365) for _ in range(num_people)]
if len(birthdays) != len(set(birthdays)):
num_duplicates_overall += 1
probability = num_duplicates_overall / num_iterations
print(f"Probability: {probability * 100}%")