【问题标题】:List of combination between rows of diagonal block matrix对角块矩阵行之间的组合列表
【发布时间】:2019-06-15 08:29:35
【问题描述】:

我有以下 R 矩阵,它是 2x3 和 3x3 子矩阵的组合,它可以是超过 2 个不同维度的子矩阵(例如 m1xp 和 m2xp 和 m3xp,其中每个 m1,m2,m3

A2 <- list(rbind(c(1,1,1),c(-1,1,-1)),
           rbind(c(-1,1,1),c(1,-1,2),c(2,-1,2)))
library(Matrix)
A2 <- as.matrix(Matrix::bdiag(A2))
Rhs <- matrix(c(0,5,0.5,4),nrow = 4)
beta <- c(rep(1.2,3),c(0.5,0.2,0.1))
> A2
     [,1] [,2] [,3] [,4] [,5] [,6]
[1,]    1    1    1    0    0    0
[2,]   -1    1   -1    0    0    0
[3,]    0    0    0   -1    1    1
[4,]    0    0    0    1   -1    2
[5,]    0    0    0    2   -1    2

我想获得第一个子矩阵和第二个子矩阵之间的所有行索引组合来解决线性优化问题。该组合必须来自两个子矩阵,然后求解新的 beta,然后检查条件 Aq %*% beta == Rhs 是否满足,停止。如果没有,则采取另一种组合。我认为下面是子矩阵之间的所有行组合:

一个来自第一个子矩阵和一个来自第二个子矩阵的组合

Aq <- A2[c(1,3),]
Aq <- A2[c(1,4),]
Aq <- A2[c(1,5),]
Aq <- A2[c(2,3),]
Aq <- A2[c(2,4),]
Aq <- A2[c(2,5),]

然后,第一个矩阵中的一个和第二个矩阵中的 2 个组合

Aq <- A2[c(1,3,4),]
Aq <- A2[c(1,3,5),]
Aq <- A2[c(1,4,5),]
Aq <- A2[c(2,3,4),]
Aq <- A2[c(2,3,5),]
Aq <- A2[c(2,4,5),]

然后,第一个矩阵中的一个和第二个矩阵中的 3 个组合

Aq <- A2[c(1,3,4,5),]
Aq <- A2[c(2,3,4,5),]

然后,组合为第一个矩阵中的 2 和第二个矩阵中的一个

Aq <- A2[c(1,2,3),]
Aq <- A2[c(1,2,4),]
Aq <- A2[c(1,2,5),]

然后,组合为第一个矩阵中的 2 和第二个矩阵中的 2

Aq <- A2[c(1,2,3,4),]
Aq <- A2[c(1,2,3,5),]
Aq <- A2[c(1,2,4,5),]

然后,组合为第一个矩阵中的 2 和第二个矩阵中的 3

Aq <- A2[c(1,2,3,4,5),]

有没有更好的方法来获得所有组合? 然后我想一次在上述组合上创建一个选择一个的循环并检查是否

if (Aq %*% beta == Rhs) {
  break
} else {
  TAKE ANOTHER COMBINATION Aq
}

请注意,我可以有超过 2 个子矩阵来创建块矩阵。然后我必须在第一个、第二个和第三个矩阵之间创建所有行组合。我希望在 R 中有一种简单的方法。我尝试了 grid.expand 函数,但它没有给我想要的输出。

【问题讨论】:

  • 我不太明白,什么是第一个块和第二个块矩阵?
  • 看起来A2 是一个稀疏矩阵,它是 2x3 和 3x3 子矩阵的组合。但我不明白这个问题。你能退后一步解释一下你想要达到的目标吗?什么是Aq 和选择上述组合之一的循环,然后检查是否Aq %*% beta == Rhs?您是否只是在寻找第一个解决Aq %*% beta == RhsAq?你想解一组线性方程吗?
  • @YOLO 第一个块矩阵是块对角矩阵上的第一个矩阵,第二个块矩阵是块对角矩阵上的第二个矩阵。请注意,对角块矩阵中的矩阵的列数相同,并且行数不能超过每个矩阵的列数。
  • @smci 谢谢,你说得对,我正在尝试解决一些优化问题,我需要找到第一个解决线性优化问题的矩阵 Aq。
  • bdiagMatrix::bdiag,对吗?您需要将library(Matrix) 添加到您的代码中。

标签: r combinations slice sparse-matrix linear-algebra


【解决方案1】:

一种可能的基础 R 方法:

indices1 <- 1:2
indices2 <- 3:5
apply(expand.grid(seq_along(indices1), seq_along(indices2)), 1, 
    function(x) t(apply(
                      expand.grid(combn(indices1, x[1], simplify=FALSE), 
                            combn(indices2, x[2], simplify=FALSE)), 
                  1, unlist)))

输出:

[[1]]
     Var1 Var2
[1,]    1    3
[2,]    2    3
[3,]    1    4
[4,]    2    4
[5,]    1    5
[6,]    2    5

[[2]]
     Var11 Var12 Var2
[1,]     1     2    3
[2,]     1     2    4
[3,]     1     2    5

[[3]]
     Var1 Var21 Var22
[1,]    1     3     4
[2,]    2     3     4
[3,]    1     3     5
[4,]    2     3     5
[5,]    1     4     5
[6,]    2     4     5

[[4]]
     Var11 Var12 Var21 Var22
[1,]     1     2     3     4
[2,]     1     2     3     5
[3,]     1     2     4     5

[[5]]
     Var1 Var21 Var22 Var23
[1,]    1     3     4     5
[2,]    2     3     4     5

[[6]]
     Var11 Var12 Var21 Var22 Var23
[1,]     1     2     3     4     5

编辑:添加更通用的版本:

#identifying the indices
indices <- split(seq_len(nrow(A2)), max.col(abs(A2) > 0, "first"))

#generating the combinations
apply(expand.grid(lapply(indices, seq_along)), 1L, 
    function(idx) {
        t(apply(
            expand.grid(
                lapply(seq_along(idx), 
                    function(k) {
                        combn(indices[[k]], idx[k], simplify=FALSE)
                    })),
            1L, unlist))
    })

【讨论】:

  • 非常感谢您采用这种方法。有没有办法从 A2 中识别索引
  • @JesZ,我添加了一个更通用的版本。请看一下
  • 非常感谢您的帮助,非常感谢您的帮助
  • 如果我有这个矩阵 A2 A2
  • A2 的索引
猜你喜欢
  • 1970-01-01
  • 2015-05-21
  • 1970-01-01
  • 2017-05-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-04-13
  • 1970-01-01
相关资源
最近更新 更多