【问题标题】:R expand.grid with row restrictionsR expand.grid 具有行限制
【发布时间】:2016-11-28 12:09:31
【问题描述】:

我有一个长度为 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 替换为 x

有没有办法做到这一点而不会对大 N 造成问题?

【问题讨论】:

  • 11:15 令牌数据(根据@EtienneMoerman 的优化)还是典型的真实数据?这有什么应用?处理 2^45 的基数是很罕见的

标签: r matrix combinations subset-sum


【解决方案1】:

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

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

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

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

【讨论】:

    【解决方案2】:

    试试这个:

    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))))))
    

    【讨论】:

    • 很好的答案,谢谢!我应该提到,跟踪每个总和中的元素也很有用,但我可以通过解决您的解决方案来实现这一点 - 在您的函数中添加更多行并再次使用 combn 创建一个矩阵元素位置。
    猜你喜欢
    • 2018-06-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-12
    • 2012-08-21
    • 2015-07-17
    相关资源
    最近更新 更多