在尝试对图表中的节点进行一些导管化时(会呈现不同),我发现自己遇到了以下问题:
给定元素S = {0, 1, ... M}
的超集和{{1>}个非不相交子集n
,T_i
,是什么找出名为0 <= i < n
的集合S
的分区的最佳算法?
P
是原始超集P = S
的所有不相交分区P_j
与S
的联合,以便对所有元素{ {1}},每个0 <= j < M
在“原始”集x in P_j
中都有相同的“父母”列表。
x
所有T_i
都是:
S = [1, 2, 3, 4, 5, 6, 8, 9]
T_1 = [1, 4]
T_2 = [2, 3]
T_3 = [1, 3, 4]
P_j
s 和的“父母”列表,理想情况下仅限于P_1 = [1, 4] # all elements x have the same list of "parents": T_1, T_3
P_2 = [2] # all elements x have the same list of "parents": T_2
P_3 = [3] # all elements x have the same list of "parents": T_2, T_3
P_4 = [5, 6, 8, 9] # all elements x have the same list of "parents": S (so they're not in any of the P_j
和{{1 }}?也许已经有了一个能够做到这一点的功能P_j
s 和的最佳算法是什么,“父母”列表?我们注意numpy
我认为蛮力方法是生成scipy
个集合的所有2个组合,并将它们分成最多3个不相交的集合,这些集合将被添加回池中P_j
设置然后重复该过程,直到所有生成的T_0 = S
都不相交,因此我们得到了我们的答案 - T
集合。有点问题可能是在那里缓存所有“父母”。
我怀疑 动态编程方法可用于优化算法。
注意:我会喜欢在latex中编写数学部分(通过MathJax),但不幸的是,这不会被激活: - (
答案 0 :(得分:1)
以下应为线性时间(T
s中元素的数量)。
from collections import defaultdict
S = [1, 2, 3, 4, 5, 6, 8, 9]
T_1 = [1, 4]
T_2 = [2, 3]
T_3 = [1, 3, 4]
Ts = [S, T_1, T_2, T_3]
parents = defaultdict(int)
for i, T in enumerate(Ts):
for elem in T:
parents[elem] += 2 ** i
children = defaultdict(list)
for elem, p in parents.items():
children[p].append(elem)
print(list(children.values()))
结果:
[[5, 6, 8, 9], [1, 4], [2], [3]]
答案 1 :(得分:1)
我这样做的方法是构造一个M × n
布尔数组In
,其中In(i, j) = Si ∈ Tj
。您可以在O(Σj|Tj|)
中构建它,前提是您可以将S
的元素映射到O(1)
中的整数索引,方法是扫描所有集T
并标记相应的位在In
。
然后,您可以通过将行i
连接成二进制数In
位,直接从i
读取每个元素n
的“签名”。签名正是您正在寻找的分区的等价关系。
顺便说一下,我完全同意你关于数学标记的看法。也许是时候开始一个新的活动了。