Python I';我想做一个程序,显示掷N个骰子的样本空间
我正在尝试做一个程序,显示掷N骰子的样本空间,并写出每个骰子的结果,然后对样本空间中每个元素的每个骰子的结果求和,最后用和做一个直方图 我知道如何对少量的骰子进行操作,用手将Python I';我想做一个程序,显示掷N个骰子的样本空间,python,statistics,dice,Python,Statistics,Dice,我正在尝试做一个程序,显示掷N骰子的样本空间,并写出每个骰子的结果,然后对样本空间中每个元素的每个骰子的结果求和,最后用和做一个直方图 我知道如何对少量的骰子进行操作,用手将放入循环 3个骰子的示例: import numpy as np import matplotlib.pyplot as plt diceNum=3 # number of dices ss = 6**diceNum # number of elements of the sample space: throw
放入循环
3个骰子的示例:
import numpy as np
import matplotlib.pyplot as plt
diceNum=3 # number of dices
ss = 6**diceNum # number of elements of the sample space: throw n dices and write points of each dice. (n**N)
diceSum = []
diceThrow = []
nn=0 # to count the number of elements
# 3 for loops for each dice
for k in range(6):
for i in range(6):
for j in range(6):
dices = [k+1,i+1,j+1] # Result of throw the 3 dices
diceThrow.append(dices) # Sample space
diceSum.append(sum(diceThrow[nn])) #Sum each element of the sample space
nn=nn+1
print(diceThrow)
print(" ")
print(diceSum)
# Make a histogram with the sum of each element of the sample space
plt.hist(diceSum, bins = sm)
plt.grid()
plt.show()
我的问题是如何对N个骰子执行此操作,例如N=100,而不必手动将N放入循环中?对这个算法有什么想法吗?下面的函数生成样本空间列表。下面的print语句还显示了如何检索总和列表。在我的示例中,我没有将函数调用分配给要绘制的变量,但是您可以自己实现它。(我不是绝对正确的,因此如果这对您不起作用或您不理解,请让我知道)
如Bill所述,制作更直观的代码:
diceNum=10 # number of dices
ss = 6**diceNum # number of elements of the sample space: throw n dices and write points of each dice. (n**N)
diceSum = []
diceThrow = []
def roll_dice(diceThrow_n1)->list: # diceThrow_n1 is the list for n dices thrown
#check if it's the first dice
if diceThrow_n1 == []:
diceThrow_n2=np.array([[i] for i in range(1,7)])
else:
diceThrow_n2 = [] # list for n+1 thrown dices
for d in diceThrow_n1:
for t in range(1,7): # throw the n+1 dice
diceThrow_n2.append([*d,t])
return diceThrow_n2
for d in range(diceNum): # Throw diceNum dices
diceThrow = roll_dice(diceThrow)
diceSum = [sum(elm) for elm in diceThrow] # Sum each element of the sample space
掷骰接受掷骰列表除了接受所有列表入口并将另一次掷骰的结果添加到末尾之外,没有其他操作。(因此,每次执行函数时,diceThrow中的条目都乘以6)
让我们检查一下diceNum=2:
在first execute d=0(first dice throw)中,我们为roll_dice提供了一个空列表(dice throw=[])。所以掷骰子时,掷骰子时使用1…6(掷骰子=[[1]、[2]、[3]、[4]、[5]、[6]])。
现在d=1:
掷骰子开始时掷骰子=[[1]、[2]、[3]、[4]、[5]、[6]:
我们转到函数的另一部分。现在我们迭代列表中的所有条目。从d=[1]开始。(*列表前面给出了所有元素(*[a,b,c]=a,b,c)),它接受每个掷骰子并添加下一次掷骰子的结果。所以[1]得到了[1,1],[1,2],[1,3],…,[1,6]]。但1只是第一次投掷的一个可能结果,因此我们对其他所有可能结果都这样做,并以以下结果结束:
diceThrow = [[1 1]
[1 2]
[1 3]
[1 4]
[1 5]
[1 6]
[2 1]
[2 2]
[2 3]
[2 4]
[2 5]
[2 6]
[3 1]
[3 2]
[3 3]
[3 4]
[3 5]
[3 6]
[4 1]
[4 2]
[4 3]
[4 4]
[4 5]
[4 6]
[5 1]
[5 2]
[5 3]
[5 4]
[5 5]
[5 6]
[6 1]
[6 2]
[6 3]
[6 4]
[6 5]
[6 6]]
现在每增加一个骰子,就可以重复这个步骤。
在最后,我们像以前一样对每个条目进行求和,但是每次我们在diceThrow中创建一个新条目时都这样做,我们在最后这样做是为了防止我们多次这样做。
但问题开始了。这是非常无效的,因为python中的列表不是最快的。我们一次又一次地这样做。创建一个列表,创建一个更大的列表
一个更好但不那么直观的方法是使用numpy
diceNum=2
diceThrow = np.array(np.meshgrid(*([np.array([1,2,3,4,5,6])]*diceNum))).T.reshape(-1,diceNum)
diceSum = [sum(elm) for elm in diceThrow]
原则上,使用1,2,…,6]给出网格网格函数diceNum np.array,然后以获得diceNum骰子的方式对其进行重塑。
这里有一个很好的解释(对我有点启发xD),你可以在这里找到
但即使这样,我也会在diceNum>10的情况下进入长时间运行。也许其他任何人都有一个好主意,保持实用的方法,不使用任何分析理论。你说的“不用手放”是什么意思?不用为每个骰子写每个for循环。
diceNum=2
diceThrow = np.array(np.meshgrid(*([np.array([1,2,3,4,5,6])]*diceNum))).T.reshape(-1,diceNum)
diceSum = [sum(elm) for elm in diceThrow]