掷骰子的公式(非蛮力)


14

首先,我不确定该问题应该发布在哪里。我问一个统计问题是否是NP-Complete,如果不能以编程方式解决它。我将其发布在这里是因为统计问题是中心问题。

我正在尝试找到解决问题的更好公式。问题是:如果我有4d6(4个普通的6面骰子)并全部掷出,请移除一个具有最低编号的骰子(称为“掉落”),然后将剩余的3个相加,得出每个可能结果的概率是多少?我知道答案是这样的:

Sum (Frequency): Probability
3   (1):         0.0007716049
4   (4):         0.0030864198
5   (10):        0.0077160494
6   (21):        0.0162037037
7   (38):        0.0293209877
8   (62):        0.0478395062
9   (91):        0.0702160494
10  (122):       0.0941358025
11  (148):       0.1141975309
12  (167):       0.1288580247
13  (172):       0.1327160494
14  (160):       0.1234567901
15  (131):       0.1010802469
16  (94):        0.0725308642
17  (54):        0.0416666667
18  (21):        0.0162037037

平均值是12.24,标准偏差是2.847。

我通过蛮力找到了上述答案,但不知道如何或是否有公式。我怀疑这个问题是NP-Complete,因此只能通过蛮力解决。可能有可能获得3d6的所有概率(3个正常的6面骰子),然后将每个概率向上倾斜。这比蛮力要快,因为当所有骰子都放好时,我的公式很快。

我编写了将所有骰子留在大学的公式。我曾问过我的统计学教授,他找到了这个页面,然后他向我解释了。此公式与蛮力之间存在很大的性能差异:50d6花费了20秒,但8d6下降了40秒后的最低崩溃(chrome内存不足)。

这是NP完成问题吗? 如果是,请提供证明;如果否,请提供非蛮力公式来解决。

请注意,我对NP-Complete不太了解,所以我可能在考虑NP,NP-Hard或其他东西。NP完全性的证明对我来说毫无用处,我之所以要求它的唯一原因是防止人们猜测。并且请向我展示,因为我从事此工作已经很长时间了:我不记得统计数据,也可能需要解决这个问题。

理想情况下,当N个掉落时,我正在为X个带有Y边的骰子寻找更通用的公式,但从更简单的方法开始。

编辑:

我也更喜欢公式来输出频率,但是仅输出概率是可以接受的。

对于那些感兴趣的人,我已经在GitHub上的 JavaScript中编写了Whuber的答案(在此提交中,仅测试实际上使用了所定义的函数)。


1
这是个有趣的问题。我认为这里应该是主题。谢谢您的考虑。
gung-恢复莫妮卡

1
尽管设置很有趣,但是您尚未提出一个可回答的问题:NP完整性的想法取决于一问题,而您仅描述了一个问题。您究竟想如何概括它?尽管您暗示骰子的数量可以变化,但是可以使用各种其他选项,并且它们可能会产生不同的答案:您可以更改面孔的数量,面孔上的值,骰子的数量以及掉落的骰子的数量,所有这些以各种方式彼此之间有着各种关系。
whuber

1
@whuber她不了解任何复杂性理论,但我认为很明显,她正在询问由改变骰子数量而产生的一系列问题。我也认为我有一个有效的算法。
安迪·琼斯

2
@安迪,我确实看到最后她在问“对于当X个骰子中有N个掉落时,带有Y边的骰子数量更通用的公式”。
胡伯

@whuber哈!显然没有我当时想的那么清晰。对不起这是我的错。
安迪·琼斯

Answers:


5

要有骰子各给予同等机会的结果1 2 ... d = 6。当所有n个骰子独立抛出时,令K为值的最小值。n=41,2,,d=6Kn

考虑以K为条件的所有值之和的分布。令X为这个总和。假设最小值至少为k,则生成任意给定X值的方法数量的生成函数为nKXXk

(1)f(n,d,k)(x)=xk+xk+1++xd=xk1xdk+11x.

由于骰子是独立的,因此所有n个骰子都显示k或更大值的值形成方式的生成函数为Xnk

(2)f(n,d,k)(x)n=xkn(1xdk+11x)n.

此生成函数包括超过k的事件的项,因此我们需要将其减去。因此,给定K = k时,形成X值的方式数量的生成函数为KkXK=k

(3)f(n,d,k)(x)nf(n,d,k+1)(x)n.

请注意,最高值的总和是所有值的总和减去最小值,等于X - K。因此,生成函数需要除以k。通过乘以骰子1 / d n的任意组合的机会,它变为概率生成函数:n1XKk(1/d)n

(4)dnk=1dxk(f(n,d,k)(x)nf(n,d,k+1)(x)n).

由于所有多项式乘积和幂都可以用运算来计算(它们是卷积,因此可以使用离散快速傅立叶变换来执行),因此总的计算量为O kO(nlogn)。特别是,它是多项式时间算法。O(knlogn)


让我们研究问题中的示例,其中d = 6n=4d=6

为的PGF X条件上ķ ķ给出(1)XKk

f(4,6,1)(x)=x+x2+x3+x4+x5+x6f(4,6,2)(x)=x2+x3+x4+x5+x6f(4,6,5)(x)=x5+x6f(4,6,6)(x)=x6f(4,6,7)(x)=0.

如公式2 )所示将它们提高到n=4(2)

f(4,6,1)(x)4=x4+4x5+10x6++4x23+x24f(4,6,2)(x)4=x8+4x9+10x10++4x23+x24f(4,6,5)(x)4=x20+4x21+6x22+4x23+x24f(4,6,6)(x)4=x24f(4,6,7)(x)4=0

它们在公式中的连续差异为(3)

f(4,6,1)(x)4f(4,6,2)(x)4=x4+4x5+10x6++12x18+4x19f(4,6,2)(x)4f(4,6,3)(x)4=x8+4x9+10x10++4x20f(4,6,5)(x)4f(4,6,6)(x)4=x20+4x21+6x22+4x23f(4,6,6)(x)4f(4,6,7)(x)4=x24.

公式的结果之和为(4)

64(x3+4x4+10x5+21x6+38x7+62x8+91x9+122x10+148x11+167x12+172x13+160x14+131x15+94x16+54x17+21x18).

例如,前三个骰子总和为的机会是x 14的系数,等于14x14

64×160=10/81=0.123456790123456.

它与问题中引用的概率完全吻合。

顺便说一句,平均(从这个结果计算)为和标准差为15869/129612.24459876513612487/16796162.8468444

对于骰子(而不是n = 4)的类似(未优化)计算花费了不到半秒的时间,支持了以下论点:该算法对计算的要求不高。这是分布主要部分的图:n=400n=4

数字

由于最小很可能等于1并且总和X将是非常接近具有正常400 × 7 / 2 400 × 35 / 12 的分布(其平均为1400和标准偏差是约34.1565),则意味着必须非常接近1400 - 1 = 1399,标准偏差非常接近34.16。这很好地描述了该图,表明它可能是正确的。实际上,精确计算得出的平均值约为K1X(400×7/2,400×35/12)140034.156514001=139934.16大于 1399,标准偏差约 1.24 × 10 31小于2.13×103213991.24×1031400×35/12


1
您的答案是快速且正确的,因此我将其标记为答案。我也曾在编辑中说,如果可能的话,也要有频率。为此,您不需要编辑答案,因为我可以看到6^-4乘数用于将频率转换为概率。
SkySpiral7 '16

6

编辑:@SkySpiral无法使以下公式正常工作。我目前没有时间解决问题所在,因此,如果您正在阅读此书,则最好在不正确的假设下进行。


我不确定骰子,边数和掉落数的变化是否会引起普遍的问题,但是我认为我可以看到一个有效的算法来处理掉落1情况。限定词是我不能完全确定它是正确的,但是现在我看不到任何缺陷。

XnnYnn

p(Yn=a)=kp(Yn1=ak)p(Xn=k)

Znn

p(Zn=a)=p(nth die is the smallest)p(Yn1=a)+p(nth die is not the smallest)kp(Zn1=ak)p(Xn=k)

Mnn

p(Zn=a)=p(XnMn1)p(Yn1=a|XnMn1)+p(Xn>Mn1)kp(Zn1=ak)p(Xn=k|Xn>Mn1)

Mn

p(Mn=a)=p(XnMn1)p(Xn=a|XnMn1)+p(Xn>Mn1)p(Mn1=a|Xn>Mn1)

Yn,ZnMnn

p(XnMn1)Xn,Mn1

p(XnMn1)=a,bp(Xn=a,Mn1=b,ab)

p(Xn=k|Xn>Mn1)Xn,Mn1


1
+1这看起来很正确,您说的是二次方。但是距离我进行统计已经有几年了(我主要是一名程序员)。因此,在将其标记为答案之前,我想完全理解这一点。我也看到你有p(nth是最小的骰子),如果nth与最小的领带并列,这包括在内吗?例如滚动3s。
SkySpiral7

nYn1(<)()

谢谢。如果我正确理解这一点,我认为您的公式就是答案。但是我不知道如何计算p(X(n)> M(n-1))(或取反)或p(X(n)= k | X(n)> M(n-1) )),所以我还不能使用这个答案。我会将其标记为答案,但我需要更多信息。您可以编辑答案以解释这些问题,还是应该将其发布为另一个问题?
SkySpiral7 2014年

编辑了我的答案。
安迪·琼斯

1
抱歉,我已经过去一年半了,但是我终于可以解决这个问题了。但是,p(Z(n)= a)公式似乎不正确。假设2个骰子带有2个面(下降最低),结果为1的机会是多少?X(n)最小或平局的机会是3/4,而p(Y(n-1)= 1)的概率是1/2,因此即使正确的答案是,Z(n)至少返回3/8。 1/4。Z公式对我来说似乎是正确的,我不知道如何解决。因此,问的不是太多:您如何看待?
SkySpiral7'7

1

对于测试,我有一个相当有效的算法,该算法在测试上似乎与纯蛮力的结果相匹配,而不太依赖于枚举所有可能性。实际上,它比上述4d6问题(下降1)更为笼统。

XNdYXY1YN43d63,4,51,3,4,5在四个骰子上。(请注意,我称其为“序列”,但是这里的顺序并不重要,特别是因为最后我们只关心序列的总和。)

P(XNdY=S)P(43d6=S)

Sks0,s1,...,sksi>si+1siciS=3,4,4,5(s0,c0)=(5,1)(s1,c1)=(4,2)(s2,c2)=(3,1)

P(XNdY=S)

P(XNdY=S)=(i=0k1(Xh=0i1chci))(j=0XN(ck+XNck+XNj)(sk1)j)YX

我知道那太乱了。

i=0k1Ss0(Xci)s1c0s0sih=0i1ch

j=0XNsksk

P[43d6=(5,4,4)]

(s1,c1)=(5,1)
(s2,c2)=(4,2)

因此,使用上面的公式:

P[43d6=(5,4,4)]=(41)((33)30+(32)31)64=5162=0.0308641975¯

sk=1j=0001sk=1

XNdYSS

XNdY


作为程序员,我可能更容易理解您的Python代码(尽管我从未使用过Python,所以可能是一样的)。张贴在这里的代码是题外话,但你可以张贴一个链接到GitHub的等等
SkySpiral7

1
您的答案可能是正确的,并且似乎将复杂度从降低O(Y^X)到,O((Y+X-1)!/(X!*(Y-1)!))但效率仍不及O(c*X*log(X))。感谢您的回答,尽管+1。
SkySpiral7 '16
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.