我无法在一个地方找到任何令人满意的关于这个主题的报道,所以我想知道:
什么是最快的交集,联合和分离算法?
是否存在有限域名的有趣内容?
任何人都可以击败O(Z),其中Z是交叉点的实际大小吗?
如果您的方法依赖于排序集,请注意,但不要将其视为不合格因素。在我看来,必须有一个真正的微妙优化仓库来分享,我不想错过任何一个。
我知道的一些算法依赖于vanilla之外的按位运算,因此您可以假设存在SSE4并访问popcount等内在函数。请注意这个假设。
感兴趣: An Implementation of B-Y Intersect
更新
我们有一些非常好的部分答案,但我仍然希望对这个问题进行更彻底的攻击。我特别感兴趣的是看到更明确地使用布隆过滤器来解决这个问题。
更新
我已经完成了一些关于将bloom过滤器与cuckoo哈希表相结合的初步工作。它看起来几乎令人讨厌,因为它们有非常相似的需求。我已经接受了答案,但我现在并不满意。
答案 0 :(得分:4)
如果你愿意考虑类似集合的结构,那么bloom filters就会有简单的联合和交叉操作。
答案 1 :(得分:3)
对于相当密集的集合,区间列表可以超过您指定的操作的O(n),其中n是集合中元素的数量。
区间列表本质上是严格增加的数字列表,[a1,b1,a2,b2,...,an,bn],其中每对ai,bi表示区间[ai,bi]。严格增加的约束确保每个可描述的集合具有唯一的表示。将一个集合表示为有序的间隔集合允许您的集合操作在每次迭代时处理多个连续元素。
答案 2 :(得分:2)
如果set实际上是一个散列集,并且两个集具有相同的散列函数和表大小,那么我们可以跳过仅存在于一个集合中的所有存储桶。这可能会缩小搜索范围。
答案 3 :(得分:2)
如果交点大于差值(Z> n / 2),下面的论文给出了有序集合上的联合,交集和差异的算法,这些算法超过O(Z):
答案 4 :(得分:1)
没有O(Z)的最优解决方案,因为如果从逻辑上考虑问题,每个交叉,联合和分离算法必须至少读取所有输入元素一次,因此Z读取是必须的。因为默认情况下没有对集合进行排序,所以没有进一步的优化可以超过O(Z)
答案 5 :(得分:0)
抽象地说,集合是支持操作的东西,“X是成员吗?”。您可以在A n B
和A
上的交叉点B
上定义该操作。实现看起来像:
interface Set { bool isMember(Object X); };
class Intersection {
Set a, b;
public Intersection(Set A, Set B) { this.a = A; this.b = B; }
public isMember(Object X) {
return a.isMember(X) and b.isMember(Y);
}
}
可以使用显式集类型(如HashSet)实现 A
和B
。每次操作的成本都非常便宜,让我们用O(1)来近似;因此交叉路口的成本仅为2 O( n )。 ; - )
无可否认,如果你构建一个这样的大型交叉层次结构,那么检查一个成员可能会更加昂贵,而层次结构中的 n 集合的O( n )最多。对此的潜在优化可以是针对阈值检查层次结构的深度,并且如果超过阈值则将其实现为HashSet。这将降低成员的运营成本,并且可能在应用多个交叉点时摊销建设成本。