R 中的替换和规则排列

Permutations with replacement and rules in R

我需要做一种 Truth table 与 Monte Carlo 模拟一起使用。

基本上我需要用 110 个“操作数”为 0 和 1 生成排列,但有一些规则。

例如:它不能有两个并排的零

使用 3 列的示例(我需要 110)

c_1 c_2  c_3
0    0   0 = DROP
0    0   1 = DROP
0    1   0 = OK
0    1   1 = OK
1    0   0 = DROP
1    0   1 = OK
1    1   0 = OK
1    1   1 = OK 

我正在尝试使用包裹安排,但我不知道如何应用这些规则。

创建测试数据,g,然后将列粘贴在一起并使用 grep 查找没有双零的行。然后索引g

g <- expand.grid(c_1 = 0:1, c_2 = 0:1, c_3 = 0:1) # test data

ok <- ! grepl("00", do.call("paste0", g))
g[ok, ]

给予:

  c_1 c_2 c_3
3   0   1   0
4   1   1   0
6   1   0   1
7   0   1   1
8   1   1   1

一行

如果你有一个单独的行作为向量然后使用as.list来使用上面的:

x <- c(0, 1, 1)
! grepl("00", do.call("paste0", as.list(x)))
## [1] TRUE

枚举

如果有 n 列,则任何行中的零都不能超过 ceiling(n/2) 个,因此为了枚举所有可能性,我们可以用一个零枚举所有行,然后是两个零,...,ceiling (n/2) 个零。使用 k zeros 的 arrangements 包 NotDoubleZero 初始化一个结构并 iter 迭代它直到没有更多的点它 returns NULL

library(arrangements)

NotDoubleZero <- function(n, k = 0) {
  structure(NA, icomb = icombinations(n, k))
}

iter <- function(x, ...)  {
  if (is.null(x)) return(NULL)
  icomb <- attr(x, "icomb")
  n <- icomb$n
  k <- icomb$k
  repeat {
    r <- icomb$getnext()
    if (is.null(r) || all(diff(r) > 1)) break
  }
  if (is.null(r)) {
    k <- k + 1
    if (k > ceiling(n/2)) return(NULL)
    x <- NotDoubleZero(n, k)
    iter(x)
  } else structure(r, icomb = icomb)
}

# test
res <- NotDoubleZero(3)
while(!is.null(res <- iter(res))) cat("Positions of 0's: <", res, "> \n")

给予:

Positions of 0's: <  >   <- no zeros, i.e. all ones
Positions of 0's: < 1 > 
Positions of 0's: < 2 > 
Positions of 0's: < 3 > 
Positions of 0's: < 1 3 > 

给定 k 的随机行

给定 n(列数)和 k(零数),给出随机行中零的位置。您也可以随机生成 k 但这不会在行上提供均匀分布;但是,也许这就足够了。

set.seed(123)
n <- 3
k <- 2
repeat {
  r <- sort(sample(n, k))
  if (all(diff(r) > 1)) break
}
r
## [1] 1 3

1 - replace(numeric(n), r, 1)
## [1] 0 1 0