【发布时间】:2021-10-18 19:38:27
【问题描述】:
长话短说,我正在掷不公平的骰子,并试图找出在 x 次掷骰后任何给定总和的概率。在实践中,有数百个面孔和数百个卷,所以我不能简单地找到所有可能的组合,然后找到概率,列出大小和内存限制。
我正在通过查找所有可能的组合以及它们一次出现 1 次掷骰的概率来解决这个问题。在我找到所有可能的组合和每个组合的概率后,我需要通过组合具有相同总和的组合概率来浓缩它。
认为组合 (1,3) 和 (2,2) 都是独特的组合,但它们的总和都是 4,如果 (1,3) 发生的概率是 3/6,那么(2,2) 出现的概率是 1/6 和 4 的连击概率是 4/6。
希望我不需要详细说明其工作原理及其背后的数学原理,但如果需要更多信息,请告诉我。
我已经明白了,我有一个列表,其中包含滚动后每种可能组合之一的总和,以及一个包含这些总和概率的全等列表。
对于我们的示例,它是这样的:
Sum of this rolls combos:
Sums = [6,4,2,5,4,3]
The congruent list of probabilities:
Probs = [11/36, 9/36, 7/36, 5/36, 3/36, 1/36]
在我们的实际示例中,数字没有也不能有公分母,并且是长小数,但我使用这些数字来显示我要查找的内容。
顺序很重要。我可以从总和列表中删除重复的总和并保持我需要的顺序:
Condenced_sums = []
For x in sums:
If x not in condenced_sums
condenced_sums.append(x)
这给了我们 Condensed_sums = [6, 4, 2, 5, 3]
我的问题是相应的概率不会消失,第一次出现的概率和任何重复出现的概率都不一样。为了确保每个总和的概率保持准确,在我删除重复出现的概率之前,我需要将它添加到原始出现的概率中。 理想情况下,压缩后的 prob 如下所示:
Condenced_prob = [11/36, 12/36, 7/36, 5/36, 1/36]
我在想也许我可以将列表压缩在一起并得到类似的东西:
Zipped_Sum_Prob = [(6, 11/36), (4, 9/36), (2, 7/36), (5, 5/36), (4, 3/36), (3, 1/36)]
然后可能在列表理解语句中使用 If else 语句,但我对此仍然很陌生,还没有想出一种方法来完成这项工作。
作为另一个说明,因为我不确定它是否会有所作为,任何总和都可能出现多次,而不仅仅是两次。
感谢任何帮助,即使这只是提出问题的更好方式。
谢谢!
编辑:
我认为提供更多关于我为什么需要维护订单的背景可能会更有用。这是我目前所拥有的:
假设 faces = [1,2,3] #实际上这是一个带有随机值的随机长度列表 new_faces = 面孔 卷=随机数 prob = [.5,.333333, .1666666] #这是随机概率的全等列表。 new_prob = 概率
#en stands for enumerated.
en_new_faces = [(index_2, y_face) for index_2, y_face in enumerate(new_faces)]
en_faces = [(index_1, x_face) for index_1, x_face in enumerate(faces)]
#Why new faces? For the first roll, the possible sums are the same as the value on the faces of the die, but on the second roll we start to have combos and a number of unique sums/possible outcomes is greater than the number of faces on the original die. On the 3ed roll we need to treat each unique sum like a face of one of our dice because each unique sum can be increased by any of the values on the faces of our original die, but we don’t need to apply this to each unique combo because adding 3 to combo (2 + 2) and adding 3 to (1 + 3) gives us the same outcome. So:
new_faces = list((w,x,y,z) for w, x in en_faces for y, z in en_new_faces if w
#rolls > 1 因为第一个滚动与面相同。 滚动 > 1
#new_list find the sum of combos that happen twice such as (1,3) & (3,1)
new_list = [(x+z) for w,x,y,z in new_faces if w != y]
#even_list finds the sum of combos that happen once such as (1,1) or (2,2). Even though the combos only happen once, the sum may not be unique.
even_list = [(x+z) for w,x,y,z in new_faces if w == y]
这些列表是分开的,因为偶数列表组合的概率是 (1/(len(faces)**rolls)),而 new_list 组合的概率是 (2/(len(faces)**rolls))
通过保持列表有序,我们可以保持它,这样无论我们经过多少次滚动,数字的第一个 len(faces) 的概率发生一次,new_faces 中剩余数字的概率发生两次。
Here is how i’ve been keeping it in order:
for (x) in even_list:
new_list.append(x)
new_list = list(reversed(new_list))
rolls = rolls - 1
这就引出了我的问题。
【问题讨论】:
-
将这些概率存储在
dict而不是list中可能会有所帮助。通常,尝试保持多个列表的排序“同步”比它的价值更麻烦。 -
@0x5453 感谢您的回复。我考虑过使用字典,但我不确定如何使用它来完成我想要完成的任务。我已经编辑了我的帖子,以显示是什么导致我提出我的问题。我不确定未知数量的面孔和滚动是否会成为问题。我认为这可能是因为我无法为每卷创建一个密钥或进行我正在尝试做的数学运算。
-
我猜百面骰子是您真正正在研究的问题的抽象表示;如果是这种情况,直接描述问题可能是个好主意。问题的表述可能比特定的编程方法更重要,因此 stats.stackexchange.com 是更多关于主题的问题。也就是说,请记住,根据中心极限定理,数百卷的总和将非常非常接近高斯,所以也许你可以大大简化计算。
-
另外,每个 pmf 或 pdf 的卷积中自变量之和的 pmf 或 pdf。与枚举所有可能性相比,评估卷积要容易得多。
-
@RobertDodier,感谢您的回复。骰子是抽象的。现实情况是,我试图估计股票在以后价值 x 的概率。在我的真实情况下,我们假设每天股票的价格变化都遵循标准差。这将使每 1 美分范围成为骰子上的“面”。价格在该范围内下跌的概率为滚动该面的概率,而滚动的次数为交易天数。我从来没有上过统计课,所以我可能遗漏了一些东西,但我不知道是什么。
标签: python python-3.x list list-comprehension probability