【问题标题】:Choosing an element of each rows of a matrix and sum them for all possible combinations [R]从矩阵的每一行中选择一个元素,并对所有可能的组合求和 [R]
【发布时间】:2021-06-23 22:22:35
【问题描述】:

我有一个n*n 矩阵,我需要从每一行中取出 1 个元素并将它们加在一起。我需要对所有可能的组合执行此操作,并找到最小的行和列索引。考虑以下示例:

set.seed(1)
n <- 9
A <- matrix(round(runif(n, min = 0, max = 9)), nrow = sqrt(n), ncol = sqrt(n)) 

> A
     [,1] [,2] [,3]
[1,]    2    7    4
[2,]    1    1    7
[3,]    8    4    3

因此这里有 27 种可能的组合:

2+1+8 = 11
2+1+4 = 7
2+1+3 = 6
.
.
4+7+3 = 14

因此最小值的预期结果是 6,产生最小结果的索引是 (1,1),(2,1),(3,3)(1,1),(2,2),(3,3)

如您所见,解决方案搜索空间将随着n 的增加而爆炸式增长。你能推荐一个快速的方法来编写这个例程吗?

【问题讨论】:

    标签: r combinations permutation combinatorics


    【解决方案1】:

    我之前的回答肯定会产生所有 n^n 值,所以你是对的并没有有效地解决问题。

    动态规划方法会更有效:

    smallest_sum <- function(B){
      ans = matrix(rep(NA,nrow(B)*ncol(B)), ncol=ncol(B))
      ans[1,] = B[1,]
      for (row in 2:nrow(B)){
        mn = min(ans[row-1,])
        for (col in 1:ncol(B)){
          ans[row,col] = mn + B[row,col]
        }
        print(ans)
      }
      return(ans)
    }
    

    smallest_sum() 输出的位置 (i,j) 中的值包含包含 A[i,j] 值的最小总和。

    要得到最小值的索引,只需回溯答案,选择每一行的最小值的索引:

    backtrack <- function(ssB){
        # ssB is result from smallest_sum function
        min_ix = c()
        for (row in seq(nrow(ssB),1,-1)){
            min_ix = c(which.min(ssB[row,]), min_ix)
        }
        return(min_ix)
    }
    

    您可以修改它以包含多个索引以获得第二个(和后续)结果。

    【讨论】:

      【解决方案2】:

      这是 R 中问题的递归解决方案:

      perm <- function(A,level=NA){
          if (is.na(level)){
              level = nrow(A)
          }
          if (level == 1){
              return(matrix(A))
          } else{
              ans = array()
              r = perm(A[-1,], level-1)
              for (x in A[1,]){
                  for (row in seq(1, nrow(r))){
                      y = r[row,]
                      z = array(c(x,y))
                      ans = rbind(ans, array(c(x, y)))
                  }
              }
          }
          return (ans[complete.cases(ans),])
      }
      

      实际上,这是按列工作的,所以你必须使用

      perm(t(A))
      

      【讨论】:

      • 问题没有python标签
      • 是的,应该是 27。我正在寻找 R 中的解决方案
      • 对不起,我看错了标签,现在提供了一个 R 解决方案
      • 如果我理解正确,它会返回所有可能的组合。我对么?对于更高的 n 值,我怀疑这是一个足够快的解决方案。
      猜你喜欢
      • 2012-12-11
      • 1970-01-01
      • 2015-06-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-09-10
      • 1970-01-01
      相关资源
      最近更新 更多