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

Calculating the probability of throwing five different numbers when you throw five six-sided dice

所以我 4 天前才开始学习 python C++,我在一个编码挑战中遇到了困难,我正在计算当你掷五个六面骰子时掷出五个不同数字的概率。 我做了很多研究,尝试了很多方法,但还是做不到。 这是我的一段代码:

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

如果您正在尝试模拟概率,尤其是掷骰子,那么您应该使用一种称为 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)

以上是使用 Monte Carlo 方法超过 100,000 次迭代的解决方案示例。每次迭代 'rolls' 5 个六面骰子,并将它们添加到列表中。然后它将列表转换为 set 并检查长度。集合删除重复项,因此 'roll' 五个不同数字的唯一方法是集合的长度为 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...