Generate a matrix of all possible outcomes for throwing n dice (ignoring order)
Asked Answered
H

2

7

In cases where order does matter, it's rather easy to generate the matrix of all possible outcomes. One way for doing this is using expand.grid as shown here.

What if it doesn't?

If I'm right, the number of possible combinations is (S+N-1)!/S!(N-1)!, where S is the number of dice, each with N sides numbered 1 through N. (It is different from the well known combinations formula because it is possible for the same number to appear on more than one dice). For example, when throwing four six-sided dice, N=6 and S=4, so the number of possible combinations is (4+6-1)!/4!(6-1)! = 9!/4!x5! = 126. How can I generate a matrix of these 126 possible outcomes?

Thank you.

Herzel answered 23/5, 2010 at 19:9 Comment(1)
Retagged to add dice and algorithm.Arbour
A
5

Here is code which gd047 and Marek were kind enough to provide.

S <- 6 
N <- 4 
n <- choose(S+N-1,N) 
outcomes <- t(combn(S+N-1,N,sort)) - matrix(rep(c(0:(N-1)),each=n),nrow=n)

Note: this is optimal in the sense that it does not try to generate all and then throw away the dupes. It actually generates only those that are required.

An explanation of why it works:

The possible numbers on the dice are 1 to N.

Suppose you are given a possible combination of the dice numbers: x1 , x2 , ..., xS where S is the number of dice.

Since the order does not matter, we can assume that

x1 ≤ x2 ≤ ..., ≤ xS.

Now consider the sequence x1, x2 + 1, x3 + 2, ..., xS + S-1.

(Eg: 1,1,1 becomes 1,1+1,1+2 = 1,2,3).

This new sequence has numbers from 1 to N+S-1 and all numbers are distinct.

This mapping from your dice sequence to new one we created is 1-1 and easily reversible.

Thus to generate a possible combination of S dice with numbers 1 to N, all you need to do is to generate all N+S-1 Choose S combinations of S numbers from 1, 2, ..., N+S-1. Given such a combination, you sort it, subtract 0 from the smallest, 1 from the second smallest and so on to get your dice number combination for S dice numbered 1 to N.

For instance, say N = 6 and S = 3.

You generate a combo of 3 numbers from 1 to 6+3-1 = 8, i.e 3 numbers from 1,2,...,8.

Say you get 3,6,7. This translates to 3, 6-1, 7-2 = 3,5,5.

If you got 1,2,8. This would translate to 1,1,6.

Incidentally, this mapping also proves the formula you have.

Arbour answered 23/5, 2010 at 20:7 Comment(3)
@Moron You are right!. I posted before reading your answer, noticing that there was not code in it. No doubt you answered first, so I'm adding my code as a comment to your answer. S <- 6 N <- 4 n <- choose(S+N-1,N) outcomes <- t(apply(combn(S+N-1,N),2,sort)) - matrix(rep(c(0:(N-1)),each=n),nrow=n)Horick
@gd047. Ok, I have edited my answer to add your code. Feel free to edit the answer if you feel it needs anything.Arbour
This is very comprehensive answer. One tip to the code: combn can apply a function to each combination, so apply(combn(S+N-1,N),2,sort) could be replaced with combn(S+N-1,N,sort).Cisalpine
C
1

Generaly you need to order each outcome from original expand.grid and then unique them, for example using apply:

X <- expand.grid(1:6,1:6,1:6,1:6)
dim(unique(t(apply(X,1,sort))))
#[1] 126   4

But you can be tricky and choose subset of all outcomes that are ordered:

X <- expand.grid(1:6,1:6,1:6,1:6)
dim(subset(X, Var1>=Var2 & Var2>=Var3 & Var3>=Var4))
# [1] 126   4

Second version is much faster.

Cisalpine answered 23/5, 2010 at 19:40 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.