7

在顺序确实很重要的情况下,生成所有可能结果的矩阵相当容易。这样做的一种方法是使用此处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 个可能结果的矩阵?

谢谢你。

4

2 回答 2

5

这是 gd047 和 Marek 提供的代码。

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)

注意:这是最佳的,因为它不会尝试生成所有然后丢弃欺骗。It actually generates only those that are required.

解释它为什么起作用:

骰子上可能的数字是 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 + 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 从 1、2、...、N+S-1 中选择 S 个数字的 S 组合。给定这样的组合,您对其进行排序,从最小的减去 0,从第二小的减去 1,依此类推,以获得编号为 1 到 N 的 S 骰子的骰子数组合。

例如,假设 N = 6 和 S = 3。

您生成从 1 到 6+3-1 = 8 的 3 个数字的组合,即 1,2,...,8 的 3 个数字。

假设你得到 3,6,7。这转换为 3、6-1、7-2 = 3、5、5。

如果你有 1,2,8。这将转化为 1,1,6。

顺便说一句,这个映射也证明了你的公式。

于 2010-05-23T20:07:00.767 回答
1

一般来说,您需要先从原始结果订购每个结果expand.grid,然后再订购unique它们,例如使用 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

第二个版本要快得多。

于 2010-05-23T19:40:26.813 回答