我使用R生成在其中复制的向量的排列。
在生成排列时,我使用数字来表示组。这是我能为小家伙做的事情:
unlist(unique(permn(c(1,1,2,2,3,3,4,4), paste0, collapse = "")))
返回2520个排列的矢量(8!/ 2 ^ 4)
问题是我试图将其滚动到11,这样我就能得到16选11的每个独特排列。为了得到我所做的每一个组合:
combs = unique(combn(c(1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4),11, paste0, collapse = ""))
然后迭代它们并将它们粘贴在一起以获得所有独特的16种选择11种排列。
听起来像是一个巨大的数字?
不是。它理论上是525,525行(16!/ 5!4!4!4!4!)问题是这种方法必须以39个为一组计算所有174356582400行(大约为1740亿)百万(11!)并对它们进行独特的操作。
在找到排列时,是否有一种方法可以在重复中使用快捷方式和因子?
看看其他方法,我发现这样可行:
unique(permutations(16,11, c(1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4), set=FALSE))
除了它花费太多时间做这件事,而且我做了同样的事情,我通过找到所有坏的,然后将它们排除在外面
答案 0 :(得分:4)
您正在寻找的是multisets的排列。
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
完整性检查:
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
以下是一些基准:
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)是不正确的。发现这是little more involved而不是提供的一个班轮。
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中此类问题的更多信息,我在@RandyLai(arrangements
和iterpc
的作者的问题上写了thorough overview问题:R: Permutations and combinations with/without replacement and for distinct/non-distinct items/multiset能够有效地完成上述工作。)