2013-05-07 66 views
0

我处于统计类,并且我们经常因各种限制而给出“骰子问题”。这是一个概率问题,我需要通过使用蒙特卡罗方法来评估事件的概率。我知道我可以通过它整合我的方式,但我想编写一个程序,使我可以简单地修改约束条件,包括我有多少个骰子,多少个骰子以及这些骰子有多少个边。使用蒙特卡罗方法在Python 3.2中查找某个特定骰子输出的特定概率

这是我正在处理的问题之一。更简单,因为我不想被我的代码写成“能力”。

假设一个骰子各有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) 

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

+0

@MartijnPieters真的吗?但是,我还能如何确保掷骰子是公平和独立的? – user2227808 2013-05-07 13:12:45

+0

啊,现在我真的应该把我的脚从我的嘴里拿出来,读一下蒙特卡洛方法*先*。我的道歉,这是你*掷骰子的方法之一。 :-P – 2013-05-07 13:19:41

回答

2

我不认为我会在这里使用课堂。你只需生成骰子卷,然后检查骰子卷是否应该计数。在这种情况下,我会使用一个Counter做计数只是为了让代码更干净:

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,您的输出中的点差就越小。最终,当传播足够小时,你说你已经有一些确定的解决方案。

+0

感谢您的帮助!但是,您是否介意通过ntries解释您的意思?这是指我制作的卷数量?我看到你的观点,就像我获得的更好的平均数越多,但在技术上我认为我只做1卷。那会是1尝试吗? – user2227808 2013-05-07 14:01:13

+0

@ user2227808 - 你不能从1尝试任何东西。蒙特卡罗方法的基础是,你反复尝试,并从实际做实验中获得概率。所以是的,'ntries'是您的计算机正在滚动5个9面骰子的次数。 – mgilson 2013-05-07 14:23:15

0

只需使用模具类大量的时间:

# 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) 

编辑:我知道这个解决方案没有解决你的功课问题,但希望它能为您提供所需的工具,用于掷骰和计数骰子。很可能你需要一次完成多人死亡并且有一种比较他们在每次掷骰时的平等的方法。