计算投掷五个六面骰子时投掷五个不同数字的概率

时间:2018-02-08 15:27:57

标签: python probability dice

所以我刚刚从C ++开始学习python 4天,我有点卡在一个编码挑战上,正在计算投掷五个六面骰子时投掷五个不同数字的概率。 我做了很多研究,我尝试了很多方法,但仍然无法做到。 这是我的一段代码:

def numOne(roll):
  return len([dice1 for dice1 in roll if dice1 == 1])
def numTwo(roll):
  return len([dice2 for dice2 in roll if dice2 == 2])
def numThree(roll):
  return len([dice3 for dice3 in roll if dice3 == 3])
def numFour(roll):
  return len([dice4 for dice4 in roll if dice4 == 4])
def numFive(roll):
  return len([dice5 for dice5 in roll if dice5 == 5])
def numSix(roll):
  return len([dice6 for dice6 in roll if dice6 == 6])

r = range(1,7)
sample = [(i,j,k,l,m) for i in r for j in r for k in r for l in r for m in r]
event1 = [roll for roll in sample if  numOne(roll) == 1]
event2 = [roll for roll in sample if  numTwo(roll) == 1]
event3 = [roll for roll in sample if  numThree(roll) == 1]
event4 = [roll for roll in sample if  numFour(roll) == 1]
event5 = [roll for roll in sample if  numFive(roll) == 1]
event6 = [roll for roll in sample if  numSix(roll) == 1]

print (len(event1)*len(event2)*len(event3)*len(event4)*len(event5)*len(event6), "/" ,len(sample))

或者这个:

def numOne(roll):
  return len([dice1 for dice1 in roll if dice1 == 1])
def numTwo(roll):
  return len([dice2 for dice2 in roll if dice2 == 2])
def numThree(roll):
  return len([dice3 for dice3 in roll if dice3 == 3])
def numFour(roll):
  return len([dice4 for dice4 in roll if dice4 == 4])
def numFive(roll):
  return len([dice5 for dice5 in roll if dice5 == 5])
def numSix(roll):
  return len([dice6 for dice6 in roll if dice6 == 6])

r = range(1,7)
sample = [(i,j,k,l,m) for i in r for j in r for k in r for l in r for m in r]
event = [roll for roll in sample if numOne(roll)==1 and numTwo(roll)==1 and 
numThree(roll)==1 and numFour(roll)==1 and numFive(roll)==1 or 
numSix(roll)==1]

print(len(event) / len(sample))

当然,两者都是错的。我还没有放弃,如果我做了什么就会编辑,同时提出任何提示或建议。

这是一个更简单的例子来解释我想要达到的目的:计算我们掷三个骰子时有一个六的概率:

def numsix(roll):
      return len([dice for dice in roll if dice == 6])

r = range(1,7)
sample = [(i,j,k,l) for i in r for j in r for k in r for l in r]
event = [roll for roll in sample if numsix(roll)==1]
print(len(event) / len(sample))

1 个答案:

答案 0 :(得分:2)

如果你试图模拟概率,特别是滚动骰子,那么你应该使用一个名为Monte Carlo simulation的策略来包含随机性。

您的代码不包含任何随机性。排除两个代码示例计算错误结果的事实,它总是计算相同结果。如果不包括随机抽样,则表示您已事先知道将要发生的事情,并且您的问题将成为一个直接的计算。

Python是一种与C ++截然不同的动物。您不应该尝试使用您对面向对象语言的知识来使用解释性编程语言编写代码。

import random

same = 0
totalRolls = 100000

for i in range(1, totalRolls + 1):
    myRolls = []
    while len(myRolls) < 5:
        myRolls.append(random.randint(1, 6))
    if len(set(myRolls)) == 5:
        same += 1

print(same / totalRolls)

以上是使用蒙特卡罗方法超过100,000次迭代的解决方案示例。每次迭代'滚动'5个六面骰子,并将它们添加到列表中。然后它将列表转换为set并检查长度。设置删除重复项,因此“滚动”五个不同数字的唯一方法是设置长度为5.否则,重复。

我会阅读Python的文档,然后尝试修改代码,使其与上面的代码段类似。

修改:如果您要使用代码段查找平均预期值,则可以执行以下操作:

r = range(1,7)
sample = [(i,j,k,l,m) for i in r for j in r for k in r for l in r for m in r]

for i in sample:
    if len(set(i)) == 5:
        same1 += 1

print(same1 / len(sample))

...或者您可以使用数学方法:在第一卷上有6种可能的优惠结果。下一卷将有5个可能的优惠结果,滚动后有4个等等等等。这是6!。如果您将此数字除以每个滚动总数的总结果数,例如6*6*6*6*6 = 6^6您也会得到答案:0.0925925925...