从原始嵌套列表中查找最大的非交叉集嵌套列表

时间:2016-05-22 14:21:10

标签: python list set set-intersection

我有以下嵌套列表(只有整数)。

L = [[9, 10, 14, 19, 11], [9, 11, 13, 12, 4], [40, 43, 44, 42, 41, 26, 14], [10, 16, 17, 26, 14], [25, 28, 20], [25, 20, 21, 27, 24], [3, 29, 22, 28], [25, 15, 2, 16, 17, 24], [0, 2, 16, 10, 9, 4], [0, 1, 29, 3], [29, 31, 32, 23, 22], [29, 31, 33, 8, 51, 1], [0, 1, 51, 50, 49, 39, 12, 4], [0, 2, 15, 3], [25, 15, 3, 28]]

我想找到一个嵌套列表,它将来自原始嵌套列表的最大数量的非交叉集合(上图)分组。输出将类似于:

[[9, 11, 13, 12, 4], [40, 43, 44, 42, 41, 26, 14], [25, 20, 21, 27, 24], [3, 29, 22, 28], [0, 1, 51, 50, 49, 39, 12, 4]]

我不知道该怎么办。任何帮助将不胜感激。

非常感谢。

1 个答案:

答案 0 :(得分:0)

这实际上是一个图形问题。每个子列表都是一个节点,如果它们不相交,它们之间就有一条边。我们想要find the biggest cliques,即所有对节点都连接的子图。这是NP完全问题,因此如果self.navigationController?.navigationBar.setBackgroundImage(nil, forBarMetrics: UIBarMetrics.Default) self.navigationController?.navigationBar.shadowImage = nil self.navigationController?.navigationBar.translucent = true 变大,则需要一段时间。

L

输出:

from networkx import Graph, find_cliques
from itertools import combinations, takewhile

L = [[9, 10, 14, 19, 11], [9, 11, 13, 12, 4], [40, 43, 44, 42, 41, 26, 14], [10, 16, 17, 26, 14], [25, 28, 20],
     [25, 20, 21, 27, 24], [3, 29, 22, 28], [25, 15, 2, 16, 17, 24], [0, 2, 16, 10, 9, 4], [0, 1, 29, 3],
     [29, 31, 32, 23, 22], [29, 31, 33, 8, 51, 1], [0, 1, 51, 50, 49, 39, 12, 4], [0, 2, 15, 3], [25, 15, 3, 28]]

L = map(tuple, L)

g = Graph()
g.add_nodes_from(L)

for sublist1, sublist2 in combinations(L, 2):
    if set(sublist1).isdisjoint(sublist2):
        g.add_edge(sublist1, sublist2)

cliques = sorted(find_cliques(g), key=len, reverse=True)
cliques = list(takewhile(lambda c: len(c) == len(cliques[0]), cliques))
for clique in cliques:
    flat = sum(clique, ())
    assert len(flat) == len(set(flat))
    print(sorted(flat))
    print(sorted(clique))

输出是成对的:首先是展平列表,然后是2D列表。