我有一个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
响应应该是作为此查询字符串的子集的向量的索引。例如,在上面的列表中,只有vec1
和vec3
是查询的子集,因此在这种情况下的响应应为
response: 1 3
此数据库不会更改,因此您可以以任何可能的方式对其进行预处理。只要信息相同,您也可以指定查询也包含在任何协议中。例如,它可以作为排序列表或布尔表。
对数据库和查询进行编码以实现最高响应率的最佳策略是什么?
答案 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