Monte Carlo 模拟骰子 python

Monte Carlo simulation dices in python

我有一个与 Monte Carlo 基于掷 2 个骰子概率的模拟有关的问题。在 python 中编码时如何呈现总和大于 n 且小于 m 的事实?作为一个例子,我在 mathlab 中做了这个:

NT = 10^5; %number of throws
log = zeros(1,12);
for throw = 1:NT
    dices = ceil(6*rand(1,2));
    s = sum(dices);
    log(s) = log(s)+1;
end
p = 36*log(6:9)/NT;
s1 = sum(round(p))

在上面的例子中,我假设 n 是 5,m 是 10。

谢谢

见下文-

import numpy as np
NT = 10**5
n=5
m=10
x = np.random.randint(1, 12, NT)
s = sum((x>=n) & (x<=m))
p = s*1.0/NT
print(p)

在每个循环中,您要模拟两个独立的随机掷骰子。我的以下代码片段使用 list(如果您愿意,可以使用 dict)来存储 NT 模拟的结果:

import random

num_throws = 10**5  # NT
roll_log = [0] * 12  # Generate list for dice roll tallies

for i in range(num_throws):
    # Random integer between 1 and 6 inclusive for each dice
    dice_1 = random.randint(1, 6)
    dice_2 = random.randint(1, 6)

    # Sum the random dice and increment the tally for that particular roll total
    roll_sum = dice_1 + dice_2
    roll_log[roll_sum-1] += 1  # minus 1 because Python is 0-indexed

要处理结果数据,您可以通过 roll_log[roll-1] 访问结果列表中特定掷骰子的计数,其中 2 <= roll <= 12roll = 1 的概率为零,因为它2+ 个骰子是不可能的)。以下 for 循环只是一个示例,说明如果您不熟悉 Python:

中的枚举,如何访问 NT 模拟的结果
for i, tally in enumerate(roll_log):
    roll_prob = float(tally) / num_throws  # Experimental probability of roll
    roll = i + 1  # Since Python lists are 0-indexed
    print('{}: {}/{} = {}'.format(roll, tally, num_throws, roll_prob))

输出:

1: 0 / 100000 = 0
2: 2741 / 100000 = 0.02741
3: 5518 / 100000 = 0.05518
4: 8202 / 100000 = 0.08202
5: 11235 / 100000 = 0.11235
6: 14046 / 100000 = 0.14046
7: 16520 / 100000 = 0.1652
8: 13799 / 100000 = 0.13799
9: 11025 / 100000 = 0.11025
10: 8459 / 100000 = 0.08459
11: 5672 / 100000 = 0.05672
12: 2783 / 100000 = 0.02783

具体解决问题的最后一部分,找到掷骰子在 n = 5m = 10 之间的概率(不包含),这可以使用称为 的方法来完成列表切片:

n = 5
m = 10
                                 #    6      7      8      9
rolls_between = roll_log[n:m-1]  # [14046, 16520, 13799, 11025]
sum_rolls_between = sum(rolls_between)  # 55390
prob_between = float(sum_rolls_between) / num_throws  # 0.5539

注意: 最后一行 sum_rolls_betweennum_throwsfloat 转换对于获得十进制输出是必不可少的,因为Python 中两个整数之间的除法总是在应用数学 floor() 函数后产生整数输出。换句话说,如果不将这两个值之一更改为浮点值,结果将为 0。