我有一个包含500多个子集的列表,每个子集具有1到500个值(整数)。所以我有类似的东西:
{1, 2, 3 }
{2, 3}
{4, 5}
{3, 6, 7}
{7, 9}
{8, 4}
{10, 11}
运行代码后我想得到:
{1, 2, 3, 6, 7, 9}
{4, 5, 8}
{10, 11}
我编写了简单的代码[here],将每个子集与每个子集进行比较,如果它们相交则将它们连接在一起,否则不会。 它在小规模上是可以的,但是需要大量的数据才能永远。
拜托,您能告知任何改进吗?
P.S。我在数学或逻辑方面都不强,对我来说,大符号会很有希望。对不起。
答案 0 :(得分:2)
您尝试在图表中查找已连接的组件,每个输入集代表一组完全连接的节点。这是一个简单的实现:
sets = [{1, 2, 3 },{2, 3},{4, 5},{3, 6, 7},{7, 9},{8, 4},{10, 11}]
allelts = set.union(*sets)
components = {X: {X} for X in allelts}
component = {X: X for X in allelts}
for S in sets:
comp = sorted({component[X] for X in S})
mergeto = comp[0]
for mergefrom in comp[1:]:
components[mergeto] |= components[mergefrom]
for X in components[mergefrom]:
component[X] = mergeto
del components[mergefrom]
这导致组件具有组件列表(由其最小元素键入),以及组件存储每个元素的组件:
>>> print(components)
{1: {1, 2, 3, 6, 7, 9}, 4: {8, 4, 5}, 10: {10, 11}}
>>> print(component)
{1: 1, 2: 1, 3: 1, 4: 4, 5: 4, 6: 1, 7: 1, 8: 4, 9: 1, 10: 10, 11: 10}
>>>