在R中使用递归查找所有组合

在R中使用递归查找所有组合,r,recursion,combinatorics,R,Recursion,Combinatorics,我在从递归函数返回值方面遇到了问题,希望您能帮助我解决这个问题。我有一个包含一组矩阵的列表,每个矩阵表示一组可能的组合,并使用combn()生成。例如,列表中可能有3个矩阵: # set 1 has 4 elements, do nCk = 4C1: set1 <- c("b2","b3","b4","b5") set1 <- combn(set1,1,simplify = T) # set 2 has 3 elements, choose 2: set2 <- c("c

我在从递归函数返回值方面遇到了问题,希望您能帮助我解决这个问题。我有一个包含一组矩阵的列表,每个矩阵表示一组可能的组合,并使用combn()生成。例如,列表中可能有3个矩阵:

# set 1 has 4 elements, do nCk = 4C1:
set1 <- c("b2","b3","b4","b5")
set1 <- combn(set1,1,simplify = T)  

# set 2 has 3 elements, choose 2:
set2 <- c("c1","c2","b2")
set2 <- combn(set2,2,simplify = T)

# set 3 has 10 elements, choose 1:
set3 <- combn(c(1:10),1, simplify = T)
我需要得到所有可能的4元素组合(上面每套1个元素)。我可以使用while循环和模拟状态机来实现这一点,但这种解决方案很笨重,而且代码很长。我知道这可以通过递归来实现,因为我能够正确地打印120个组合(下面的代码),但是当试图返回它们或将它们保存在变量中时,我要么得到一个下标超出范围的错误,要么结果重复数千次。我也希望避免全局变量,这将嵌入到一个相当大的项目中,因此我更希望避免使用比需要更多的变量来膨胀我的工作空间

当然,在部署时,集合的数量将是动态的,每个集合的元素也将发生变化。集合也不太大,所以我很想实现一种递归方法

要打印的工作代码:

combb <- function(allsets, number, carry){
  if(number>length(allsets)){
    print(carry)
    return()
  } else{
    for(j in 1:length(allsets[[number]][1,])){
      newcarry <- c(carry, allsets[[number]][,j])
      number2 <- number + 1
      combb(allsets, number2, newcarry)
    }
  }
}
comb长度(所有集合)){
打印(携带)
返回()
}否则{
对于(j in 1:length(所有集合[[number]][1,])){

newcarry我发现来回携带结果非常困难,因为它需要标志和列表或不同的解决方案。我所做的是创建一个包装函数,其中我创建了一个局部变量。递归函数在内部定义,并访问(“全局”)上面提到的变量。然后,包装器返回该变量:

combb <- function(allsets){

  carry <- integer(0)
  height <- 0L
  for (j in 1:length(allsets)) {
    height <- height + length(allsets[[j]][, 1])
  }

  output <- matrix(allsets[[1]][0, 1], nrow = height, ncol = 0)

  combb1 <- function(allsets, number, carry) {
    if(number > length(allsets)){
      output <<- cbind(output, carry, deparse.level = 0)
      return()
    } else{
      for (j in 1:length(allsets[[number]][1,])) {
        # Only add unique combinations (some combinations are vectors)
        if((TRUE %in% (allsets[[number]][, j] %in% carry)) == FALSE) {
          newcarry <- c(carry, allsets[[number]][, j], use.names = FALSE)
          number2 <- number + 1
          combb1(allsets, number2, newcarry)
        } else{
          next()
        }
      }
    }
  }

  combb1(allsets, 1, carry)

  return(output)
}

comb如何运行
comb
功能?目前,我只做comb(allset,1,carry);carry在外部定义为一个空向量什么是
allset
?如果能显示预期输出的前几行也会很有帮助。
allset
只是每个集合的一个列表。就输出而言,“所有可能的4元素组合”都是不言自明的,只要我可以访问任何组合,我就不会对特定的格式感到烦恼。例如,
c(“b2”、“c1”、“c2”、“4”)
就是这样的组合
combb <- function(allsets){

  carry <- integer(0)
  height <- 0L
  for (j in 1:length(allsets)) {
    height <- height + length(allsets[[j]][, 1])
  }

  output <- matrix(allsets[[1]][0, 1], nrow = height, ncol = 0)

  combb1 <- function(allsets, number, carry) {
    if(number > length(allsets)){
      output <<- cbind(output, carry, deparse.level = 0)
      return()
    } else{
      for (j in 1:length(allsets[[number]][1,])) {
        # Only add unique combinations (some combinations are vectors)
        if((TRUE %in% (allsets[[number]][, j] %in% carry)) == FALSE) {
          newcarry <- c(carry, allsets[[number]][, j], use.names = FALSE)
          number2 <- number + 1
          combb1(allsets, number2, newcarry)
        } else{
          next()
        }
      }
    }
  }

  combb1(allsets, 1, carry)

  return(output)
}