模拟抛硬币实验 - RealPython

时间:2018-01-30 00:53:11

标签: python python-3.x algorithm

有人可以帮我解释以下Realpython分配任务的解决方案吗?我发现的解决方案似乎令人困惑。

编写一个python脚本,使用抛硬币模拟来确定这个稍微复杂的概率难题的答案:我一直在翻转一个公平的硬币,直到我看到它至少每次都落在头部和尾部 - 换句话说,在我第一次翻转硬币之后,我继续翻转它直到我得到不同的结果。平均而言,我需要多少次翻转硬币?同样,实际的概率可以解决,但这里的重点是使用randint模拟事件。要获得预期的平均投掷数,您应该设置变量试验为10000并且变量flips为0,然后在每次掷硬币时将flips变量加1。然后,您可以在代码末尾打印翻转/试用,以查看平均翻转次数。

    from random import randint
    flips = 0
    trials = 10000
    for i in range(trials):
        first_flip = randint(0, 1)
        while randint(0, 1) == first_flip:
            flips += 1           # Every flip after the first flip.
    print("flips done is {}".format(flips))
    print(flips / trials + 2.0)  # Initial trial and final trial added.

在上述情况下,如果first_flip为0且while循环条件在第一次随机尝试时产生1,则for循环迭代而不添加翻转。此外,如果while循环在随机尝试等于first_flip时运行,则在while循环跟踪中,即" i"在for循环中没有添加。简而言之,翻转的最终数量多于或少于试验次数。

有人可以帮我解释一下这个或更好的python脚本背后的逻辑吗?

2 个答案:

答案 0 :(得分:2)

代码主要用于您的思考方式。您缺少的部分:

  

如果first_flip为0且while循环条件在第一次随机尝试时产生1,则for循环迭代而不添加翻转。

这在底部解决,

print(flips / trials + 2.0)  # Initial trial and final trial added.

他们在这里每次试用添加2个'缺失'翻转。

如果我编写了代码,我就会这样做。

flips = 0
def flip():
    global flips
    flips += 1
    return randint(0,1)

trials = 10000
for i in range(trials):
    first_flip = flip()
    while flip() == first_flip:
        pass

print("flips done is {}".format(flips))
print("average flips", flips / trials)

答案 1 :(得分:0)

我将其分解得有点不同。

对于每个试验,让我们假设第一次翻转为0.(它实际上并不重要,它对逻辑没有任何影响 - 所以我们只是假设这就是我们得到的东西,然后我们甚至不必翻转它。)然后我们一直翻转直到得到1。

当我们完成所有试验时,我们有一个未知数量的0(每次试验加上一个我们没有实际做过的0)加上每次试验一次。所以翻转的总数是{我们实际翻转的0的数量} + 2 * {试用次数},一旦我们有{试验次数} 1,我们就会停止。

from random import randint

def total_flips(trials):
    zeros = 0
    ones = 0
    while ones < trials:
        if randint(0, 1):
            ones += 1
        else:
            zeros += 1
    return zeros + 2 * trials

trials = 10000
flips = total_flips(trials)
print("Flips done:", flips)
print("Average flips:", flips / trials)