Generate all combinations given a constraint

2019-07-23 05:34发布

问题:

How can I generate all of the 6 combinations of 2 treatments (A,B) in blocks of 4, such that in each block there is an equal number of A's and B's, using R?

"AABB","ABAB","ABBA","BBAA","BABA","BAAB" 

P.S. The number of combinations is calculated as follows:

If

T = #treatments

n = #treatments in each block = k*T,

The number of combinations equals n! / [k!*k! (T times)]

Thank you

回答1:

Something like this should work:

library(gtools)

t <- c('A','B')
k <- 2
n <- k * length(t)

t2 <- rep(t, k)
m <- permutations(n,n)
res <- unique(apply(m,MARGIN=1,function(x) paste(t2[x],collapse='')))

--------------------------------------------------------------------
res
[1] "ABAB" "ABBA" "AABB" "BAAB" "BABA" "BBAA"


回答2:

The multicool package implements an algorithm for permuting multisets --- exactly the task you want to have performed. Here's an example of what it can do:

library(multicool)

# Create a simple convenience function
enumAllPartitions <- function(multiset) {
    m1 <-  initMC(multiset)        # Initialize the permutation object
    N <- fact(length(multiset))/   # Calculate number of permutations
         prod(fact(table(multiset)))
    sapply(seq_len(N), function(X) paste(nextPerm(m1), collapse=""))
}

# Try it out with a few different multisets
x <- c("A", "A", "B", "B")
y <- c("G", "L", "L", "L")
z <- c("X", "X", "Y", "Z", "Z")

lapply(list(x,y,z), enumAllPartitions)
[[1]]
[1] "BBAA" "ABBA" "BABA" "ABAB" "AABB" "BAAB"

[[2]]
[1] "LLLG" "GLLL" "LGLL" "LLGL"

[[3]]
 [1] "ZZYXX" "XZZYX" "ZXZYX" "ZZXYX" "XZZXY" "ZXZXY" "XZXZY" "XXZZY" "ZXXZY"
[10] "ZZXXY" "YZZXX" "ZYZXX" "XZYZX" "ZXYZX" "YZXZX" "XYZZX" "YXZZX" "ZYXZX"
[19] "XZYXZ" "ZXYXZ" "XZXYZ" "XXZYZ" "ZXXYZ" "YZXXZ" "XYZXZ" "YXZXZ" "XYXZZ"
[28] "XXYZZ" "YXXZZ" "ZYXXZ"


回答3:

The expected solution can also be achieved using the new iterpc package.

I <- iterpc(c(2, 2), labels=c("A", "B"), ordered=TRUE)
getall(I)

#      [,1] [,2] [,3] [,4]
# [1,] "A"  "A"  "B"  "B" 
# [2,] "A"  "B"  "A"  "B" 
# [3,] "A"  "B"  "B"  "A" 
# [4,] "B"  "A"  "A"  "B" 
# [5,] "B"  "A"  "B"  "A" 
# [6,] "B"  "B"  "A"  "A"