【问题标题】:R combinations split N into sub n [closed]R组合将N分成子n [关闭]
【发布时间】:2017-02-15 06:12:33
【问题描述】:

我正在使用一种算法,该算法将根据总体样本大小计算所有可能的 bin 样本大小。所以我想用 sum(n_i) = N 和 n_i >= 1 的约束来计算 n_i 的所有组合。

例如 N = 10,我有 4 个 bin 样本,一些可能的组合可能是

2,3,2,3 另一个 1,1,1,7等

理想情况下,该函数将采用两个参数

bins = 4
N = 10

并返回所有组合,谢谢

【问题讨论】:

    标签: r combinations permutation


    【解决方案1】:

    这个问题本质上是递归的,最好通过使用带有记忆的动态编程来解决(因为具有相同参数值的递归函数将被多次调用,记住已经计算的值是有意义的)。

    让我们定义函数partition(n,k) 来表示所有k-tuples (x1,x2,...,xk) s.t. 的集合。 x1+x2+...+xk=n 与每个 xi >= 1(换句话说,将 n 划分为 k 非空子集)。下图展示了使用自顶向下递归会遇到过多的冗余计算:

    正如我们所见,partition(n,k) 可以通过组合来自所有i=1,2,...n-1partition(n-i,k-1) + [i] 的结果来计算。让我们将函数partition(n,k) 的值存储为D[n,k](实现为list of lists)。

    partition <- function(n, k, lst) {
    
      DT <- rep(list(list()),n*k) # the dynamic programming table as list of lists
      for (i in 1:n) {
        DT[[i]][[1]] <- list(i)
      }
    
      for (i in 2:n) {
        for (j in 2:k) {
          temp <- list()
          for (m in 1:(i-1)) {
            if (i-m >= j-1) {
              temp <- c(temp, lapply(DT[[i-m]][[j-1]], function(x) c(x,m)))
            }
          }
          DT[[i]][[j]] <- temp
        }
      }
    
      return(DT[[n]][[k]]) 
    
    }    
    
    partition(10,4,list())
    
    # output
    [[1]]
    [1] 7 1 1 1
    
    [[2]]
    [1] 6 2 1 1
    
    [[3]]
    [1] 5 3 1 1
    
    [[4]]
    [1] 4 4 1 1
    
    [[5]]
    [1] 3 5 1 1
    
    [[6]]
    [1] 2 6 1 1
    
    [[7]]
    [1] 1 7 1 1
    
    [[8]]
    [1] 6 1 2 1
    
    [[9]]
    [1] 5 2 2 1
    
    [[10]]
    [1] 4 3 2 1
    
    [[11]]
    [1] 3 4 2 1
    
    [[12]]
    [1] 2 5 2 1
    
    [[13]]
    [1] 1 6 2 1
    
    [[14]]
    [1] 5 1 3 1
    
    [[15]]
    [1] 4 2 3 1
    
    [[16]]
    [1] 3 3 3 1
    
    [[17]]
    [1] 2 4 3 1
    
    [[18]]
    [1] 1 5 3 1
    
    [[19]]
    [1] 4 1 4 1
    
    [[20]]
    [1] 3 2 4 1
    
    [[21]]
    [1] 2 3 4 1
    
    [[22]]
    [1] 1 4 4 1
    
    [[23]]
    [1] 3 1 5 1
    
    [[24]]
    [1] 2 2 5 1
    
    [[25]]
    [1] 1 3 5 1
    
    [[26]]
    [1] 2 1 6 1
    
    [[27]]
    [1] 1 2 6 1
    
    [[28]]
    [1] 1 1 7 1
    
    [[29]]
    [1] 6 1 1 2
    
    [[30]]
    [1] 5 2 1 2
    
    [[31]]
    [1] 4 3 1 2
    
    [[32]]
    [1] 3 4 1 2
    
    [[33]]
    [1] 2 5 1 2
    
    [[34]]
    [1] 1 6 1 2
    
    [[35]]
    [1] 5 1 2 2
    
    [[36]]
    [1] 4 2 2 2
    
    [[37]]
    [1] 3 3 2 2
    
    [[38]]
    [1] 2 4 2 2
    
    [[39]]
    [1] 1 5 2 2
    
    [[40]]
    [1] 4 1 3 2
    
    [[41]]
    [1] 3 2 3 2
    
    [[42]]
    [1] 2 3 3 2
    
    [[43]]
    [1] 1 4 3 2
    
    [[44]]
    [1] 3 1 4 2
    
    [[45]]
    [1] 2 2 4 2
    
    [[46]]
    [1] 1 3 4 2
    
    [[47]]
    [1] 2 1 5 2
    
    [[48]]
    [1] 1 2 5 2
    
    [[49]]
    [1] 1 1 6 2
    
    [[50]]
    [1] 5 1 1 3
    
    [[51]]
    [1] 4 2 1 3
    
    [[52]]
    [1] 3 3 1 3
    
    [[53]]
    [1] 2 4 1 3
    
    [[54]]
    [1] 1 5 1 3
    
    [[55]]
    [1] 4 1 2 3
    
    [[56]]
    [1] 3 2 2 3
    
    [[57]]
    [1] 2 3 2 3
    
    [[58]]
    [1] 1 4 2 3
    
    [[59]]
    [1] 3 1 3 3
    
    [[60]]
    [1] 2 2 3 3
    
    [[61]]
    [1] 1 3 3 3
    
    [[62]]
    [1] 2 1 4 3
    
    [[63]]
    [1] 1 2 4 3
    
    [[64]]
    [1] 1 1 5 3
    
    [[65]]
    [1] 4 1 1 4
    
    [[66]]
    [1] 3 2 1 4
    
    [[67]]
    [1] 2 3 1 4
    
    [[68]]
    [1] 1 4 1 4
    
    [[69]]
    [1] 3 1 2 4
    
    [[70]]
    [1] 2 2 2 4
    
    [[71]]
    [1] 1 3 2 4
    
    [[72]]
    [1] 2 1 3 4
    
    [[73]]
    [1] 1 2 3 4
    
    [[74]]
    [1] 1 1 4 4
    
    [[75]]
    [1] 3 1 1 5
    
    [[76]]
    [1] 2 2 1 5
    
    [[77]]
    [1] 1 3 1 5
    
    [[78]]
    [1] 2 1 2 5
    
    [[79]]
    [1] 1 2 2 5
    
    [[80]]
    [1] 1 1 3 5
    
    [[81]]
    [1] 2 1 1 6
    
    [[82]]
    [1] 1 2 1 6
    
    [[83]]
    [1] 1 1 2 6
    
    [[84]]
    [1] 1 1 1 7
    

    如果我们想要唯一的分区,丢弃顺序,我们可以对每个列表进行排序,然后取出唯一的,如下所示。

    unique(lapply(partition(10,4,list()), function(x)sort(x)))
    [[1]]
    [1] 1 1 1 7
    
    [[2]]
    [1] 1 1 2 6
    
    [[3]]
    [1] 1 1 3 5
    
    [[4]]
    [1] 1 1 4 4
    
    [[5]]
    [1] 1 2 2 5
    
    [[6]]
    [1] 1 2 3 4
    
    [[7]]
    [1] 1 3 3 3
    
    [[8]]
    [1] 2 2 2 4
    
    [[9]]
    [1] 2 2 3 3
    

    【讨论】:

    • 谢谢你=)
    猜你喜欢
    • 2013-12-07
    • 2018-03-10
    • 1970-01-01
    • 2013-06-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-01
    相关资源
    最近更新 更多