在订单确实重要的情况下,生成所有可能结果的矩阵相当容易。实现此目的的一种方法是使用expand.grid
,如here所示。
如果没有怎么办?
如果我是对的,可能组合的数量是(S+N-1)!/S!(N-1)!
,其中S是骰子的数量,每个骰子的编号为1到N.(它与众所周知的组合公式不同,因为它可以在多个骰子上出现相同的数字)。例如,当投掷四个六面骰子时,N = 6且S = 4,所以可能组合的数量是(4 + 6-1)!/ 4!(6-1)! = 9!/ 4!x5! = 126.如何生成这126种可能结果的矩阵?
谢谢。
答案 0 :(得分: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中选择S数的S组合-1。给定这样的组合,你可以对它进行排序,从最小的减去0,从第二个减去1,依此类推,得到你的骰子编号组合为1到N的S骰子。
例如,假设N = 6且S = 3.
您生成3个数字的组合,从1到6 + 3-1 = 8,即1,2,...,8中的3个数字。
说你得到3,6,7。这转换为3,6-1,7-2 = 3,5,5。
如果你有1,2,8。这将转化为1,1,6。
顺便说一句,这种映射也证明了你的公式。
答案 1 :(得分: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
第二版更快。