我正在尝试用R生成所有长度为N的序列(假设N是偶数),这样零的数量正好是N / 2.
答案 0 :(得分:2)
我认为这是你正在寻找的东西。我使用expand.grid
生成了所有可能的二进制组合,并选择了其中包含N/2
个二进制组合的组合。
bin.combs <- function(N){
cbs <- as.matrix(expand.grid(rep(list(0:1),N)))
cbs <- cbs[rowSums(cbs)==N/2,]
unname(cbs)
}
# > bin.combs(4)
# [,1] [,2] [,3] [,4]
# [1,] 1 1 0 0
# [2,] 1 0 1 0
# [3,] 0 1 1 0
# [4,] 1 0 0 1
# [5,] 0 1 0 1
# [6,] 0 0 1 1
修改强>
# @Matthew Lundberg
bin.combs3 <- function(N){
apply(combn(N,N/2), 2, FUN=function(x) 1:N %in% x)
}
# @Bernardo
bin.combs2 <- function(N){
vec <- rep(c(0,1),N/2)
cbs <- permn(vec)
cbs[!duplicated(cbs)]
}
这是迄今为止提出的解决方案的基准。结果表明我和@Matthews解决方案非常接近。
microbenchmark(bin.combs(8), bin.combs2(8), bin.combs3(8), times=20)
# Unit: microseconds
# expr min lq mean median uq max neval
# bin.combs(8) 551.916 586.021 788.5850 663.6950 736.8880 3200.565 20
# bin.combs2(8) 483857.505 522567.683 546706.0648 545832.1185 561677.2175 672247.779 20
# bin.combs3(8) 688.192 749.524 809.2446 795.3495 874.2095 1003.857 20
答案 1 :(得分:2)
combn
获得组合。然后,您可以从1:N中选择这些条目。下面矩阵中的列是解决方案。
> f <- function(N) apply(combn(N,N/2), 2, FUN=function(x) 1:N %in% x)
> f(4)
[,1] [,2] [,3] [,4] [,5] [,6]
[1,] TRUE TRUE TRUE FALSE FALSE FALSE
[2,] TRUE FALSE FALSE TRUE TRUE FALSE
[3,] FALSE TRUE FALSE TRUE FALSE TRUE
[4,] FALSE FALSE TRUE FALSE TRUE TRUE
答案 2 :(得分:1)
SimonG的方法的另一种方法是首先定义一个包含所需零和一个数的向量,然后使用包combinat
获取所有排列。应该更有效,特别是对于大N,因为你不必生成所有可能性然后将其子集化。
library(combinat)
N = 4
vec = rep(c(0,1),N/2)
permn(vec)