R

时间:2018-02-20 21:12:28

标签: r permutation

我使用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))

除了它花费太多时间做这件事,而且我做了同样的事情,我通过找到所有坏的,然后将它们排除在外面

1 个答案:

答案 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(arrangementsiterpc的作者的问题上写了thorough overview问题:R: Permutations and combinations with/without replacement and for distinct/non-distinct items/multiset能够有效地完成上述工作。)