Formula per il lancio di dadi (forza non bruta)


14

Prima di tutto, non sono sicuro di dove pubblicare questa domanda. Sto chiedendo se un problema di statistica è NP-Complete e se non risolverlo a livello di codice. Lo sto postando qui perché il problema statistico è il punto centrale.

Sto cercando di trovare una formula migliore per risolvere un problema. Il problema è: se ho 4d6 (4 dadi a 6 facce ordinari) e li lancio tutti in una volta, rimuovo un dado con il numero più basso (chiamato "lancio"), quindi somma i restanti 3, qual è la probabilità di ogni possibile risultato ? So che la risposta è questa:

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 media è 12,24 e la deviazione standard è 2,847.

Ho trovato la risposta di cui sopra con la forza bruta e non so come o se esiste una formula per essa. Sospetto che questo problema sia NP-Complete e quindi possa essere risolto solo con la forza bruta. Potrebbe essere possibile ottenere tutte le probabilità di 3d6 (3 dadi a 6 facce normali), quindi inclinarli verso l'alto. Questo sarebbe più veloce della forza bruta perché ho una formula veloce quando tutti i dadi sono tenuti.

Ho programmato la formula per tenere tutti i dadi al college. Ne avevo chiesto al mio professore di statistica e aveva trovato questa pagina , che poi mi ha spiegato. C'è una grande differenza prestazionale tra questa formula e la forza bruta: 50d6 ha impiegato 20 secondi ma 8d6 ha fatto cadere gli arresti più bassi dopo 40 secondi (la memoria di Chrome si esaurisce).

Questo problema è NP-Complete? In caso affermativo, fornire una prova, in caso contrario fornire una formula di forza non bruta per risolverlo.

Nota che non so molto su NP-Complete, quindi potrei pensare a NP, NP-Hard o qualcos'altro. La prova della NP-completezza è inutile per me l'unica ragione per cui lo chiedo è di impedire alle persone di indovinare. E, per favore, mettiti a nudo con me dato che è da molto tempo che non mi occupo di questo: non ricordo le statistiche e potrei aver bisogno di risolverlo.

Idealmente sto cercando una formula più generica per il numero X di dadi con i lati Y quando N di loro viene lasciato cadere, ma sto iniziando con qualcosa di molto più semplice.

Modificare:

Preferirei anche la formula per emettere frequenze ma è accettabile solo l'output delle probabilità.

Per gli interessati ho programmato la risposta di Whuber in JavaScript sul mio GitHub (in questo commit solo i test utilizzano effettivamente le funzioni definite).


1
Questa è una domanda interessante Penso che dovrebbe essere in tema qui. Grazie per la vostra considerazione.
gung - Ripristina Monica

1
Sebbene l'impostazione sia interessante, non hai ancora posto una domanda responsabile: l'idea di completezza NP dipende dall'avere una classe di problemi, mentre ne hai descritto solo uno. Esattamente come vuoi generalizzare? Sebbene accenni al fatto che il numero di dadi potrebbe variare, sono possibili varie opzioni aggiuntive che potrebbero fornire risposte diverse: è possibile modificare il numero di facce, i valori sulle facce, il numero di dadi e il numero di dadi lanciati, tutti in vari modi con varie relazioni tra loro.
whuber

1
@whuber Non conosce alcuna teoria della complessità, ma penso che sia chiaro che sta chiedendo la famiglia di problemi generati cambiando il numero di dadi. Penso anche di avere un algoritmo efficiente per questo.
Andy Jones,

2
@Andy vedo che alla fine sta chiedendo "una formula più generica per X numero di dadi con lati Y quando N di loro viene lasciato cadere".
whuber

@whuber Hah! Apparentemente non è così chiaro come pensavo allora. Scusa colpa mia.
Andy Jones,

Risposte:


5

Soluzione

Lascia che ci siano dadi ciascuno che dia pari possibilità ai risultati 1 , 2 , ... ,n=4 . Permettere1,2,,d=6 sia il minimo dei valori quando tutti i n dadi vengono lanciati indipendentemente.Kn

Prendere in considerazione la distribuzione della somma di tutte le valori condizionali su K . PermetterenK sia questa somma. La funzione generatrice del numero di modi per formare un dato valore di X , dato che il minimo è almeno k , èXXk

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

Poiché i dadi sono indipendenti, la funzione generatrice del numero di modi per formare valori di X cui tutti i dadi mostrano valori di k o maggiore ènk

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

Questa funzione di generazione include termini per gli eventi in cui supera k , quindi è necessario sottrarli. Pertanto, la funzione generatrice del numero di modi per formare valori di X , dato KKkX , èK=k

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

Notando che la somma dei valori più alti è la somma di tutti i valori meno la più piccola, pari a X - K . La funzione di generazione deve quindi essere divisa per k . Diventa una funzione generatrice di probabilità al moltiplicarsi per la probabilità comune di qualsiasi combinazione di dadi, ( 1n1XKk :(1/d)n

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

Poiché tutti i prodotti e i poteri polinomiali possono essere calcolati in O(nlogn) (sono convoluzioni e quindi possono essere eseguiti con la trasformata di Fourier veloce discreta), lo sforzo computazionale totale è . In particolare,è un algoritmo temporale polinomiale.O(knlogn)


Esempio

Esaminiamo l'esempio nella domanda con e dn=4 .d=6

Formula per PGF di X condizionale su K k(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.

Alzandoli alla potenza come nella formula ( 2 ) producen=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

Le loro successive differenze nella formula sono(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.

The resulting sum in formula (4) is

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 This looks correct and you said that's it's quadratic. But it's been a few years since I took statistics (I'm primarily a programmer). So I'd like to fully understand this before marking it as the answer. Also I see you have p(nth is the smallest die) does this include if nth is tied with the smallest? Such as rolling all 3s.
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
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.