0

我在上统计学课,我们经常遇到各种约束的“骰子问题”。这是一个概率问题,我需要使用蒙特卡罗方法来评估一个事件的概率。我知道我可以通过它整合我的方式,但我想编写一个程序,让我可以简单地修改我有多少个骰子,我做了多少卷以及这些骰子有多少面的约束。

这是我正在解决的问题之一。更简单,因为我不想因为我的代码编写“能力”而忘乎所以。

假设一个骰子每个有 9 个面。估计当你掷出 5 个骰子时,至少有 3 个骰子的值相同的概率。

这是我们给出的问题的通用模板:掷 X 个 n 面骰子,每个骰子的边数从 1 到 n。估计我们将获得 3 个或更多骰子并获得相同结果的概率。

我想为示例问题编写一个函数,比如说,它将一个整数 n 作为输入,它是每个骰子中的面数,并计算 3 个或更多骰子具有相同值的概率。我最大的问题是“至少 5 个中有 3 个”的约束。我已经查看了 Stackoverflow 上的其他类似问题,但没有一个真正与我息息相关。您将如何编写约束代码?我正在使用 Python 3.2。

class Die(object):
  def __init__(self, sides = 9):
    self.sides = sides

  def roll(self):
    return randint(1, self.sides)

我被困在这里。任何输入都是有帮助的,谢谢!

4

2 回答 2

2

我不认为我会在这里使用一个类。您只需生成掷骰子,然后检查是否应该计算掷骰子。在这种情况下,我会使用 aCounter来进行计数,以使代码更简洁:

from collections import Counter
from random import randint

def roll(ndice,nsides=9):
    return [randint(1,nsides) for _ in range(ndice)]

def count_it():
    c = Counter(roll(5))
    return c.most_common(1)[0][1] >= 3

ntries = 100000
print (sum(1 for _ in range(ntries) if count_it())/ntries)

在我看来,你有大约 10% 的机会。蒙特卡洛的诀窍在于确定你是否已经收敛。您可以使用不同数量的ntries. 您的品牌越大ntries,输出中的价差就越小。最终,当价差足够小时,您就可以肯定地说您已经收敛到了解决方案上。

于 2013-05-07T13:30:05.787 回答
0

只需多次使用您的 Die 类:

# roll a lot of dice!
myDie = Die(9) # 9 sides

roll_counts = {side:0 for side in range(1, myDie.sides + 1)} 

numRolls = int(1e6)
for x in xrange(numRolls):
    roll_counts[myDie.roll()] += 1

然后根据需要分析您的分布:

for side in sorted(roll_counts):
    side_pct = float(roll_counts[side]) / numRolls * 100
    print 'side {} comprised {}% of all rolls'.format(side, side_pct)

编辑:我知道这个解决方案不能解决你的作业问题,但希望它能给你提供掷骰子和数骰子所需的工具。您可能需要一次对多个骰子执行上述操作,并且有一种方法可以在每次掷骰时比较它们的相等性。

于 2013-05-07T13:33:50.017 回答