我想在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
)然后丢弃它们,但对于像这样的小问题,这样做的解决方案是可以接受的。
答案 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