R n个m元组的最小子元组,使得所有n个子元组成对不同

R n个m元组的最小子元组,使得所有n个子元组成对不同,r,algorithm,linear-algebra,combinatorics,R,Algorithm,Linear Algebra,Combinatorics,我有一组n个m元组,其中的元素来自a={0,1,2,3},所以a(I,j)∈ i的{0,1,2,3}∈ M={1,…,M}和j∈ N={1,…,N}。我想确定M'的最小子集M',以便相应的子偶a(I',j)与I'∈ M'和j∈ N都是两两不同的 以下是R中的一个示例: n <- 10 m <- 20 set.seed(13) set_of_tuples <- replicate(n, sample((0:3), m, replace = TRUE)) set_of_tup

我有一组n个m元组,其中的元素来自
a={0,1,2,3}
,所以
a(I,j)∈ i的{0,1,2,3}∈ M={1,…,M}和j∈ N={1,…,N}
。我想确定M'的最小子集M',以便相应的子偶
a(I',j)与I'∈ M'和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
要测试长度为2的合适子集M'是否存在,您可以评估所有可能的子偶:

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
这10对都是两两不同的

虽然在原则上这工作得很好,但对于较大的n和m,它会变得非常缓慢。因此,我想问两个问题:

1) 有没有比“试错法”更好的方法,即评估所有可能的子偶


2) 如果没有,R中的计算速度能更快吗?

这里有一个更快的版本(如果这有什么区别的话),不幸的是,这个问题是NP难的(你可以将NP难的集合覆盖问题简化为它,尽管不幸的是,我现在没有时间这么做)。所以一般来说,最坏情况下的执行时间是指数级的。@akrun:我想试试这个。不幸的是,combnPrim不像combn那样将函数作为参数。因此,我修改了我的代码如下:
index_I@akrun:对不起,无法完成上述操作。在任何情况下,我都会收到一个错误'error In match.fun(fun):'idential(x[,j[[1]]],x[,j[[2]])不是我不理解的函数、字符或符号'。也许你能帮忙。谢谢,mceHere是一个更快的版本(如果这有什么区别的话),这个问题很不幸是NP难的(你可以把NP难的集合覆盖问题简化为它,尽管很不幸,我现在没有时间这么做)。所以一般来说,最坏情况下的执行时间是指数级的。@akrun:我想试试这个。不幸的是,combnPrim不像combn那样将函数作为参数。因此,我修改了我的代码如下:
index_I@akrun:对不起,无法完成上述操作。在任何情况下,我都会收到一个错误'error In match.fun(fun):'idential(x[,j[[1]]],x[,j[[2]])不是我不理解的函数、字符或符号'。也许你能帮忙。谢谢,mce
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
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