子集查询的快速响应

时间:2017-01-25 00:58:04

标签: database algorithm data-structures

我有一个10,000个整数向量的数据库,范围从1到1,000。每个向量的长度最多可达1,000。例如,它看起来像这样:

vec1: 1 2 56 78
vec2: 23 34 35 36 37 38
vec3: 1 2 3 4 5 7
vec4: 2 3 4 6 100
...
vec10000: 13 234

现在,我希望以一种快速响应特定类型请求的方式存储此数据库。每个请求都将以整数向量的形式出现,最长可达10,000个:

query: 1 2 3 4 5 7 56 78 100

响应应该是作为此查询字符串的子集的向量的索引。例如,在上面的列表中,只有vec1vec3是查询的子集,因此在这种情况下的响应应为

response: 1 3

此数据库不会更改,因此您可以以任何可能的方式对其进行预处理。只要信息相同,您也可以指定查询也包含在任何协议中。例如,它可以作为排序列表或布尔表。

对数据库和查询进行编码以实现最高响应率的最佳策略是什么?

2 个答案:

答案 0 :(得分:2)

由于您使用的是python,因此这种方法看起来很简单。 (对于任何其他语言,它也是可实现的,但将包括模运算等。)

因此,对于1-1000中的每个数字,为​​其指定一个素数。所以,

1 => 2
2 => 3
3 => 5
4 => 7
...
...
25 => 97
...
...
1000 => 7919

对于每个集合,使用其值作为集合中所有值的乘积生成的散列函数。

例如。如果你的向量,vec-x = {1,2,5,25},vec-x = 2 * 3 * 11 * 97

同样,您的查询向量可以如上计算。让它的值为Q.

如果Q%vec-i == 0,则它是一个子集,否则不是。

答案 1 :(得分:1)

如何将矢量列表预处理为指标矩阵并使用矩阵乘法,例如:

import numpy as np

# generate 10000 random vectors with length in [0-1000]
# and elements in [0-1000]
vectors = [np.random.randint(1000, size=n)
           for n in np.random.randint(1000, size=10000)]

# generate indicator matrix
database = np.zeros((10000, 1000), dtype='int8')
for i, vector in enumerate(vectors):
    database[i, vector] = 1
lengths = database.sum(axis=1)

def query(ints):
    tmp = np.zeros(1000, dtype='int8')
    tmp[ints] = 1
    return np.where(database.dot(tmp) == lengths)[0]

数据库行和转换后的查询的点积将等于查询中行的元素数。如果此数字等于行中元素的总数,那么我们找到了一个子集。请注意,这使用基于0的索引。

以下是针对您的示例数据进行修订的

vectors = [[1, 2, 56, 78],
           [23, 34, 35, 36, 37, 38],
           [1, 2, 3, 4, 5, 7],
           [2, 3, 4, 6, 100],
           [13, 234]]
database = np.zeros((5, 1000), dtype='int8')
for i, vector in enumerate(vectors):
    database[i, vector] = 1
lengths = database.sum(axis=1)

print query([1, 2, 3, 4, 5, 7, 56, 78, 100])
# [0, 2] 0-based indexing