Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

dice roll math with large n (>100)

Tags:

r

dice

I promise this is not just another dice rolling homework problem. I implemented a function to calculate the probability of obtaining less than a sum s when rolling n m-sided dice. My function works for small values of n but I am finding weird results for large values of n. See the attached plot. Anyone have insight into what is going on?

My probability function

Implemented from this math stack exchange

probability <- function(s, m, n) {

  i <- 0:((s-1-n) / m)
  m^(-n) * sum((-1)^i * choose(n, i) * choose(s - 1 - i * m, n))

}

Starts breaking with ~ n > 80

n <- 1:90 # number of dice
m <- 6 # number of sides
s <- floor(mean(1:m)*n) # sum of faces
p <- mapply(probability, s = s, m = m, n = n)
plot(n, p, main = paste("probability of rolling less than floor(", mean(1:m),"* n) as sum of n rolls of a", m, "sided dice"))

enter image description here

like image 610
Lief Esbenshade Avatar asked Apr 28 '20 20:04

Lief Esbenshade


People also ask

What happens if you roll a dice 100 times?

A "lucky number" in this case is any face of the die that occurs visibly more common than one would normally expect. If you roll a six-sided die 100 times, you expect the outcome to occur with ~16.6 results of 1, 2, 3, 4, 5, and 6 ea, on average.

What is the variance of 100 dice rolls?

Variances[100 dice rolls] = 100 * Variance[1 dice roll] = 291.

How do you calculate the probability of a dice roll?

In other words, the probability P equals p to the power n , or P = pⁿ = (1/s)ⁿ . If we consider three 20 sided dice, the chance of rolling 15 on each of them is: P = (1/20)³ = 0.000125 (or P = 1.25·10⁻⁴ in scientific notation).


1 Answers

As mentioned in the comments on the origianl question, the problem is that the probability function is asking R to calculate really huge numbers (choose(80,40) = 1.075072e+23) and we are hitting the numerical precision limits of R.

An alternative approach that doesn't involve huge numbers but instead uses lots of numbers is to run monte carlo simulations. This generates a distribution of dice roll sums and compare the observed sum to the distribution. It will take longer to run, but is much easier to do and will not have the numerical precision problems.

mc <- Vectorize(function(s, m, n, reps = 10000) {
  x <- replicate(reps, sum(sample(m, n, replace = TRUE)))
  ecdf(x)(s-1)
})



n <- 1:90 # number of dice
m <- 6 # number of sides
s <- floor(mean(1:m)*n) # sum of faces
analytic_prob <- mapply(probability, s = s, m = m, n = n)
mc_prob <- mapply(mc, s = s, m = m, n = n)


plot(n, analytic_prob, main = paste("probability of rolling less than floor(", mean(1:m),"* n) as sum of n rolls of a", m, "sided dice"),
     sub = "monte carlo in red")
points(n, mc_prob, col = "red")

enter image description here

like image 117
Lief Esbenshade Avatar answered Oct 23 '22 05:10

Lief Esbenshade