如果两个集合的交集(一个对于所有检查都相同,另一个更改)是空的或者不是,我需要做很多检查。
如果检查说(在少量检查中)它不是空的,那就没关系,但它是(可能有更精确的第二个过滤步骤),所以误报是好。这是不允许的,我过滤掉了一些非空的交叉点,所以假阴性是不行的。
所以,只有一个场景:
marker
(交集中的D),永远不允许为假
linestyle='None'
(没有交集)也可以在少量检查中返回
对于单个元素,我会使用布隆过滤器,但我找不到类似于一组元素的东西,并且逐个元素布隆过滤器检查是一个可能的选项,但我正在寻找更好的东西。
答案 0 :(得分:2)
非常感谢您的回答,帮助我提出了一个很好的解决方案并解决了问题。
这个想法大部分都是原始的,但足够了。
我创建了两个位集,一个用于更改集,另一个用于固定集。一组中的每个元素被散列为一位(例如,对于1到64中的长位),然后组合成一组(大多数是Bloom-Bitset,其中k = 1)。
要检查是否存在非空交集,我只需要将两个位集与位和操作组合,并检查结果是否为0。
假阳性率(我认为,没有做数学)会更糟,但对我的情况来说已经足够好了。
示例:
[A,B,C] => 0000100010100000
[B,D,F] => 0100000010000100
----------------------&
0000000010000000!= 0 =>真
答案 1 :(得分:0)
一个优化是保持列表(快速查找的数组)与每个集的最小/最大值。然后首先检查该列表是否重叠。如果不是 - >返回false - 不需要进一步检查。
S1: a b c
S2: d e f
S1 and S2 -> false (no overlap)
如果对这些集进行排序并且它们重叠,则只需检查重叠区域。
S1: a b c d e
S2: d e f g h
Only check the 'd e' region
如果需要检查两组以上的交集,首先尝试查找两个不重叠的集合。如果找到 - >返回false。如果没有,只检查所有这些集合的重叠区域(对于更多集合,它应该变小)。
S1: a b c d e
S2: d e f g h
S3: g h i
S1 and S2 and S3 -> false (S1 and S3 do not overlap)
如果大多数集合范围很广,您可以使用其他选项:
假设元素的最大数量是6400(对于此示例),并且每个元素都是,或者可以转换为1-6400的整数。
对于每个集合,可以创建一个小位图(64位无符号整数),其中一位代表100个项目。
例如:
S1: 1,23,80,312,340
S2: 160,184,450
S3: 230,250,340
S1 bitmap: 100100..
S2 bitmap: 010010..
S3 bitmap: 001100..
S1 and S2 -> false
S1 and S3 -> true, only check range 301-400
S1 and S2 and S3 -> false
您当然可以使用小于100的数字(最好是2的幂,因此您可以快速设置相应的位)并使用多个uint64
。
这甚至可以在多个级别中完成(取决于您愿意使用的内存/存储空间量)。例如,首先快速检查一个64位整数(占用一个CPU周期,可以很容易地用SQL完成)。只有匹配的那些才能检查包含4,8或16 uint64
的第二级,每个位代表一个较小的值范围(使用SSE / AVX寄存器也可能非常快)。如果它们仍然匹配,则进行更深入的检查,但仅针对与结果中的设置位相对应的范围。
答案 2 :(得分:0)
你提到你是在sql
做的。所以我们这样说:
PatternSet (ElemId int16 primary key)
:带有要检查的设置的第一个表ProbablyChangedSets (ElemId int16, SetId int, primary key(ElemId, SetId))
:第二个表包含要检查PatternSet
我很好奇这个查询性能还不够吗?
-- sets with intersections
select distinct
cs.SetId
from ProbablyChangedSets cs
join PatternSet s on
cs.ElemId = s.ElemId
-- |cs| = setCount * avgSetSize = 10^8 * 10 = 10^9
-- |s| = avgSetSize = 10
-- numberOfComparisons ~= 10^9 * 10 = 10^10, comparisonComplexity = O(1)
通过足够的并行化,它会非常快 - 只需几秒钟。
或者您的检查是连续的,您需要优化单一检查操作吗?