生成M个箱中N个球的所有排列

时间:2014-11-21 15:23:27

标签: r permutation

我想在n个分区中生成一组m个球的排列。以下嵌套列表集生成这些排列。

n <- 3
m <- 4
v <- rep(0,m)
for (i in n:0){
  for (j in (n-sum(i)):0){
    for (k in (n-sum(i,j)):0){
      for (l in (n - sum(i,j,k)):0){
        v <- c(i,j,k,l)
        print(v)
        if (sum(v) == n){ break }
      }
    }
  }
}

打印解决方案:

[1] 3 0 0 0
[1] 2 1 0 0
[1] 2 0 1 0
[1] 2 0 0 1
[1] 1 2 0 0
[1] 1 1 1 0
[1] 1 1 0 1
[1] 1 0 2 0
[1] 1 0 1 1
[1] 1 0 0 2
[1] 0 3 0 0
[1] 0 2 1 0
[1] 0 2 0 1
[1] 0 1 2 0
[1] 0 1 1 1
[1] 0 1 0 2
[1] 0 0 3 0
[1] 0 0 2 1
[1] 0 0 1 2
[1] 0 0 0 3

排列的总数将为choose(n+m-1,m-1),排列的顺序对我来说无关紧要。但我很难将其变成一个可以使用任意数量的箱子的功能。 (我不会破坏我的尝试,但它只是嵌套循环的混乱。)所以,如果比我更saavy的人可以将上面的嵌套循环转换为函数,我会很感激。

或者,如果已经存在可用于执行此类排列的功能(或者遵循不同的算法),我将不胜感激。我更喜欢一种不会产生多余排列的方法(这里不会加起来n)然后丢弃它们,但对于像这样的小问题,这样做的解决方案是可以接受的。

2 个答案:

答案 0 :(得分:11)

library(partitions)
compositions(3,4)

# [1,] 3 2 1 0 2 1 0 1 0 0 2 1 0 1 0 0 1 0 0 0
# [2,] 0 1 2 3 0 1 2 0 1 0 0 1 2 0 1 0 0 1 0 0
# [3,] 0 0 0 0 1 1 1 2 2 3 0 0 0 1 1 2 0 0 1 0
# [4,] 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 2 2 2 3

答案 1 :(得分:1)

以下通过使用更通用的包iterpc

给出了略有不同但相当的答案
m = 4; n = 3
library(iterpc)
I = iterpc(m, n, replace=T)
getall(I)

输出是n个球的bin编号。

     [,1] [,2] [,3]
 [1,]    1    1    1
 [2,]    1    1    2
....
....
[18,]    3    3    4
[19,]    3    4    4
[20,]    4    4    4

第一行表示3个球全部来自bin 1,而最后一行表示3个球全部来自bin 4。

您可以通过计算1,2,3和4的数字轻松生成所需的结果。您还可以使用迭代器按顺序生成结果。

count <- function(x){
    as.numeric(table(factor(x, levels=1:m)))
}
I = iterpc(m, n, replace=T)


> count(getnext(I))
[1] 3 0 0 0
> count(getnext(I))
[1] 2 1 0 0
> count(getnext(I))
[1] 2 0 1 0
> count(getnext(I))
[1] 2 0 0 1
相关问题