2010-05-23 22 views
5

Dans les cas où l'ordre est important, il est plutôt facile de générer la matrice de tous les résultats possibles. Une façon de le faire est d'utiliser expand.grid comme indiqué here.Générer une matrice de tous les résultats possibles pour lancer n dés (en ignorant l'ordre)

Et si ce n'est pas le cas? Si j'ai raison, le nombre de combinaisons possibles est (S+N-1)!/S!(N-1)!, où S est le nombre de dés, chacun avec N côtés numérotés de 1 à N. (Il est différent de la formule des combinaisons bien connues car il est possible de le même numéro apparaîtra sur plus d'un dé). Par exemple, en lançant quatre dés à six faces, N = 6 et S = 4, le nombre de combinaisons possibles est (4 + 6-1)!/4! (6-1)! = 9!/4! X5! = 126. Comment puis-je générer une matrice de ces 126 résultats possibles?

Merci.

+0

Réenregistré pour ajouter des dés et un algorithme. –

Répondre

5

Voici le code que gd047 et Marek ont ​​eu la gentillesse de fournir.

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: ceci est optimal dans le sens où il ne cherche pas à tout générer puis à rejeter les dupes. It actually generates only those that are required.

Une explication des raisons pour lesquelles cela fonctionne:

Les numéros possibles sur les dés sont 1 à N.

Supposons que vous donne une combinaison possible du nombre de dés: x , x , ..., x S où S est le nombre de dés.

Puisque l'ordre n'a pas d'importance, on peut supposer que

x ≤ x ... ≤, ≤ x S.

Considérons maintenant la séquence x , x + 1, X + 2, ..., x S + S-1.

(par exemple: 1,1,1 devient 1,1 + 1,1 + 2 = 1,2,3).

Cette nouvelle séquence a des nombres de 1 à N + S-1 et tous les nombres sont distincts.

Cette correspondance entre votre séquence de dés et la nouvelle que nous avons créée est 1-1 et facilement réversible.

Ainsi, pour générer une combinaison possible de S avec les nombres 1 à N, tout ce que vous devez faire est de générer toutes les combinaisons S + S-1 S de S numéros de 1, 2, ..., N + S-1. Étant donné une telle combinaison, vous triez, soustrayez 0 du plus petit, 1 du second plus petit et ainsi de suite pour obtenir votre combinaison de dés pour les dés numérotés de 1 à N.

Par exemple, disons N = 6 et S = 3.

Vous générez un combo de 3 nombres de 1 à 6 + 3-1 = 8, soit 3 nombres de 1,2, ..., 8.

Disons que vous obtenez 3,6,7. Cela se traduit par 3, 6-1, 7-2 = 3,5,5.

Si vous avez 1,2,8. Cela se traduirait par 1,1,6. Par ailleurs, cette cartographie prouve également la formule que vous avez.

+0

@Moron Vous avez raison! J'ai posté avant de lire votre réponse, notant qu'il n'y avait pas de code dedans. Vous avez sans doute répondu en premier, alors j'ajoute mon code comme commentaire à votre réponse. N <- 4 n <- 4 n <- choisir (S + N-1, N) résultats <- t (appliquer (combn (S + N-1, N), 2, trier)) - matrice (rep (c (0: (N-1)), chacun = n), nrow = n) –

+0

@ gd047. Ok, j'ai édité ma réponse pour ajouter votre code. N'hésitez pas à modifier la réponse si vous pensez qu'elle a besoin de quelque chose. –

+1

Ceci est une réponse très complète. Une pointe au code: 'combn' peut appliquer une fonction à chaque combinaison, donc' apply (combn (S + N-1, N), 2, sort) 'pourrait être remplacé par' combn (S + N-1, N, trier) – Marek

1

Généralement vous devez commander chaque résultat de l'original expand.grid puis les unique, par exemple en utilisant appliquer:

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

Mais vous pouvez être difficile et choisissez sous-ensemble de tous les résultats qui sont classés:

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

La deuxième version est beaucoup plus rapide.

+0

+1 réponse très intelligente! – nico