大家好,谢谢您阅读我的问题。
所以基本上我有一个列表或集合的列表,其中包含从0到n的值。
一个列表的例子是n = 4。
L1 = [0, 1, 3, 4]
我有一个更大的列表,其中包含它们。例如:
L = [L1, L2, L3, ..., Lm]
我要做的是创建所有可能兼容的子集的列表,这些子集之间没有交集。
例如,如果我有:
L1 = [0, 1, 2] and L2 = [3, 4, 5, 6, 7]
这两个被认为是兼容的,因为它们的交集为空。
我已经编写了此函数,该函数接受此类列表的列表,并检查它们之间是否全部兼容。
def areListsCompatible(list):
o = set(list[0])
for i in range(1, len(list)):
o = o & set(list[i])
if(bool(o)==True):
return False
return True
现在我的问题是如何编写一个包含列表的函数,并找到兼容列表的所有可能组合,两个列表可以兼容,三个甚至四个兼容?
我正在考虑递归,但似乎无法正确完成。
有帮助吗?谢谢。
编辑:
有人要求我输入和输出示例。
输入:
L = [[0, 1, 2], [3, 4, 5], [0, 1], [2, 3], [6, 7]]
输出:
O = [[[0, 1, 2], [3, 4, 5], [6, 7]], #O1
[[0, 1], [3, 4, 5], [6, 7]], #O2
[[0, 1], [2, 3], [6, 7]], #O3
...
]
依此类推...
答案 0 :(得分:3)
以下递归生成器函数应该起作用。我相信性能可以提高。
def subsets(lsts):
if not lsts:
return
for i, lst in enumerate(lsts):
yield [lst]
s = set(lst)
pool = [x for x in lsts[i+1:] if not s.intersection(x)]
for subs in subsets(pool):
yield [lst] + subs
>>> L = [[0, 1], [1, 2], [2, 3], [3, 4], [4, 5]]
>>> list(subsets(L))
[[[0, 1]],
[[0, 1], [2, 3]],
[[0, 1], [2, 3], [4, 5]],
[[0, 1], [3, 4]],
[[0, 1], [4, 5]],
[[1, 2]],
[[1, 2], [3, 4]],
[[1, 2], [4, 5]],
[[2, 3]],
[[2, 3], [4, 5]],
[[3, 4]],
[[4, 5]]]
如果您只想要完整的子集列表(不能将其他子集添加到列表),则可以进行一些细微调整:
def subsets(lsts, make_unique=True, used=None):
if not lsts:
yield []
used = set(used or [])
if make_unique:
lsts = sorted(map(list, set(map(tuple, lsts))))
for i, lst in enumerate(lsts):
s = set(lst)
pool = [x for x in lsts if not s.intersection(x)]
for subs in subsets(pool, make_unique=False, used=used):
if not used.intersection(map(tuple, subs)):
yield [lst] + subs
used.add(tuple(lst))
>>> list(subsets(L))
[[[0, 1], [2, 3], [4, 5]],
[[0, 1], [3, 4]],
[[1, 2], [3, 4]],
[[1, 2], [4, 5]]]
>>> L = [[0, 1, 2], [3, 4, 5], [0, 1], [2, 3], [6, 7]]
>>> list(subsets(L))
[[[0, 1], [2, 3], [6, 7]],
[[0, 1], [3, 4, 5], [6, 7]],
[[0, 1, 2], [3, 4, 5], [6, 7]]]