计算子集的唯一交叉点

时间:2013-04-04 06:15:52

标签: performance algorithm set intersection discrete-mathematics

给定一个 S = {s i :{z j :z∈ N }},什么是计算 S 子集的唯一交集集的时间有效算法?

对于背景,我正在处理这个问题的几个版本,有些版本比其他版本大。在最小的一个| S | ≈1,000,| s i | ≈10,000,值为邮政编码。

清晰的小例子:

Input: S = {{},{1},{2,3},{3,4,5,6,7,8,9,10}}
Output: {{},{1},{2,3},{3,4,5,6,7,8,9,10},{3}}

| 取值 | = 4且 4 = 16个 S 子集。 但是,只有五组唯一的子集交集。前四个是 S 自己的成员。第五个是{3}。空集已经是 S 的成员。所有其他10个子集交叉点也产生空集。

2 个答案:

答案 0 :(得分:2)

这是一个值得的快速预处理步骤。

调用元素x和y 等效如果,对于每个集合 i ,x和y中的两者都不属于s i 。通过删除除每个等价类的一个代表之外的所有元素来简化问题。最后,将每个代表扩展到同类。

为了简化,逐个扫描集,同时保持从每个元素到其等价类的标签的映射,其中等价是针对到目前为止处理的集合确定的。最初,所有元素都在同一个类中,因此该映射将每个元素发送到同一个标签。要处理集合,请初始化新标签的空白地图。对于集合中的每个元素x,令k为x的当前标签。如果密钥k存在于新标签映射中,则对应于k的值变为x的新标签。否则,我们分配一个新标签并将其分配给x并添加从k到新标签的映射。

这是您输入的执行。

  1. 最初标签= {1:a,2:a,3:a,4:a,5:a,6:a,7:a,8:a,9:a,10:a}。
  2. 扫描{}。没有任何事情发生。
  3. 扫描{1}。将标签[1]更改为b。
  4. 扫描{2,3}。将标签[2]和标签[3]更改为c。
  5. 扫描{3,4,5,6,7,8,9,10}。将标签[3]更改为d并将[4..10]标记为e。
  6. 最后,label = {1:b,2:c,3:d,4:e,5:e,6:e,7:e,8:e,9:e,10:e} 。选择1(b)和2(c)以及3(d)和4(e)来表示他们的类别。所有其他内容都将被删除。

答案 1 :(得分:0)

渐近时间复杂度:

n:套数,会在执行期间发生变化

m:平均设置尺寸

时间: T(搜索匹配集)x T(交点)x SUM {k}表示k:1..n

时间: 2m x 2m x 1/2 n(n + 1)

时间: O(4 m ^ 2 x 1/2 n x(n + 1))〜 O(n ^ 2 m ^ 2)

建议的算法:

FOR i: 1..n
{

    FOR j: i..n
    {

        IF i = j THEN SKIP

        INTERSECTION := FIND-INTERSECTION ( SETS[i], SETS[j] )

        IF INTERSECTION ⊄ SETS[] THEN ADD INTERSECTION TO SETS[]

    }

}