0

所以我正在尝试制作一个程序来创建一个房间里一群人生日相同的概率......我不知道如何创建这个函数。这是我到目前为止所拥有的

def birthday():
    mySet = set()
    x = 1
    for item in mySet:
        if item in mySet:
            return x
        else:
            mySet().append() # don't know what to do here.

编辑:

好吧,所以我想要完成的是使用一组使用数字 1 到 365 存储生日的函数......例如,如果你随机选择一个有 30 人的房间,他们可能不会有相同的生日。虽然,如果你在同一个房间里有双胞胎,你只需要房间里的 2 个人过相同的生日。所以最终我想要一个参数来多次测试这个函数并将它的平均值。不幸的是,我无法弄清楚如何做到这一点。我希望 x 成为房间里有多少人的计数器,当有匹配时,循环停止并停止。我也不知道要追加什么。

4

1 回答 1

1

您是否有理由尝试模拟此问题而不是使用封闭形式的解决方案来解决此问题?有一个相当不错的近似值,它快速且易于编码:

import math
def closed_form_approx_birthday_collision_probability(num_people):
    return 1 - math.exp(-num_people * (num_people - 1) / (2 * 365.0))

您还可以实现一个非常好的“精确”解决方案(在引号中,因为在转换为浮点数时会丢失一些保真度):

import operator
import functools
import fractions
def slow_fac(n):
    return functools.reduce(operator.mul, range(2, n+1), 1)

def closed_form_exact_birthday_collision_probability(num_people):
    p_no_collision = fractions.Fraction(slow_fac(365), 365 ** num_people * slow_fac(365 - num_people))
    return float(1 - p_no_collision)

要进行模拟,你会做这样的事情。我使用的是列表而不是集合,因为可能性的数量很小,这避免了使用集合会做的一些额外工作:

import random
def birthday_collision_simulate_once(num_people):
    s = [False] * 365
    for _ in range(num_people):
        birthday = random.randint(0, 364)
        if s[birthday]:
            return True
        else:
            s[birthday] = True
    return False

def birthday_collision_simulation(num_people, runs):
    collisions = 0
    for _ in range(runs):
        if birthday_collision_simulate_once(num_people):
            collisions += 1
    return collisions / float(runs)

我从模拟和封闭形式解决方案中获得的数字看起来类似于http://en.wikipedia.org/wiki/Birthday_problem上的表格

>>> closed_form_approx_birthday_collision_probability(20)
0.40580512747932584
>>> closed_form_exact_birthday_collision_probability(20)
0.41143838358058
>>> birthday_collision_simulation(20, 100000)
0.41108

当然,运行这么多的模拟更接近实际的 41.1%,计算速度要慢得多。我会选择一种封闭形式的解决方案,具体取决于它需要有多准确。

于 2013-10-24T01:05:05.063 回答