В случаях, где порядок действительно имеет значение, довольно легко генерировать матрицу всех возможных результатов. Один путь к тому, чтобы сделать это использует expand.grid
как показано здесь.
Что, если это не делает?
Если я прав, количество возможных комбинаций (S+N-1)!/S!(N-1)!
, где S является количеством игры в кости, каждый со сторонами N пронумеровал 1 через N. (Это отличается от известной формулы комбинаций, потому что для того же числа возможно появиться больше чем на одной игре в кости). Например, при броске четырех шестисторонних игр в кости, N=6 и S=4, таким образом, количество возможных комбинаций (4+6-1)!/4! (6-1)! = 9!/4! x5! = 126. Как я могу генерировать матрицу этих 126 возможных результатов?
Спасибо.
Вот код, который gd047 и Марек любезно предоставили.
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)
Примечание: это оптимально в том смысле, что он не пытается сгенерировать все, а затем выбросить дубликаты. Фактически он генерирует только те, которые требуются
.
Объяснение того, почему это работает:
Возможные числа на кубиках от 1 до N.
Предположим, вам дана возможная комбинация чисел на кубиках: x 1 , x 2 , ..., x S где S - количество игральных костей.
Поскольку порядок не имеет значения, мы можем предположить, что
x 1 ≤ x 2 ≤ ..., ≤ x S .
Теперь рассмотрим последовательность x 1 , x 2 + 1, x 3 + 2, ..., x S + С-1.
(Например: 1,1,1 становится 1,1 + 1,1 + 2 = 1,2,3).
Эта новая последовательность имеет номера от 1 до N + S-1, и все числа различны.
Это отображение вашей последовательности игральных костей на новую, которую мы создали, является 1-1 и легко обратимо.
Таким образом, чтобы сгенерировать возможную комбинацию из S кубиков с числами от 1 до N, все, что вам нужно сделать, это сгенерировать все N + S-1. Выберите S комбинаций из S чисел из 1, 2, ..., N + S. -1.Получив такую комбинацию, вы сортируете ее, вычитаете 0 из наименьшего, 1 из второго наименьшего и так далее, чтобы получить комбинацию чисел для S кубиков, пронумерованных от 1 до N.
Например, скажем, N = 6 и S = 3.
Вы генерируете комбинацию из 3 чисел от 1 до 6 + 3-1 = 8, то есть 3 чисел от 1,2, ..., 8.
Допустим, у вас 3,6,7. Это означает 3, 6-1, 7-2 = 3,5,5.
Если у вас 1,2,8. Это соответствует 1,1,6.
Между прочим, это отображение также доказывает имеющуюся у вас формулу.
Обычно вам нужно упорядочить каждый результат из исходной expand.grid
, а затем уникальных
их, например, используя apply:
X <- expand.grid(1:6,1:6,1:6,1:6)
dim(unique(t(apply(X,1,sort))))
#[1] 126 4
Но вы можете быть хитрым и выбрать подмножество всех результатов, которые упорядочены:
X <- expand.grid(1:6,1:6,1:6,1:6)
dim(subset(X, Var1>=Var2 & Var2>=Var3 & Var3>=Var4))
# [1] 126 4
Вторая версия намного быстрее.