在R中设置覆盖近似值

时间:2016-08-27 18:09:32

标签: r combinatorics linear-programming set-cover

我正在尝试解决或实现R中set cover problem的近似值。给出这样的数据框。

  sets n
1   s1 1
2   s1 2
3   s1 3
4   s2 2
5   s2 4
6   s3 3
7   s3 4
8   s4 4
9   s4 5

n中的唯一元素数为:

unique(d$n)
[1] 1 2 3 4 5

我想计算覆盖n(宇宙)中所有唯一元素的较小数量的集合(sets列)。在这个例子中有两组:s1 {1,2,3}和s4 {4,5}。我已经在维基百科和互联网上阅读过它,我知道可以应用贪心算法来找到近似值。我已经检查了这个link,其中提到了两个解决此类问题的软件包,LPsolveRsymphony,但我甚至不知道如何开始。在我的现实生活中,我有超过40,000套,每套1000到10,000个元素,以及80,000的无量或独特元素。

任何有关如何开始或继续的帮助或指南将非常感激。

数据

d <- structure(list(sets = structure(c(1L, 1L, 1L, 2L, 2L, 3L, 3L, 
4L, 4L), .Label = c("s1", "s2", "s3", "s4"), class = "factor"), 
    n = c(1, 2, 3, 2, 4, 3, 4, 4, 5)), .Names = c("sets", "n"
), row.names = c(NA, -9L), class = "data.frame")

1 个答案:

答案 0 :(得分:3)

CRAN上提供lpSolve包用于线性编程问题。使用你的信息良好的Hans Borchers的回复链接,以及http://math.mit.edu/~goemans/18434S06/setcover-tamara.pdf中稍微复杂的例子(从第4/5页开始)作为模板来理解设置的正确结构,然后关注以及对?lp中第一个示例的修改:

library( lpSolve)
?lp
# In Details: "Note that every variable is assumed to be >= 0!"
# go from your long-form rep of the sets to a wide form for a matrix representation
( items.mat<- t(table(d$sets,d$n))  )  # could have reversed order of args to skip t()
#---------
> dimnames(items.mat) = list( items=1:5, sets=paste0("s", 1:4) )
> items.mat
     sets
items s1 s2 s3 s4
    1  1  0  0  0
    2  1  1  0  0
    3  1  0  1  0
    4  0  1  1  1
    5  0  0  0  1
#---------
f.obj <-  rep(1,4)  # starting values of objective parameters by column (to be solved)
f.dir <- rep(">=",5) # the constraint "directions" by row
f.rhs <- rep(1,5)    # the inequality values by row (require all items to be present)

lp ("min", f.obj, items.mat, f.dir, f.rhs)$solution
#[1] 1 0 0 1

所以集s1s4是最小的封面。 “列系数”决定了“集合”的选择。