【发布时间】:2014-11-21 15:23:27
【问题描述】:
我想在m 箱中生成一组n 球的排列。下面的一组嵌套列表会生成这些排列。
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),排列的顺序对我来说并不重要。但是我很难把它变成一个可以接受任意数量的垃圾箱的函数。 (我不会用我的尝试破坏井,不过它只是嵌套循环的混乱。)因此,如果有人比我更精明,可以将上面的嵌套循环转换为函数,我将不胜感激。
或者,如果已经有一个函数可用于执行这种类型的排列(或要遵循的不同算法),我将不胜感激。我更喜欢一种不会产生多余排列的方法(这里加起来不等于n)然后丢弃它们,但对于像这样的小问题,这样做的解决方案是可以接受的。
【问题讨论】:
-
一种方法,当然不是最有效但比多个嵌套 for 循环更好,是:
x <- expand.grid(rep(list(0:n), m)); x[rowSums(x) == n,] -
谢谢@beginneR!我在使用
expand.grid时遇到了我想要的问题,不过这个例子对我来说有点清楚。 -
永远不要永远重新发明一个明显的轮子。各种包装中有大量类似梳子和烫发的工具。 (例如乔希的回答)
-
不确定投反对票的意义何在。在我创建这个问题之前,我当然调查了几个包,例如
combinations和permutations加上基本的 R 函数。 -
如果您还没有看过它,您可能会发现this question and answer 作为一般参考很有用。它并不全面,但确实指出了 R 中许多有用的组合包。
标签: r permutation