我正试图编写一些Python代码来计算n个滚动的m边公平骰子之和成为某个值或更大值的概率。输入是所有骰子卷的总和、所做的卷数和骰子上的边数。输出是掷骰子总数达到或超过该值的概率百分比。
我的计算基于我在这篇论文中找到的方程,并对任何被轧制多次的单面模具进行缩放:https://digitalscholarship.unlv.edu/cgi/viewcontent.cgi?article=1025
我做了一些“有效”的代码,但是当骰子有很多面时速度非常慢,所以只对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面的模具,你将不得不迭代100^4 = 100,000,000次......
我很确定有一些数学公式可以简化这段代码,使其运行速度快很多个数量级,但数学不是我最喜欢的科目,我不知道有任何公式或Python函数可以提供帮助。
快速看了一眼纸,被公式吓了一跳。以一种可能不同的方式实施,只需计算达到不同总数的频率:
from functools import lru_cache
@lru_cache(None)
def sum_freq(total, rolls, faces):
if not rolls:
return not total
return sum(sum_freq(total - die, rolls - 1, faces)
for die in range(1, faces + 1))
def probability_calculator(roll_total, num_of_rolls, dice_faces):
return sum_freq(roll_total, num_of_rolls, dice_faces) / dice_faces**num_of_rolls
您的“四个100面模具”演示:
prob_314 = probability_calculator(314, 4, 100)
prob_any = sum(probability_calculator(total, 4, 100)
for total in range(1, 401))
print(f'{prob_314:%}')
print(f'{prob_any:%}')
输出:
0.113564%
100.000000%
10个100面骰子的输出:
0.050065%
100.000000%
42个这样的100面骰子的输出:
0.000000%
100.000000%
在线试试吧!
我试图创建一个程序,掷2个骰子,给出和的数量,然后将它们相加。我得到了骰子的随机数,但是当它们相加(总和)时,总数是不正确的。 我尝试过更改,,我已经将总和更改为,但总和总是出错。如果有人可以查看代码,看看我是否将其他所有内容放在正确的位置。提前感谢。 这应该是掷骰子1,给我骰子1的面值,然后给我骰子2的面值,然后给我两个骰子的总数。
每次我运行程序,相同的数字为骰子出现。此外,我的while语句最终显示用户和计算机都赢了。我也只想有回合上升到五,然后程序显示游戏的获胜者。我如何获得它,以便只有数字较高的玩家赢得这一轮。
题目链接 Lintcode 题目描述 把 n 个骰子扔在地上,求点数和为 s 的概率。 解题思路 动态规划 使用一个二维数组 dp 存储点数出现的次数,其中 dp[i][j] 表示前 i 个骰子产生点数 j 的次数。 空间复杂度:O(N2) // java public List<map.entry> dicesSum(int n) { final int face = 6; fi
问题内容: 我需要一种方法来计算Python中长整数的第n个根。 我试过了,但是不起作用: OverflowError:long int太大,无法转换为float 有任何想法吗? 长整数是指真正的长整数,例如: 11968003966030964356885611480383408833172346450467339251 1960931441410456834630852911156774884
一、题目 把n个骰子扔在地上,所有骰子朝上一面的点数之和为s。输入n,打印出s 的所有可能的值出现的概率。 二、解题思路 解法一:基于通归求解,时间效率不够高。 先把n个骰子分为两堆:第一堆只有一个,另一个有n- 1 个。单独的那一个有可能出现从1 到6 的点数。我们需要计算从1 到6 的每一种点数和剩下的n-1 个骰子来计算点数和。接下来把剩下的n-1个骰子还是分成两堆,第一堆只有一个, 第二堆
买支笔 示例输入 5d10 7 10d6*1d3 所以我试着跟着 但显然,这只适用于单输入,如5d7。我做错了什么