R expand.grid有行限制

时间:2016-11-28 12:09:32

标签: r matrix combinations subset-sum

我有一个长度为N的数值向量x,并且想要创建所有以下集合的内集合和的向量:x元素的任何可能组合,每个组合中最多M个元素。我把一个缓慢的迭代方法放在一起;我在这里寻找的是一种不使用任何循环的方式。

考虑我一直采用的方法,在下面的例子中,N = 5且M = 4

M <- 4
x <- 11:15
y <- as.matrix(expand.grid(rep(list(0:1), length(x))))
result <- y[rowSums(y) <= M, ] %*% x

然而,当N变大(对我来说超过22)时,expand.grid输出变得太大并且给出错误(用x&lt; - 11:55替换上面的x来观察这个)。理想情况下,会有一个expand.grid函数,它允许在构造完整矩阵之前对行进行限制,这(至少对于我想要的)将矩阵大小保持在内存限制内。

有没有办法实现这一点而不会导致大N的问题?

2 个答案:

答案 0 :(得分:2)

你的问题与大量的组合有关。 您似乎正在做的是以x的长度序列列出0和1的所有不同组合。

在你的例子中,x长度为5,你有2 ^ 5 = 32种组合 当x的长度为22时,你有2 ^ 22 = 4194304个组合。

你不能使用二进制编码吗? 在你的情况下,这意味着 0代表00000 1代表00001 2代表00010 3代表00011 ...

它不会完全解决你的问题,但你应该能够比现在更进一步。

答案 1 :(得分:1)

试试这个:

c(0, unlist(lapply(1:M, function(k) colSums(combn(x, k)))))

它生成的结果与expand.grid方法相同,如下所示,显示测试数据。

M <- 4
x <- 11:15

# expand.grid approach
y <- as.matrix(expand.grid(rep(list(0:1), length(x))))
result <- y[rowSums(y) <= M, ] %*% x

# combn approach
result1 <- c(0, unlist(lapply(1:M, function(k) colSums(combn(x, k)))))

all(sort(result[,1]) == sort(result1))
# [1] TRUE

这应该很快(我的机器需要0.227577秒,N = 22,M = 4):

x <- 1:22 # N = 22
M <- 4
c(0, unlist(lapply(1:M, function(k) colSums(combn(x, k)))))
# [1]  0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22  3  4  5  6  7 

您可能希望使用

选择总和的唯一值
unique(c(0, unlist(lapply(1:M, function(k) colSums(combn(x, k))))))
相关问题