Formule pour larguer des dés (force non brute)


14

Tout d'abord, je ne sais pas où cette question doit être publiée. Je demande si un problème de statistique est NP-Complete et si ce n'est pas le résoudre par programme. Je le poste ici parce que le problème des statistiques est le point central.

J'essaie de trouver une meilleure formule pour résoudre un problème. Le problème est: si j'ai 4d6 (4 dés ordinaires à 6 faces) et que je les lance tous en même temps, retirez un dé avec le plus petit nombre (appelé "drop"), puis additionnez les 3 restants, quelle est la probabilité de chaque résultat possible ? Je sais que la réponse est la suivante:

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

La moyenne est de 12,24 et l'écart-type est de 2,847.

J'ai trouvé la réponse ci-dessus par force brute et je ne sais pas comment ou s'il existe une formule pour cela. Je soupçonne que ce problème est NP-Complete et ne peut donc être résolu que par la force brute. Il pourrait être possible d'obtenir toutes les probabilités de 3d6 (3 dés normaux à 6 faces) puis de les incliner vers le haut. Ce serait plus rapide que la force brute car j'ai une formule rapide lorsque tous les dés sont conservés.

J'ai programmé la formule pour garder tous les dés à l'université. J'avais interrogé mon professeur de statistique à ce sujet et il a trouvé cette page qu'il m'a ensuite expliquée. Il y a une grande différence de performances entre cette formule et la force brute: 50d6 a pris 20 secondes mais 8d6 baisse le plus bas crash après 40 secondes (le chrome manque de mémoire).

Ce problème est-il NP-Complete? Si oui, veuillez fournir une preuve, si non, veuillez fournir une formule de force non brute pour le résoudre.

Notez que je ne connais pas grand-chose à NP-Complete, donc je pense peut-être à NP, NP-Hard ou autre chose. La preuve de NP-Completeness est inutile pour moi, la seule raison pour laquelle je la demande est d'empêcher les gens de deviner. Et je vous en prie, car cela fait longtemps que je n'ai pas travaillé là-dessus: je ne me souviens pas des statistiques aussi bien que je pourrais avoir besoin de résoudre cela.

Idéalement, je recherche une formule plus générique pour le nombre X de dés avec les côtés Y lorsque N d'entre eux sont supprimés, mais je commence par quelque chose de beaucoup plus simple.

Éditer:

Je préférerais également la formule aux fréquences de sortie, mais elle n'est acceptable que pour les probabilités de sortie.

Pour ceux qui sont intéressés, j'ai programmé la réponse de whuber en JavaScript sur mon GitHub (dans ce commit, seuls les tests utilisent réellement les fonctions définies).


1
C'est une question intéressante. Je pense que cela devrait être sur le sujet ici. Merci pour votre considération.
gung - Réintégrer Monica

1
Bien que le paramètre soit intéressant, vous n'avez pas encore posé de question à laquelle vous pouvez répondre: l'idée de complétude de NP dépend du fait d'avoir une classe de problèmes, alors que vous n'en avez décrit qu'un seul. Exactement comment voulez-vous qu'il se généralise? Bien que vous laissiez entendre que le nombre de dés peut varier, diverses options supplémentaires sont possibles et peuvent donner des réponses différentes: vous pouvez modifier le nombre de visages, les valeurs sur les visages, le nombre de dés et le nombre de dés largués, tous de diverses manières avec diverses relations entre eux.
whuber

1
@whuber Elle ne connaît aucune théorie de la complexité mais je pense qu'il est clair qu'elle pose la question de la famille des problèmes générés par le changement du nombre de dés. Je pense aussi que j'ai un algorithme efficace pour cela.
Andy Jones

2
@Andy, je vois à la fin, elle demande "une formule plus générique pour le nombre X de dés avec Y côtés lorsque N d'entre eux sont lâchés".
whuber

@whuber Hah! Apparemment pas aussi clair que je le pensais alors. Désolé mon mauvais.
Andy Jones

Réponses:


5

Solution

Soit dés chacun donnant des chances égales aux résultats 1 , 2 , , d = 6 . Soit K le minimum des valeurs lorsque tous les n dés sont lancés indépendamment.n=41,2,,d=6Kn

Tenez compte de la répartition de la somme de tous les valeurs conditionnelles sur K . Soit X cette somme. La fonction génératrice du nombre de façons de former une valeur donnée de X , étant donné que le minimum est d'au moins k , estnKXXk

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

Puisque les dés sont indépendants, la fonction génératrice du nombre de façons de former des valeurs de où tous les n dés montrent des valeurs de k ou plus estXnk

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

Cette fonction de génération inclut des termes pour les événements où dépasse k , nous devons donc les soustraire. Par conséquent, la fonction génératrice du nombre de façons de former des valeurs de X , étant donné K = k , estKkXK=k

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

Constatant que la somme des valeurs les plus élevées est la somme de toutes les valeurs moins la plus petite, égale à X - K . La fonction génératrice doit donc être divisée par k . Il devient une fonction génératrice de probabilité lors de la multiplication par la chance commune de toute combinaison de dés, ( 1 / d ) n :n1XKk(1/d)n

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

Étant donné que tous les produits et puissances polynomiaux peuvent être calculés dans des opérations (ce sont des convolutions et peuvent donc être effectuées avec la transformée de Fourier rapide discrète), l'effort de calcul total est O ( kO(nlogn) . Il s'agit en particulier d'un algorithme polynomial temporel.O(knlogn)


Exemple

Reprenons l'exemple de la question avec et d = 6 .n=4d=6

La formule pour le PGF de X conditionnel à K k donne(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.

Les élever à la puissance comme dans la formule ( 2 ) produitn=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

Leurs différences successives dans la formule sont(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.

La somme résultante dans la formule est(4)

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

For example, the chance that the top three dice sum to 14 is the coefficient of x14, equal to

64×160=10/81=0.123456790123456.

It is in perfect agreement with the probabilities quoted in the question.

By the way, the mean (as calculated from this result) is 15869/129612.244598765 and the standard deviation is 13612487/16796162.8468444.

A similar (unoptimized) calculation for n=400 dice instead of n=4 took less than a half a second, supporting the contention that this is not a computationally demanding algorithm. Here is a plot of the main part of the distribution:

Figure

Since the minimum K is highly likely to equal 1 and the sum X will be extremely close to having a Normal(400×7/2,400×35/12) distribution (whose mean is 1400 and standard deviation is approximately 34.1565), the mean must be extremely close to 14001=1399 and the standard deviation extremely close to 34.16. This nicely describes the plot, indicating it is likely correct. In fact, the exact calculation gives a mean of around 2.13×1032 greater than 1399 and a standard deviation around 1.24×1031 less than 400×35/12.


1
Your answer is fast and is correct so I've marked it as the answer. Also in an edit I said it would also be nice to have frequencies if possible. For that you don't need to edit your answer since I can see that the 6^-4 multiplier is used to convert from frequency to probability.
SkySpiral7

6

Edit: @SkySpiral has had trouble getting the below formula to work. I currently don't have time to work out what the issue is, so if you're reading this it's best to proceed under the assumption it's incorrect.


I'm not sure about the general problem with varying numbers of dice, sides, and drops, but I think I can see an efficient algorithm for the drop-1 case. The qualifier is that I'm not completely sure that it's correct, but right now I can't see any flaws.

Let's start by not dropping any dice. Suppose Xn represents the nth die, and suppose Yn represents the sum of n dice. Then

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

Now suppose Zn is the sum of n dice when one die is dropped. Then

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)

If we define Mn to be distribution of the minimum of n dies, then

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

and we can calculate Mn using

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

Anyway, together this all suggests a dynamic programming algorithm based on Yn,Zn and Mn. Should be quadratic in n.

edit: A comment has been raised on how to calculate p(XnMn1). Since Xn,Mn1 can each only take on one of six values, we can just sum over all possibilities:

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

Similarly, p(Xn=k|Xn>Mn1) can be calculated by applying Bayes rule then summing over the possible values of Xn,Mn1.


1
+1 Cela semble correct et vous avez dit que c'était quadratique. Mais cela fait quelques années que je n'ai pas pris de statistiques (je suis principalement programmeur). Je voudrais donc bien comprendre cela avant de le marquer comme la réponse. Je vois aussi que vous avez p (nième est le plus petit dé) est-ce que cela inclut si nième est lié au plus petit? Tels que rouler tous les 3.
SkySpiral7

Good catch. If the nth die rolled is the same as the current minimum, we can regard that die as the one to be dropped. In which case the distribution is Yn1. I've swapped some (<)s for ()s to reflect this.
Andy Jones

Thank you. If I understand this correctly I think your formulas are the answer. However I don't know how to calculate p(X(n) > M(n-1)) (or the negation of it) or p(X(n)=k|X(n) > M(n-1)) so I can't use this answer yet. I'll mark this as the answer but I'd like more information. Can you edit your answer to explain these or should I post it as another question?
SkySpiral7

Edited my answer.
Andy Jones

1
Sorry I know it's been a year and a half but I've finally gotten around to implementing this formula into code. However the p(Z(n)=a) formula appears incorrect. Suppose 2 dice with 2 sides (drop lowest), what are the chances of the result being 1? The chance of X(n) being the smallest or tied is 3/4 and p(Y(n-1)=1) is 1/2 so that Z(n) returns at least 3/8 even though the correct answer is 1/4. The Z formula looks correct to me and I don't know how to fix it. So if it's not too much to ask: what do you think?
SkySpiral7

1

I have a reasonably efficient algorithm for this that, on testing, seems to match results of pure brute force while relying less heavily on enumerating all possibilities. It's actually more generalized than the above problem of 4d6, drop 1.

Some notation first: Let XNdY indicate that you are rolling X dice with Y faces (integer values 1 to Y), and considering only the highest N dice rolled. The output is a sequence of dice values, e.g. 43d6 yields 3,4,5 if you rolled 1,3,4,5 on the four dice. (Note that I'm calling it a "sequence," but the order is not important here, particularly since all we care about in the end is the sum of the sequence.)

The probability P(XNdY=S) (or more specifically, P(43d6=S)) is a simplified version of the original problem, where we are only considering a specific set of dice, and not all possible sets that add up to a given sum.

Suppose S has k distinct values, s0,s1,...,sk, such that si>si+1, and each si has a count of ci. For example, if S=3,4,4,5, then (s0,c0)=(5,1), (s1,c1)=(4,2), and (s2,c2)=(3,1).

You can calculate P(XNdY=S) in the following way:

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

That's pretty messy, I know.

The product expression i=0k1 is iterating through all but the lowest of the values in S, and calculating all the ways those values may be distributed among the dice. For s0, that's just (Xci), but for s1, we have to remove the c0 dice that have already been set aside for s0, and likewise for si you must remove h=0i1ch.

The sum expression j=0XN is iterating through all the possibilities of how many of the dropped dice were equal to sk, since that affects the possible combinations for the un-dropped dice with sk as their value.

By example, let's consider P[43d6=(5,4,4)]:

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

So using the formula above:

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

The formula breaks down on a domain issue when sk=1 and j=0 in the summation, leading to a first term of 00, which is indeterminate and needs to be treated as 1. In such a case, a summation is not actually necessary at all, and can be omitted, since all the dropped dice will also have a value of sk=1.

Now here's where I do need to rely on some brute force. The original problem was to calculate the probability of the sum being some value, and XNdY represents the individual dice left after dropping. This means you must add up the probabilities for all possible sequences S (ignoring ordering) whose sum is the given value. Perhaps there is a formula to calculate this across all such values of S at once, but I haven't even tried broaching that yet.

I've implemented this in Python first, and the above is an attempt to express it mathematically. My Python algorithm is accurate and reasonably efficient. There are some optimizations that could be made for the case of calculating the entire distribution of XNdY, and maybe I'll do that later.


As a programmer it might be easier for me to understand your Python code (although I've never used Python so it might be the same). Posting the code here is off topic but you could post a link to github etc.
SkySpiral7

1
Your answer may be correct and it seems to reduce the complexity from O(Y^X) to O((Y+X-1)!/(X!*(Y-1)!)) but it still isn't as efficient as whuber's answer of O(c*X*log(X)). Thanks for your answer though +1.
SkySpiral7
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.