对超集进行分区并获取每个分区的原始列表

时间:2012-12-22 17:27:56

标签: algorithm python-3.x categories categorization

简介

在尝试对图表中的节点进行一些导管化时(会呈现不同),我发现自己遇到了以下问题:

问题

给定元素S = {0, 1, ... M}的超集和{{1>}个非不相交子集nT_i,是什么找出名为0 <= i < n的集合S的分区的最佳算法?

P是原始超集P = S的所有不相交分区P_jS的联合,以便对所有元素{ {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]

问题

  1. python包中有哪些好的函数/类来计算所有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 }}?也许已经有了一个能够做到这一点的功能
  2. 找到每个分区P_j s 的最佳算法是什么,“父母”列表?我们注意numpy
  3. 我认为蛮力方法是生成scipy个集合的所有2个组合,并将它们分成最多3个不相交的集合,这些集合将被添加回池中P_j设置然后重复该过程,直到所有生成的T_0 = S都不相交,因此我们得到了我们的答案 - T集合。有点问题可能是在那里缓存所有“父母”。

    我怀疑 动态编程方法可用于优化算法。

    注意:我会喜欢在latex中编写数学部分(通过MathJax),但不幸的是,这不会被激活: - (

2 个答案:

答案 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的“签名”。签名正是您正在寻找的分区的等价关系。

顺便说一下,我完全同意你关于数学标记的看法。也许是时候开始一个新的活动了。