这是 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。
顺便说一句,这个映射也证明了你的公式。