从一组元素中检索最接近的元素

时间:2012-11-15 15:08:57

标签: algorithm search

我正在尝试一个想法,我有以下子问题:

我有一个包含固定长度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调用最近的群集。然后,我可以搜索该特定群集中最接近的元组。我认为它应该可行,但我不完全确定,如果在查询元组位于集群边缘的情况下它很好。

然而,我想知道,如果你有更好的想法解决问题,因为我的思绪目前完全是空白。但是,我有一种强烈的感觉,可能有一种聪明的方法来做到这一点。

需要预先计算某些东西的解决方案很好,只要它们降低了查询的复杂性。

2 个答案:

答案 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)
    ...  

繁重的过程正在创建索引,一旦你构建它们,搜索将非常快。