【发布时间】:2021-10-28 08:00:57
【问题描述】:
我正在尝试编写一些 Python 代码,该代码将计算 n 掷出的 m 面公平骰子之和为某个值或更大的概率。输入是所有掷骰子的总和、掷骰子的数量和骰子的边数。输出是骰子总和等于或大于该值的百分比机会。
我的计算基于我在本文中找到的方程式,并针对任何滚动任意次数的双面骰子进行缩放:https://digitalscholarship.unlv.edu/cgi/viewcontent.cgi?article=1025&context=grrj
我编写了一些“有效”的代码,但是当骰子有很多面时速度非常慢,所以只对 20 面或更少面的骰子有用。
import numpy as np
def probability_calculator(roll_total, num_of_rolls, dice_faces):
if num_of_rolls == 0:
probability = 100
elif num_of_rolls == 1:
probability = (dice_faces + 1 - roll_total) * 100/dice_faces
else:
inverse = (dice_faces ** num_of_rolls) ** -1
side_list = np.linspace(1, dice_faces, dice_faces)
expanded_list = np.zeros(dice_faces * num_of_rolls)
stacked_side_list = side_list
for i in range(num_of_rolls - 1):
stacked_side_list = np.vstack((stacked_side_list, side_list))
index_array = np.zeros(num_of_rolls, dtype=int)
while True:
value = 0
for i in range(num_of_rolls):
value = value + stacked_side_list[i][index_array[i]]
expanded_list[int(value) - 1] += 1
if sum(index_array) == (dice_faces - 1) * num_of_rolls:
break
for i in range(num_of_rolls):
if index_array[i] == dice_faces - 1:
index_array[i] = 0
else:
index_array[i] += 1
break
probability = inverse * sum(expanded_list[roll_total - 1:]) * 100
return probability
如您所见,这是非常低效的代码,如果您只滚动四个 100 面骰子,您将不得不遍历 while 循环 100^4 = 100,000,000 次.....
我很确定有一些数学方程式可以简化此代码并使其运行速度提高许多数量级,但数学不是我最喜欢的科目,我不知道有任何方程式或 Python 函数可以提供帮助。
【问题讨论】:
-
堆栈溢出非常适合需要调整代码和对计算的理解的人。但是,在您的情况下,只是您的代码的数学规模很差(是的,您确实在做数学!)。几乎所有编程都在一定程度上使用了一些数学,但您可能会在致力于数学或统计的社区中找到更好的帮助,例如数学或统计堆栈交换。您甚至可以指定您正在寻找一种可扩展的高性能算法。
-
请修正缩进。目前您的代码没有运行,如何修复它绝对不明显。
标签: python probability dice