What you are looking for are multisets permutations .
library(RcppAlgos)
multiPerm <- permuteGeneral(1:4, freqs = rep(2,4))
head(multiPerm)
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8]
[1,] 1 1 2 2 3 3 4 4
[2,] 1 1 2 2 3 4 3 4
[3,] 1 1 2 2 3 4 4 3
[4,] 1 1 2 2 4 3 3 4
[5,] 1 1 2 2 4 3 4 3
[6,] 1 1 2 2 4 4 3 3
Health Check:
library(combinat)
library(gtools)
OPTestOne <- unlist(unique(permn(c(1,1,2,2,3,3,4,4), paste0, collapse = "")))
all.equal(sort(apply(multiPerm, 1, paste, collapse="")), sort(OPTestOne))
[1] TRUE
OPTestTwo <- unique(permutations(8,8,c(1,1,2,2,3,3,4,4), set=FALSE))
all.equal(OPTestTwo, multiPerm)
[1] TRUE
Here are a few steps:
library(microbenchmark)
microbenchmark(OP_One = unique(permn(c(1,1,2,2,3,3,4,4), paste0, collapse = "")),
Algos = permuteGeneral(1:4, freqs = rep(2,4)),
OP_Two = unique(permutations(8,8,c(1,1,2,2,3,3,4,4), set=FALSE)),
times = 5, unit = "relative")
Unit: relative
expr min lq mean median uq max neval
OP_One 8435.40 5570.476 5877.457 5562.094 5378.490 5409.687 5
Algos 1.00 1.000 1.000 1.000 1.000 1.000 5
OP_Two 15335.55 10095.646 10700.802 9982.139 9539.425 10295.974 5
, m .
system.time(multiPermChoose11 <- permuteGeneral(1:4, m = 11, freqs = rep(4, 4)))
user system elapsed
0.154 0.023 0.178
head(multiPermChoose11)
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11]
[1,] 1 1 1 1 2 2 2 2 3 3 3
[2,] 1 1 1 1 2 2 2 3 2 3 3
[3,] 1 1 1 1 2 2 2 3 3 2 3
[4,] 1 1 1 1 2 2 2 3 3 3 2
[5,] 1 1 1 1 2 2 3 2 2 3 3
[6,] 1 1 1 1 2 2 3 2 3 2 3
OP , (525,525) . , .
nrow(multiPermChoose11)
[1] 2310000
, :
length(unique(apply(multiPermChoose11, 1, paste, collapse ="")))
[1] 2310000
iterpc, , np_multiset
iterpc::np_multiset(rep(4,4), 11)
[1] 2310000
R : R: / / / by @RandyLai ( arrangements iterpc, .)