这只是多集0:1 的简单排列。有几个库能够有效地处理这些问题:RcppAlgos(我是作者)和arrangements。
RcppAlgos::permuteGeneral(1:0, freqs = c(3, 3))
arrangements::permutations(x = 1:0, freq = c(3, 3))
两者都给出了预期的结果。您会注意到传递的向量是按降序排列的(即1:0)。之所以如此,是因为这两个库都按字典顺序生成它们的输出。
正如 cmets 中所述,对于您的真实数据,由于结果数量太大,因此发布的解决方案都不起作用。
RcppAlgos::permuteCount(0:1, freqs = c(100,100))
[1] 9.054851e+58
arrangements::npermutations(x = 0:1, freq = c(100, 100), bigz = TRUE)
Big Integer ('bigz') :
[1] 90548514656103281165404177077484163874504589675413336841320
由于一次生成如此大量的数据根本不可行,arrangements 和 RcppAlgos 这两个软件包都提供了替代方法,可以让人们解决更大的问题。
安排
对于包arrangements,您可以设置一个迭代器,允许用户一次生成组合/排列n,避免生成所有的开销他们。
library(arrangements)
iperm <- ipermutations(x = 1:0, freq = c(3,3))
## get the first 5 permutations
iperm$getnext(d = 5)
[,1] [,2] [,3] [,4] [,5] [,6]
[1,] 1 1 1 0 0 0
[2,] 1 1 0 1 0 0
[3,] 1 1 0 0 1 0
[4,] 1 1 0 0 0 1
[5,] 1 0 1 1 0 0
## get the next 5 permutations
iperm$getnext(d = 5)
[,1] [,2] [,3] [,4] [,5] [,6]
[1,] 1 0 1 0 1 0
[2,] 1 0 1 0 0 1
[3,] 1 0 0 1 1 0
[4,] 1 0 0 1 0 1
[5,] 1 0 0 0 1 1
RcppAlgos
对于RcppAlgos,有参数lower 和upper 允许生成特定块。
library(RcppAlgos)
permuteGeneral(1:0, freqs = c(3,3), lower = 1, upper = 5)
[,1] [,2] [,3] [,4] [,5] [,6]
[1,] 1 1 1 0 0 0
[2,] 1 1 0 1 0 0
[3,] 1 1 0 0 1 0
[4,] 1 1 0 0 0 1
[5,] 1 0 1 1 0 0
permuteGeneral(1:0, freqs = c(3,3), lower = 6, upper = 10)
[,1] [,2] [,3] [,4] [,5] [,6]
[1,] 1 0 1 0 1 0
[2,] 1 0 1 0 0 1
[3,] 1 0 0 1 1 0
[4,] 1 0 0 1 0 1
[5,] 1 0 0 0 1 1
由于这些块是独立生成的,因此可以轻松地并行生成和分析:
library(parallel)
mclapply(seq(1,20,5), function(x) {
a <- permuteGeneral(1:0, freqs = c(3,3), lower = x, upper = x + 4)
## Do some analysis
}, mc.cores = detectCores() - 1)
对于这个小示例,您不会注意到任何加速,但随着结果数量的增加,会有明显的提升。
summary 中有更多关于这个主题的信息,我写信给这个问题:R: Permutations and combinations with/without replacement and for distinct/non-distinct items/multiset。