假设我有许多“已知”集:
1 {a, b, c, d, e}
2 {b, c, d, e}
3 {a, c, d}
4 {c, d}
我想要一个将一个集合作为输入的函数(例如{a, c, d, e}
)并找到具有最多元素数量的集合,而不是其他共同的项目。换句话说,具有最大基数的子集。答案不一定是适当的子集。这种情况下的答案是{a, c, d}
。
编辑:以上示例错误,现已修复。
我正试图找到绝对最有效的方法。
(在下面,我假设为了简单起见,比较两个集合的成本是 O(1)。这个操作不在我的控制之内,所以没有必要考虑它。事实上,它将是被比较的两组基数的函数。)
Candiate 1:
生成输入的所有子集,然后遍历已知集并返回作为子集的最大集。这样做的缺点是复杂度将类似于 O(n!×m ),其中 n 是输入集的基数, m 是“已知”子集的数量。
候选人1a(感谢@bratbrat):
迭代所有“已知”集合并计算交集的基数,并取一个具有最高值的集合。这将是 O(n),其中 n 是子集的数量。
候选人2:
创建一个逆表并计算输入和已知集之间的欧氏距离。这可能很快。我不清楚如何限制它只包括没有后续 O(n)过滤器的子集。
候选人3:
迭代所有已知集并与输入进行比较。复杂性将是 O(n),其中 n 是已知集的数量。
我可以使用Python和Redis内置的set函数。
这些似乎都不是特别好。想法?集合的数量可能会变大(猜测大约为100,000)。
答案 0 :(得分:1)
在O(n)时间内没有办法做到这一点......只需读取输入就是O(n)。
一些想法:
按大小(最大的第一个)对集合进行排序,并搜索作为输入集子集的第一个集合。一旦找到,就不必检查其余部分。
如果可能在集合中的可能项目数量有限,则可以通过位向量表示它们。然后,您可以计算查找表,以告诉您给定集是否是输入集的子集。 (逐步读取所考虑的每个输入集的位,逐字逐句,将每个单词索引到相应的表中。如果您发现条目告诉您它不是子集,则可以再次直接转到下一个输入集。 )这是否真的会给你带来性能,取决于实现语言。我想它在具有原始整数类型的语言中最有效,如C或Java。
答案 1 :(得分:0)
http://packages.python.org/bitstring
正如评论中所提到的,可以通过细分已知集合并为每个线程提供自己的子集来进行并行处理。每个线程提供最佳匹配,然后父线程从线程中选择最佳。
答案 2 :(得分:0)
您正在进行多少次搜索?如果您正在搜索多个输入集,则应该能够预处理所有已知集(可能作为树结构),并且每个查询的搜索时间将按查询集大小的顺序排列。
例如:使用所有已知集创建Trie结构。确保在插入之前对每个集进行排序。对于查询,请按照集合中的链接进行操作。