Performance 一种快速有效的方法来测试一个集合是否是其他n个集合的子集?
我有以下问题:我有一个项目列表Performance 一种快速有效的方法来测试一个集合是否是其他n个集合的子集?,performance,binary,set,subset,combinations,Performance,Binary,Set,Subset,Combinations,我有以下问题:我有一个项目列表 [O_0,..., O_n] ,其中每个项由二进制幂表示(o_0由2^0表示,…,o_n由2^n表示)。我已经构建了这些元素的组合列表(每个组合由项目的二进制表示的总和表示)。比如我有 combs = [3, 9, 15, ......]. 给定这些项目的一个新组合,比如C_1,我想测试combs的任何元素是否包含在C_1中。我想到的一种高效快速的方法是,从combs计算每个元素的c_I,测试c_I&c_1==c_I,这意味着这个元素是正确的。这是快,因为我正
[O_0,..., O_n]
,其中每个项由二进制幂表示(o_0由2^0表示,…,o_n由2^n表示)。我已经构建了这些元素的组合列表(每个组合由项目的二进制表示的总和表示)。比如我有
combs = [3, 9, 15, ......].
给定这些项目的一个新组合,比如C_1,我想测试combs
的任何元素是否包含在C_1
中。我想到的一种高效快速的方法是,从combs计算每个元素的c_I,测试c_I&c_1==c_I
,这意味着这个元素是正确的。这是快,因为我正在做一个明智的和明智的。
我的问题是,我没有1个元素C_1
,而是有大量元素C_1,…,C_k
,我必须为每个元素测试上述条件。因此,我想知道是否有比我提到的更快的方法来测试所有元素的条件(这实际上与测试一个集合是否是另一个集合的子集是同一个问题,这就是为什么我从一开始就选择二进制表示来将问题转换为二进制问题)我对这个问题的理解是:给定k
集合Y
和m
集合X
,我们希望找到Y
的子集S
,这样对于S
中的所有Y,X
S.t中都存在X。X
是Y
的子集
我将假设集合由表示包含的0和1的n
-向量表示。以下是设置:
import pandas as pd # for drop_duplicates & benchmarks
import numpy as np
np.random.seed(0)
n = 100 # 100 "atomic" elements
m = 1000 # small sets
k = 1000 # large sets
X = pd.DataFrame(np.random.randint(0, 2, size=(m, n))).drop_duplicates().values
Y = pd.DataFrame(np.random.randint(0, 2, size=(k, n))).drop_duplicates().values
# For each row y in Y, we would like to check if there exists a row x in X
# s.t. x represents a subset of Y
def naive(Y, X):
# O(k^2 + m^2)
for i, y in enumerate(Y):
for x in X:
found_subset = False
if (x <= y).all():
yield i
found_subset = True
if found_subset:
break
def naive_as_array(Y, X):
return np.array(list(naive(Y, X)))
在步骤d
中1
和n
之间,我们将集合Y
分为Y0
和Y1
,其中Y0
包含在Y
中不包含元素d
的集合,而Y1
包含在Y
中包含元素d
的集合。类似地,我们定义了X0
和X1
。一个关键的观察结果是X1
中的集合不能作为Y0
中集合的子集出现。因此,我们可以减少递归调用中的比较次数
时间:
%timeit contains(Y, X)
%timeit naive_as_array(Y, X)
10 loops, best of 3: 185 ms per loop
1 loop, best of 3: 2.39 s per loop
%timeit contains(Y, X)
%timeit naive_as_array(Y, X)
10 loops, best of 3: 185 ms per loop
1 loop, best of 3: 2.39 s per loop