Fórmula para tirar dados (fuerza no bruta)


14

En primer lugar, no estoy seguro de dónde se debe publicar esta pregunta. Estoy preguntando si un problema de estadística es NP-Complete y si no es para resolverlo mediante programación. Lo estoy publicando aquí porque el problema de las estadísticas es el punto central.

Estoy tratando de encontrar una mejor fórmula para resolver un problema. El problema es: si tengo 4d6 (4 dados comunes de 6 lados) y los lanzo todos a la vez, elimino un dado con el número más bajo (llamado "caída"), luego sumo los 3 restantes, ¿cuál es la probabilidad de cada posible resultado? ? Sé que la respuesta es esta:

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

El promedio es 12.24 y la desviación estándar es 2.847.

Encontré la respuesta anterior por fuerza bruta y no sé cómo o si hay una fórmula para ello. Sospecho que este problema es NP-Complete y, por lo tanto, solo se puede resolver con la fuerza bruta. Es posible obtener todas las probabilidades de 3d6 (3 dados normales de 6 lados) y luego sesgar cada uno de ellos hacia arriba. Esto sería más rápido que la fuerza bruta porque tengo una fórmula rápida cuando se guardan todos los dados.

Programé la fórmula para mantener todos los dados en la universidad. Le pregunté a mi profesor de estadística al respecto y encontró esta página , que luego me explicó. Hay una gran diferencia de rendimiento entre esta fórmula y la fuerza bruta: 50d6 tardó 20 segundos pero 8d6 dejó caer los bloqueos más bajos después de 40 segundos (el cromo se queda sin memoria).

¿Es este problema NP-Complete? En caso afirmativo, proporcione una prueba, en caso negativo, proporcione una fórmula de fuerza no bruta para resolverlo.

Tenga en cuenta que no sé mucho sobre NP-Complete, por lo que podría estar pensando en NP, NP-Hard u otra cosa. La prueba de NP-Completeness es inútil para mí, la única razón por la que la pido es para evitar que la gente adivine. Y por favor, acépteme, ya que ha pasado mucho tiempo desde que trabajé en esto: no recuerdo las estadísticas tan bien como podría necesitar resolver esto.

Idealmente, estoy buscando una fórmula más genérica para el número X de dados con lados Y cuando N de ellos se caen, pero estoy comenzando con algo mucho más simple.

Editar:

También preferiría la fórmula a las frecuencias de salida, pero es aceptable solo generar probabilidades.

Para aquellos interesados, he programado la respuesta de whuber en JavaScript en mi GitHub (en este commit solo las pruebas realmente usan las funciones definidas).


1
Esta es una pregunta interesante. Creo que debería estar en el tema aquí. Gracias por su consideración.
gung - Restablece a Monica

1
Aunque la configuración es interesante, aún no ha formulado una pregunta que responda: la idea de la completitud NP depende de tener una clase de problemas, mientras que ha descrito solo uno. Exactamente, ¿cómo quieres que se generalice? Si bien insinúa que el número de dados podría variar, son posibles varias opciones adicionales y pueden dar diferentes respuestas: puede cambiar el número de caras, los valores en las caras, el número de dados y el número de dados que se cayeron, todo de varias maneras con varias relaciones entre ellos.
whuber

1
@whuber Ella no conoce ninguna teoría de la complejidad, pero creo que está claro que pregunta por la familia de problemas generados al cambiar el número de dados. También creo que tengo un algoritmo eficiente para ello.
Andy Jones

2
@Andy veo que al final está pidiendo "una fórmula más genérica para X número de dados con lados Y cuando N de ellos se caen".
whuber

@whuber Hah! Aparentemente no es tan claro como pensaba entonces. Perdón, es mi culpa.
Andy Jones

Respuestas:


5

Solución

Sea dados cada uno, lo que da las mismas oportunidades a los resultados 1 , 2 , ... , d = 6 . Deje que K sea el mínimo de los valores cuando todos los n dados son lanzados de manera independiente.n=41,2,,d=6Kn

Tenga en cuenta la distribución de la suma de todos los valores condicionales en K . Deje X ser esta suma. La función generadora para la cantidad de formas de formar cualquier valor dado de X , dado que el mínimo es al menos k , esnKXXk

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

Dado que los dados son independientes, la función generadora para la cantidad de formas de formar valores de donde todos los n dados muestran valores de k o mayores esXnk

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

Esta función de generación incluye términos para los eventos donde excede k , por lo que debemos restarlos. Por lo tanto, la función generadora para la cantidad de formas de formar valores de X , dado K = k , esKkXK=k

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

Tomando nota de que la suma de los valores más altos es la suma de todos los valores menos la más pequeña, igual a X - K . Por tanto, la función de generación necesita ser dividido por k . Se convierte en una función generadora de probabilidad al multiplicar por la posibilidad común de cualquier combinación de dados, ( 1 / d ) n :n1XKk(1/d)n

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

Dado que todos los productos y potencias polinomiales pueden calcularse en operaciones (son convoluciones y, por lo tanto, pueden llevarse a cabo con la Transformada rápida de Fourier discreta), el esfuerzo computacional total es O ( kO(nlogn) . En particular,es un algoritmo de tiempo polinómico.O(knlogn)


Ejemplo

El trabajo de Let través del ejemplo en la pregunta con y d = 6 .n=4d=6

La fórmula para el PGF de X condicional en K k da(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.

Elevándolos a la potencia como en la fórmula ( 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

Sus sucesivas diferencias en la fórmula son(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 suma resultante en la fórmula es(4)

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

Por ejemplo, la probabilidad de que los tres dados superiores sumen es el coeficiente de x 14 , igual a14x14

64×160=10/81=0.123456790123456.

Está en perfecto acuerdo con las probabilidades citadas en la pregunta.

Por cierto, la media (calculada a partir de este resultado) es y la desviación estándar es 15869/129612.244598765.13612487/16796162.8468444

Un cálculo similar (no optimizado) para dados en lugar de n = 4 tomó menos de medio segundo, lo que respalda la afirmación de que este no es un algoritmo computacionalmente exigente. Aquí hay una trama de la parte principal de la distribución:n=400n=4

Figure

Dado que el mínimo es muy probable que ser igual a 1 y la suma X será extremadamente cerca de tener una normal ( 400 × 7 / 2 , 400 × 35 / 12 ) de distribución (cuya media es 1,400 y la desviación estándar es de aproximadamente 34,1565 ), el la media debe ser extremadamente cercana a 1400 - 1 = 1399 y la desviación estándar extremadamente cercana a 34.16 . Esto describe muy bien la trama, indicando que es probable que sea correcta. De hecho, el cálculo exacto da una media de alrededorK1X(400×7/2,400×35/12)140034.156514001=139934.162.13×1032 greater than 1399 and a standard deviation around 1.24×1031 less than 400×35/12.


1
Su respuesta es rápida y correcta, así que la marqué como la respuesta. También en una edición dije que también sería bueno tener frecuencias si es posible. Para eso no necesita editar su respuesta ya que puedo ver que el 6^-4multiplicador se usa para convertir de frecuencia a probabilidad.
SkySpiral7

6

Editar: @SkySpiral ha tenido problemas para que funcione la siguiente fórmula. Actualmente no tengo tiempo para resolver cuál es el problema, así que si estás leyendo esto, es mejor proceder bajo el supuesto de que es incorrecto.


No estoy seguro sobre el problema general con diferentes números de dados, lados y caídas, pero creo que puedo ver un algoritmo eficiente para el caso de la caída de 1. El calificador es que no estoy completamente seguro de que sea correcto, pero en este momento no puedo ver ningún defecto.

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
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.