代码之家  ›  专栏  ›  技术社区  ›  Brani

生成掷骰子的所有可能结果的矩阵(忽略顺序)

  •  5
  • Brani  · 技术社区  · 15 年前

    在顺序确实重要的情况下,很容易生成所有可能结果的矩阵。一种方法是使用 expand.grid 如图所示 here .

    如果没有呢?

    如果我是对的,可能的组合数是 (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个可能结果的矩阵?

    谢谢您。

    2 回复  |  直到 15 年前
        1
  •  5
  •   Yorgos    15 年前

    这是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 ,X ,…,X S 其中s是骰子的数目。

    既然订单无关紧要,我们可以假设

    X 小于x 小于,…x S .

    现在考虑序列x ,X + 1,X + 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数字的组合。给定这样一个组合,你将它排序,从最小的减去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。

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

        2
  •  1
  •   Marek    15 年前

    一般来说,你需要从原始数据中对每个结果进行排序。 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
    

    第二个版本更快。