我的数据有很多套(几百万)。这些设置大小中的每一个都在几个成员到几万个整数之间。其中许多集合是较大集合的子集(有许多超集)。我正在尝试将每个子集分配给它最大的超集。
任何人都可以为这类任务推荐算法吗? 有许多算法可用于生成集合的所有可能子集,但鉴于我的数据大小(例如paper或SO question),此类方法的时间禁止。
我的数据集示例:
A {1, 2, 3}
B {1, 3}
C {2, 4}
D {2, 4, 9}
E {3, 5}
F {1, 2, 3, 7}
预期答案:B和A是F的子集(不重要的是B也是A的子集); C是D的子集; E仍未分配。
答案 0 :(得分:2)
这是一个可能有用的想法:
1
映射到[F, A, B]
,2
映射到[F, A, D, C]
,{{ 1}}到3
等等。这可以实现[F, A, B, E]
时间,其中O(n log n)
是输入的总大小。n
,您将获得与1,2和3相关联的列表。您在整个算法的运行时中发出的选择总数为O(n),因此到目前为止,运行时是O(n log n + n),它仍然是O(n log n)。因此,如果我把所有内容都弄清楚,那么算法的运行时总体上是O(n log n),这看起来可能就像你要解决这个问题一样好。
这是算法的python实现:
A
注意:不要太信任我的写作。我刚才想到了这个算法,我还没有证明它是正确的还是其他任何东西。
答案 1 :(得分:0)
所以你有数百万套,每套都有数千个元素。只表示该数据集需要数十亿个整数。在你的比较中,你甚至可以毫不费力地进行数万亿次操作。
因此,我假设你需要一个能够分布在很多机器上的解决方案。这意味着我会考虑https://en.wikipedia.org/wiki/MapReduce。一系列的。
i: s
的k:v对,其中i
是集合s
的元素。(s1, s2): i
,其中s1 <= s2
都是包含在i
中的集合。不要忽略将每个集合映射为自己配对!(s1, s2)
计算交叉点的大小k
,并发送对s1: k
,s2: k
。 (如果s1
和s2
不同,则只发送第二个。s
都会收到一组超集。如果是最大值,请发送s: s
。否则,请为t: s
的严格超集的t
发送s
。s
,只有在最大值时才会接收列表集s
。如果s
最大,请为t: s
的子集t
发送s
。这有很多步骤,但从本质上讲,它需要在成对的集合之间重复比较,每个集合都有一个共同的元素。可能是O(n * n * m)
,n
是集合数,m
是多个集合中不同元素的数量。
答案 2 :(得分:0)
以下是一个算法的简单建议,该算法可能会根据您的数字给出更好的结果(n = 10 ^ 6到10 ^ 7集合,m = 2到10 ^ 5个成员,很多超级/子集)。当然,这很大程度上取决于您的数据。一般而言,复杂性比其他提出的算法差得多。也许你只能处理小于X的集合,例如其他1000个成员使用其他方法。
按照大小对集进行排序。
删除第一个(最小的)集并开始将其与后面的其他集进行比较(最大集合优先)。
找到超集后立即停止并创建关系。如果没有找到超集,请删除。
重复2.和3.除了最后一组之外的所有内容。