Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sqlite/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ R/C++;_C++_Algorithm_R_Complexity Theory_Set Cover - Fatal编程技术网

C++ R/C++;

C++ R/C++;,c++,algorithm,r,complexity-theory,set-cover,C++,Algorithm,R,Complexity Theory,Set Cover,给定一个元素U={1,2,3,…,n}的宇宙和这个宇宙中的许多集合{S1,S2,…,Sm},我们能创建的最小集合是什么,它将覆盖m个集合中至少一个元素 例如,给定以下元素U={1,2,3,4}和集合S={{4,3,1},{3,1},{4},以下集合将覆盖每个集合中的至少一个元素: {1,4} 或 {3,4} 所以这里需要的最小尺寸是2 关于如何扩大规模以解决m=100或m=1000组的问题,您有何想法?或者关于如何在R或C++中编写代码? 使用R的库(集合)从上面获取样本数据 s1如果将每个集合

给定一个元素U={1,2,3,…,n}的宇宙和这个宇宙中的许多集合{S1,S2,…,Sm},我们能创建的最小集合是什么,它将覆盖m个集合中至少一个元素

例如,给定以下元素U={1,2,3,4}和集合S={{4,3,1},{3,1},{4},以下集合将覆盖每个集合中的至少一个元素: {1,4} 或 {3,4} 所以这里需要的最小尺寸是2

关于如何扩大规模以解决m=100或m=1000组的问题,您有何想法?或者关于如何在R或C++中编写代码?

使用R的
库(集合)
从上面获取样本数据


s1如果将每个集合限制为有2个元素,那么就有了np完全问题节点覆盖。我猜更一般的问题也会是NP完全问题(对于确切的版本)。

如果你只是对一个算法感兴趣(而不是一个有效/可行的算法),你可以简单地生成基数递增的宇宙子集,并检查与S中所有集合的交集是否为非空。一旦你找到一个有效的,就停下来;基数是可能的最小值

我认为,在最坏的情况下,这种情况的复杂性是2^ U |。根据Foo-Bah的答案,我认为你不会得到多项式时间的答案…

这是一个集合,它基本上覆盖了元素和集合的角色互换。让A={4,3,1}和B={3,1}以及C={4},元素集包含关系为

  A B C
1 + + -
2 - - -
3 + + -
4 + - +
所以你基本上想用集合1={A,B}和集合2={}和集合3={A,B}和集合4={A,C}来解决覆盖{A,B,C}的问题

在实际应用中,解决集合覆盖的非平凡实例最简单的方法是找到一个具有R或C++接口的整数规划包。您的示例将以LP格式呈现为以下整数程序

Minimize
    obj: x1 + x2 + x3 + x4
Subject To
    A: x1 + x3 + x4 >= 1
    B: x1 + x3 >= 1
    C: x4 >= 1
Binary
    x1 x2 x3 x4
End

起初,我误解了问题的复杂性,提出了一个函数,可以找到一个覆盖m个集合的集合,但后来我意识到它不一定是最小的集合:

cover <- function(sets, elements = NULL) {
  if (is.null(elements)) {
    # Build the union of all sets
    su <- integer() 
    for(si in sets) su <- union(su, si)
  } else {
    su <- elements
  }

  s <- su
  for(i in seq_along(s)) {
    # create set candidate with one element removed
    sc <- s[-i] 

    ok <- TRUE
    for(si in sets) {
      if (!any(match(si, sc, nomatch=0L))) {
        ok <- FALSE
        break
      }
    }

    if (ok) {
      s <- sc
    }
  }

  # The resulting set
  s
}

sets <- list(s1=c(1,3,4), s2=c(1,3), s3=c(4))
> cover(sets) # [1] 3 4

cover嗨,每个集合中的元素在我正在解决的特定问题中都很重要,因此不能减少为2个元素。确实如此。如果2集的版本是NP完全的,那么它也是NP难的。由于可以用N-set版本轻松地求解2-set版本的实例(使用N=2的N-set版本),因此这也是NP难的。由于您可以在多项式时间内轻松验证证书(检查每个集合在S中的交集),因此它也是NP。因此NP-完全。你的意思是n=4,m=100吗?根据您的定义,
m
是集合数,
n
是元素数!我会尝试一下,但理想情况下,我正在寻找一种可行且高效的算法,可以扩展到大量集合,每个集合中包含大量元素。感谢您的回复,它为开始编写解决方案提供了良好的基础。hi@bar,这看起来很棒。问题是(我要从这里出来)我对LP不熟悉!好像我周末要看书!:-)
cover <- function(sets, elements = NULL) {
  if (is.null(elements)) {
    # Build the union of all sets
    su <- integer() 
    for(si in sets) su <- union(su, si)
  } else {
    su <- elements
  }

  s <- su
  for(i in seq_along(s)) {
    # create set candidate with one element removed
    sc <- s[-i] 

    ok <- TRUE
    for(si in sets) {
      if (!any(match(si, sc, nomatch=0L))) {
        ok <- FALSE
        break
      }
    }

    if (ok) {
      s <- sc
    }
  }

  # The resulting set
  s
}

sets <- list(s1=c(1,3,4), s2=c(1,3), s3=c(4))
> cover(sets) # [1] 3 4
n <- 100  # number of elements
m <- 1000 # number of sets
sets <- lapply(seq_len(m), function(i) sample.int(n, runif(1, 1, n)))
system.time( s <- cover(sets) ) # 0.53 seconds
ns <- 10 # number of samples
elements <- seq_len(n)
smin <- sets
for(i in seq_len(ns)) {
   s <- cover(sets, sample(elements))
   if (length(s) < length(smin)) {
     smin <- s
   }
}
length(smin) # approximate smallest length