R组合将N分成子n

时间:2017-02-15 06:12:34

标签: r combinations permutation

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

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

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

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

bins = 4
N = 10

并返回所有组合,谢谢

1 个答案:

答案 0 :(得分:1)

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

让我们定义函数partition(n,k)来表示所有k-tuples (x1,x2,...,xk) s.t的集合。 x1+x2+...+xk=n xi >= 1 n(分区kpartition(n,k)非空子集,换句话说。下图显示了使用自上而下递归将如何遇到过多的冗余计算:

enter image description here

我们可以看到,partition(n-i,k-1) + [i]可以通过将i=1,2,...n-1的结果与所有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

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

No,NAme,ID,Description
1,Stack,232,"ABCDEFGHIJKLMNO
 -- Jiuaslkm asdasdasd"
2,Queue,454,"PQRSTUVWXYZ
 -- Other 
 words here"
3,Que,4343,"sdfwerrew"