【问题标题】:Simple Yahtzee simulation not giving proper result?简单的 Yahtzee 模拟没有给出正确的结果?
【发布时间】:2017-11-08 03:03:37
【问题描述】:

我正在学习 MIT OpenCourseWare 计算机编程入门课程,但我不确定我是否以正确的方式解决了简单的模拟问题。

  1. 滚动 Yahtzee 的概率是多少!在第一卷?也就是说,什么是 掷出五个 6 面骰子并让它们都显示相同数字的概率?
  2. 编写蒙特卡罗模拟来解决上述问题(Yahtzee 问题),然后 提交您的代码

所以滚动 Yahtzee 的概率是 1/1296 或大约 0.077%

这是我运行模拟的代码:

import random

def runYahtzee(numTrials):
    """Runs the classes version of the yahtzee simulation"""

    success = 0
    for i in range(numTrials):

        dices = []
        for i in range(6):
            dices.append(random.randrange(1,7))
        #print dices

        state = True
        for dice in dices:
            if dice != dices[0]:
                state = False
        if state == True:
            print "You got a Yahtzee"
            print dices
            success += 1

    print "numTrials is: " + str(numTrials)
    print "Success is: " + str(success)
    rate = float(success)/numTrials
    return rate

runYahtzee(10000000)

多次运行该程序,我每次都得到大约 .0001258。这是 0.012%,但实际概率约为 0.077%。我在这里做错了什么吗?

【问题讨论】:

  • 出于好奇,我做了一些研究,看看您确定一组骰子是否为 yahtzee 的方法是否可以改进,结果出奇的好!我预计 len(set(dice)) == 1 会更好,但这比它高出 2 倍。我还预计 functools.reduce(operator.eq, dice) 会更好,但这也将其排除在外。
  • @AdamSmith d0 = randrange(1,7); all(d0 == randrange(1,7) for _ in range(4)) 怎么样? (完全跳过骰子的创建)。 OP 的原始版本没有优化:一旦确定 state 为 False,您就可以跳出循环。
  • len(set(dice)) == 1 对我来说是最快的(Py3),但 random.choices(range(1, 7), k=5) 也比 5 * random.randrange(1, 7) 快。

标签: python python-2.7 simulation montecarlo


【解决方案1】:

你做错的是掷 6 个骰子而不是 5 个。

0.001258 * 6 = 0.0007548

...接近你的 0.077%

改变你的循环:

    for i in range(5):

顺便说一句,复数是dice;单数是diedices错误,除非你想变得有趣。在这种情况下,您可以使用单数“douse”...永远不要说死!

【讨论】:

    【解决方案2】:

    我是这样写的(Python 3):

    from collections import Counter
    from random import randint
    
    def roll():
        return randint(1, 6)
    
    def is_yahtzee(num_dice = 5):
        first = roll()
        return all(roll() == first for _ in range(1, num_dice))
    
    def montecarlo(fn, num_trials):
        return Counter(fn() for _ in range(num_trials))
    
    def main():
        num_trials = 10000000
        result = montecarlo(is_yahtzee, num_trials)
        prob = result[True] / num_trials
        print(
            "After {} trials, probability of Yahtzee is {:0.5f}%"
            .format(num_trials, 100. * prob)
        )
    
    if __name__ == "__main__":
        main()
    

    运行方式

    After 10000000 trials, probability of Yahtzee is 0.07605%
    

    请注意,保持函数简短通常会使它们更易于理解和测试。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-05-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-10-01
      • 2013-06-21
      相关资源
      最近更新 更多