对于一组列表:如何识别所有属于另一个列表成员的适当子集的成员?

时间:2019-03-21 18:37:14

标签: r set

请考虑以下列表,其中每个成员都包含数字集。

sets <- list(a=1:3, b=2:3, c=4:6, d=4:6, e=7)

我想在列表中标识所有属于另一个集合的子集的集合,以便我想要的结果看起来像这样...

c(F,T,F,F,F)

由于我的实际功率集很大,所以我不需要计算每个功率集的功率集。有没有人想到一种有效的方法来做到这一点?

这是我到目前为止所做的,并且可以运行,但这并不是最优雅的方式。

 truthtable <- bind_rows(lapply(X=sets, FUN=function(x, allsets){
  unlist(lapply(X=allsets, FUN=function(x,testset){
    return(all(x %in% testset) & !setequal(x, testset))
  }, testset=x))
}, allsets=sets))

apply(truthtable, 1, function(x){(all(!x))})

2 个答案:

答案 0 :(得分:1)

我不知道allsets的来源,但是您的总体方法看起来还不错。这是使用简单的for循环的重构版本:

is_proper_subset = function(x, y) {
  all(x %in% y) && !setequal(x, y)
}

result = rep(NA, length(sets))
for (i in seq_along(sets)) {
  result[i] = any(sapply(sets[-i], is_proper_subset, x = sets[[i]]))
}
result
# [1] FALSE  TRUE FALSE FALSE FALSE

答案 1 :(得分:0)

为了快速进行集合操作,请使用binary decision diagrams

根据需要对集合进行哪些操作,可以选择BSD的不同变体。在最一般的情况下,请使用终端节点上每个集合的ID,并且不要统一终端节点。

有成千上万的不同文章,您可以在其中学习如何实现它们;与列表和其他琐碎的数据结构相比,要实现BSD,您有很多不同的方法可以使用它,并且还需要花更多的精力才能使用它们,但是在您理解它们之后,您一定会喜欢这种数据结构。

要理解它,这是一个很大的智力上的努力,但是,如果您希望实现集列表,集集(powerset),它将运行得非常快。