我有一组包含A = {0,1,2,3}
元素的n个元组,所以a(i,j) ∈ {0,1,2,3} for i ∈ M = {1,...,m} and j ∈ N = {1,...,n}
。我想确定最小的子集M'为了使相应的子句a(i',j) with i' ∈ M' and j ∈ N
成对不同。
这是R:
中的一个例子n <- 10
m <- 20
set.seed(13)
set_of_tuples <- replicate(n, sample((0:3), m, replace = TRUE))
set_of_tuples
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
[1,] 2 0 2 1 2 2 0 0 1 2
[2,] 0 2 0 2 1 2 0 0 3 0
[3,] 1 2 3 3 3 3 2 1 2 1
[4,] 0 2 2 2 1 2 2 2 3 3
[5,] 3 0 2 1 2 1 1 1 0 0
[6,] 0 2 3 1 2 0 0 3 3 3
[7,] 2 0 0 1 3 1 0 0 0 0
[8,] 3 1 1 0 1 0 0 2 3 2
[9,] 3 1 2 1 1 2 3 2 3 0
[10,] 0 2 2 1 3 2 3 2 3 3
[11,] 2 1 2 1 0 1 0 0 1 1
[12,] 3 1 1 1 3 0 3 1 2 1
[13,] 3 3 0 1 0 0 1 3 2 0
[14,] 2 3 3 0 3 1 0 2 1 0
[15,] 2 2 0 1 0 3 3 1 0 2
[16,] 1 0 1 3 1 0 3 1 0 3
[17,] 1 1 0 0 2 3 3 2 3 2
[18,] 2 0 1 1 3 1 2 2 1 2
[19,] 3 3 0 0 3 3 1 2 3 3
[20,] 2 0 0 2 3 3 0 3 1 1
我们是M&#39;的长度。显然,s ≥ n**(1/4)
因为长度s只有4个不同的子组。在上面的例子中,s≥2。
s <- ceiling(n**(1/4))
测试合适的子集M&#39;如果长度为2,则可以评估所有可能的子元素:
pairwise_compare_subtuples <- function(i){
combn(ncol(set_of_tuples), 2, FUN = function(j) identical(set_of_tuples[i,][, j[1]], set_of_tuples[i,][, j[2]]))
}
index <- combn(nrow(set_of_tuples), s, FUN = NULL, simplify = FALSE)
tmp <- lapply(index, pairwise_compare_subtuples)
table(!unlist(lapply(tmp, any)))
FALSE TRUE
187 3
因此,在这里的示例中,存在M的三个2元素子集,其中所有n个2元素子元素成对地不同。从索引中你可以看出第一个是对(9,15),实际上是
set_of_tuples[c(9,15),]
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
[1,] 3 1 2 1 1 2 3 2 3 0
[2,] 2 2 0 1 0 3 3 1 0 2
10对都是成对不同的。
虽然原则上这种方法很好,但是对于大的n和m来说它会变得很慢。所以我想问两个问题:
1)有没有比#34;试验和错误&#34;更好的方法,即评估所有可能的小组?
2)如果没有,可以在R?
中更快地进行计算