R 计算36个元素向量的N个随机置换

R 计算36个元素向量的N个随机置换,r,permutation,R,Permutation,我有一个包含36个元素的向量V,18个是“0”,18个是“1”。 我想计算这个向量的N个随机(不是第一个N)置换 我可以这样做: library(combinat) N <- 100 # or 200, 300, 500... max 1000 V <- c(rep(0, 18), rep(1, 18)) n <- factorial(36) # total number of unique possible permutations p <- unique(permn(

我有一个包含36个元素的向量V,18个是“0”,18个是“1”。 我想计算这个向量的N个随机(不是第一个N)置换

我可以这样做:

library(combinat)
N <- 100 # or 200, 300, 500... max 1000
V <- c(rep(0, 18), rep(1, 18))
n <- factorial(36) # total number of unique possible permutations
p <- unique(permn(V))[sample(1:n, N)]
库(combinat)

N首先,由于您有重复的元素,所以不会出现
factorial(36)
结果。如果我们这样做了,为了获得总数,我们可以使用
gmp
包获得:

gmp::factorialZ(36)
Big Integer ('bigz') :
[1] 371993326789901217467999448150835200000000
我们实际处理的是的置换(正如@JakubBucek在评论中指出的)。使用包
RcppAlgos
(由我编写)或包
排列
,我们可以轻松正确地计算结果总数,更重要的是生成所需的结果

首先,结果的实际数量:

arrangements::npermutations(0:1, freq = c(18, 18), bigz = TRUE)
Big Integer ('bigz') :
[1] 9075135300

RcppAlgos::permuteCount(0:1, freqs = c(18, 18))
[1] 9075135300
这是组合学的结果。也就是说,我们必须除以相似元素排列数的乘积:

gmp::factorialZ(36) / gmp::pow.bigz(gmp::factorialZ(18), 2)
Big Rational ('bigq') :
[1] 9075135300
现在,生成随机排列。对于包
安排
我们使用
nsample
参数。此外,我们还可以设定种子的再现性:

set.seed(123)
r1 <- arrangements::permutations(0:1, freq = c(18, 18), nsample = 10)

set.seed(123)
r2 <- arrangements::permutations(0:1, freq = c(18, 18), nsample = 10)

dim(r1)
[1] 10 36

identical(r1, r2)
[1] TRUE

## only showing 10 columns
head(r1[,1:10])
     [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
[1,]    0    0    0    0    1    1    0    1    1     1
[2,]    1    0    1    1    1    1    1    1    1     0
[3,]    0    0    0    0    0    1    1    0    0     0
[4,]    1    1    1    0    0    1    0    1    0     0
[5,]    0    1    1    0    0    1    1    1    0     1
[6,]    0    0    0    1    1    1    0    1    1     1
两个软件包都非常高效。生成1000个随机排列只需不到一秒钟:

system.time(RcppAlgos::permuteSample(0:1, freqs = c(18, 18), n = 1000))
 user  system elapsed 
0.051   0.000   0.052 

system.time(arrangements::permutations(0:1, freq = c(18, 18), nsample = 1000))
 user  system elapsed 
0.249   0.000   0.249

@约瑟夫·伍德得到了完美的答案。以防您需要这些采样排列的列表,请使用:

r <- RcppAlgos::permuteSample(0:1, freqs = c(18, 18), n = 100)
r <- lapply(1:dim(r)[1], function(x) {r[x,]})

r如果要执行
N
随机组合的
0
1
为什么要从
1:N
中采样?排列是否必须是唯一的?或者您可以只做
复制(N,样本(V))
?没有
阶乘(36)
可能的排列,因为您处理的是多集的排列(所有0和所有1都相同)-请参阅。您可以使用
multicool
软件包及其功能
allPerm
。但是,仍然存在
485200708
parmutations,生成它们需要一些时间。@pisistrato请检查。你无法区分一个0和另一个0,所以你需要更多地计算一些排列。@JosephWood是的,我注意到了你和我的数字的不同。我使用了带有以下代码的
multicool
包:
xnice addition。还要注意的是,包
arrangements
有一个名为
type
(我想)的参数,它允许您返回一个列表,因此比较简洁。
type
参数已重命名为
layout
,以保持清晰。
r <- RcppAlgos::permuteSample(0:1, freqs = c(18, 18), n = 100)
r <- lapply(1:dim(r)[1], function(x) {r[x,]})