简体   繁体   English

识别不相交(超)集

[英]Identifying non-intersecting (super-)sets

I am looking for an algorithm to identify non-intersecting (super-)sets in a set of sets.我正在寻找一种算法来识别一组集合中的非相交(超)集合。

Lets, assume I have a set of sets containing the sets A, B, C and D, ie {A, B, C, D}.让我们假设我有一组包含 A、B、C 和 D 的集合,即 {A、B、C、D}。 Each set may or may not intersect some or all of the other sets.每个集合可能会或可能不会与一些或所有其他集合相交。

I would like to identify non-intersecting (super-)sets.我想确定不相交的(超)集。

Examples:例子:

  • If A & B intersect and C & D intersect but (A union B) does not intersect (C union D), I would like the output of {(A union B), (C union D)}如果 A & B 相交且 C & D 相交但 (A union B) 不相交 (C union D),我想要 {(A union B), (C union D)} 的输出
  • If only C & D intersect, I would like the output {A, B, (C union D)}如果只有 C & D 相交,我想要输出 {A, B, (C union D)}

I am sure this problem has long been solved.我相信这个问题早就解决了。 Can somebody point me in the right direction?有人可以指出我正确的方向吗?

Even better would be of course if somebody had already done the work and had an implementation in python they were willing to share.当然,如果有人已经完成了这项工作并在他们愿意分享的 Python 中实现了一个更好的实现。 :-) :-)

I would turn this from a set problem into a graph problem by constructing a graph whose nodes are the graphs with edges connecting sets with an intersection.我将通过构建一个图,将其从集合问题转化为图问题,该图的节点是具有将集合与交集连接起来的边的图。

Here is some code that does it.这是一些执行此操作的代码。 It takes a dictionary mapping the name of the set to the set.它需要一个字典,将集合的名称映射到集合。 It returns an array of sets of set names that connect.它返回一组连接的集合名称。

def set_supersets (sets_by_label):
    element_mappings = {}
    for label, this_set in sets_by_label.items():
        for elt in this_set:
            if elt not in element_mappings:
                element_mappings[elt] = set()
            element_mappings[elt].add(label)
    graph_conn = {}
    for elt, sets in element_mappings.items():
        for s in sets:
            if s not in graph_conn:
                graph_conn[s] = set()
            for t in sets:
                if t != s:
                    graph_conn[s].add(t)

    seen = set()
    answer = []
    for s, sets in graph_conn.items():
        if s not in seen:
            todo = [s]
            this_group = set()
            while 0 < len(todo):
                t = todo.pop()
                if t not in seen:
                    this_group.add(t)
                    seen.add(t)
                    for u in graph_conn[t]:
                        todo.append(u)
            answer.append(this_group)
    return answer

print(set_supersets({
    "A": set([1, 2]),
    "B": set([1, 3]),
    "C": set([4, 5]),
    "D": set([3, 6])
}))

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM