这是使用combn 的基本 R 方法。假设您有 1 到 12 的整数,并且您想要找到所有 5 个数字的集合,总和为 20。
myGroups <- combn(1:12, 5)
mysums <- combn(1:12, 5, FUN=sum, simplify=TRUE)
myAnswers <- myGroups[, mysums == 20]
这将返回一个矩阵,其中列是数字集:
myAnswers
[,1] [,2] [,3] [,4] [,5] [,6] [,7]
[1,] 1 1 1 1 1 1 2
[2,] 2 2 2 2 2 3 3
[3,] 3 3 3 4 4 4 4
[4,] 4 5 6 5 6 5 5
[5,] 10 9 8 8 7 7 6
这将很容易封装在一个函数中。在下面的函数中,x是输入向量,我在上面的例子中设置为1:12,并且在OP的问题中定义了k和n。
myfunction <- function(x, k, n) {
myGroups <- combn(x, k)
mysums <- combn(x, k, FUN=sum, simplify=TRUE)
myGroups[, mysums == n]
}
注意
此方法假定 x 中的每个条目将在计算中使用一次,因此对于使用其中 4 个加起来为 9 的整数 0:9,myfunction 返回:
myfunction(0:9, 4, 9)
[,1] [,2] [,3]
[1,] 0 0 0
[2,] 1 1 2
[3,] 2 3 3
[4,] 6 5 4
注意
如果目标是允许重复使用这些整数,我们只需将输入的内容调整为myfunction。请注意,这将导致集合的重复输出,因为顺序对combn 很重要。
如果涉及到重复的整数,则必须修改 combn 的使用以返回一个列表,以便我们可以使用 unique 删除重复的集合:
myfunctionDupes <- function(x, k, n) {
# return list instead of matrix, with elements sorted
myGroups <- lapply(combn(x, k, simplify=FALSE), sort)
# find duplicates
dupes <- duplicated(myGroups)
# subset summations to those where myGroups is not a duplicate
mysums <- combn(x, k, FUN=sum, simplify=TRUE)[!dupes]
# subset myGroups to the unique values then those with sums == n
myGroups <- (myGroups[!dupes])[mysums == n]
# return a matrix
do.call(cbind, myGroups)
}
在@josh-obrien 的示例上运行这需要一点时间,但会产生相同的结果:
myfunctionDupes(rep(0:9, 4), 4, 9)
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11] [,12] [,13] [,14] [,15] [,16] [,17] [,18]
[1,] 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 2
[2,] 1 1 1 1 0 2 2 0 0 3 0 0 2 2 1 1 1 2
[3,] 2 3 4 1 1 3 2 2 3 3 4 0 3 2 2 3 1 2
[4,] 6 5 4 7 8 4 5 7 6 3 5 9 3 4 5 4 6 3