我正在尝试一个想法,我有以下子问题:
我有一个包含固定长度m
元组的大小n
的列表。
[(e11, e12, .., e1n), (e21, e22, .., e2n), ..., (em1, em2, .., emn)]
现在,给定一些不属于列表的随机元组(t1, t2, .., tn)
,我想找到属于列表的最接近的元组。
我使用以下距离函数(汉明距离):
def distance(A, B):
total = 0
for e1, e2 in zip(A, B):
total += e1 == e2
return total
一种选择是使用详尽的搜索,但这不足以解决我的问题,因为列表非常大。我想出的其他想法是首先使用kmedoids
对列表进行聚类并检索K
medoids(聚类中心)。对于查询,我可以确定距离函数K
调用最近的群集。然后,我可以搜索该特定群集中最接近的元组。我认为它应该可行,但我不完全确定,如果在查询元组位于集群边缘的情况下它很好。
然而,我想知道,如果你有更好的想法解决问题,因为我的思绪目前完全是空白。但是,我有一种强烈的感觉,可能有一种聪明的方法来做到这一点。
需要预先计算某些东西的解决方案很好,只要它们降低了查询的复杂性。
答案 0 :(得分:3)
您可以存储从元素(在tupple中)映射到它出现的tupples的哈希表(字典/地图):hash:element->list<tupple>
。
现在,当您有一个新的“查询”时,您将需要为新“查询”的每个元素迭代每个hash(element)
,并找到最大命中数。
伪代码:
findMax(tuple):
histogram <- empty map
for each element in tuple:
#assuming hash_table is the described DS from above
for each x in hash_table[element]:
histogram[x]++ #assuming lazy initialization to 0
return key with highest value in histogram
另一种不完全符合您所需指标的替代方案是k-d tree。区别在于k-d树也考虑了元素之间的“距离”(而不仅仅是等式/不等式)。
k-d树也要求这些元素具有可比性。
答案 1 :(得分:1)
如果您的数据足够大,您可能需要在其上创建一些inverted indexes。
使用 m n 元素的数据。
数据:
0: 1, 2, 3, 4, 5, ...
1: 2, 3, 1, 5, 3, ...
2: 5, 3, 2, 1, 3, ...
3: 1, 2, 1, 5, 3, ...
...
m: m0, ... mn
然后你想得到像这样的 n 索引:
位于index0
1: 0, 3
2: 1
5: 2
的Index1
2: 0, 3
3: 3, 3
索引2
3: 0
1: 1, 3
2: 2
...
然后,您只搜索索引以获取包含任何查询元组值的元组,并在其中找到最接近的元组。
def search(query)
candidates = []
for i in range(len(query))
value = query[i]
candidates.append(indexes[i][value])
# find candidates with min distance
for candidate in candidates
distance = distance(candidate, query)
...
繁重的过程正在创建索引,一旦你构建它们,搜索将非常快。