生成R中不完整的不同对象的所有可能排列

时间:2016-11-30 19:17:45

标签: r lapply

假设v=c(-1,-1,-1,0,0,0,1,1,1)并且我想生成所有排列。有9!/(3!3!3!)=1680

目前,我使用以下行来获取该功能,但效率不高。

unique(replicate(100000, sample(v), simplify=FALSE))

这是一种可能的情况。我想概括一下。假设n个对象由k个不同的对象a1,a2,...,ak组成,并且重复数字为n1,n2,...,nk (n1+n2+...+nk=n)。然后n!/(n1!n2!...nk!)

我该如何有效地做到这一点?

3 个答案:

答案 0 :(得分:2)

试试这个:

<script src="https://www.amcharts.com/lib/3/ammap.js"></script>
<script src="https://www.amcharts.com/lib/3/maps/js/worldLow.js"></script>
<script src="https://www.amcharts.com/lib/3/themes/light.js"></script>
<div id="chartdiv"></div>

答案 1 :(得分:2)

最简单的解决方案是使用iterpc

library(iterpc)
getall(iterpc(table(v), ordered = TRUE))

它比ds440的combinat::permn方法快至少5000倍。

> system.time(unique(combinat::permn(v)))
   user  system elapsed 
  4.861   0.037   4.902 
> system.time(getall(iterpc(table(v), ordered = TRUE)))
   user  system elapsed 
  0.001   0.000   0.001 

比sirallen方法快10倍。

> microbenchmark(getall(iterpc(table(v), ordered = TRUE)), sirallen())
Unit: microseconds
                                     expr      min       lq      mean    median
 getall(iterpc(table(v), ordered = TRUE))  583.512  605.699  804.0107  748.9305
                               sirallen() 5784.122 7571.282 8777.4111 8256.1035

答案 2 :(得分:1)

一种方法是使用置换函数生成所有可能性然后过滤。如果您需要保证所有可能性,这比您的问题中的示例方法更有优势,但如果您有一个长向量,它可能会“崩溃”。

v=c(-1,-1,-1,0,0,0,1,1,1)
unique(combinat::permn(v))

这种方法比@ sirallen的方法快得多。这种方法的概括可能是:

u  <- unique(v)
Pv <- expand.grid(rep(list(u),length(v)))
for(i in seq_along(u)) {
Pv <- Pv[rowSums(Pv==u[i])==sum(u[i]==v),]
}
dim(Pv)