2012-11-15 58 views
2

我正在与一个想法,其中我具有以下子问题的尝试检索最接近元素:从一组元素

我有固定长度n的含元组大小m的列表。

[(e11, e12, .., e1n), (e21, e22, .., e2n), ..., (em1, em2, .., emn)] 

现在,由于一些随机元组(t1, t2, .., tn),这不属于名单,我想找到最接近的元组(S),属于列表。

我用下面的距离函数(汉明距离):

def distance(A, B): 
    total = 0 
    for e1, e2 in zip(A, B): 
     total += e1 == e2 
    return total 

一种选择是使用穷举搜索,但是这还不够我的问题的列表是相当大的。其他的想法,我想出了,是先用kmedoids集群的列表,并检索K中心点划分(聚类中心)。对于查询,我可以使用K调用距离函数来确定距离最近的簇。然后,我可以从该特定群集中搜索最接近的元组。我认为它应该可以工作,但我不完全确定,如果在查询元组位于集群边缘的情况下很好。

不过,我想知道,如果你有更好的想法来解决问题,因为我的心在那一刻完全空白。但是,我有强烈的感觉,可能有一个聪明的方法来做到这一点。

的解决方案,需要预先计算的东西,只要他们打倒查询的复杂性都很好。

+0

它不完全回答您所需的指标,但如果您可以在elemenets之间进行比较,则可能需要使用[kd tree](http://en.wikipedia.org/wiki/K-d_tree)来获取最接近的元素(不同之处在于它对维度的“距离”有意义,而不仅仅是匹配维度的最高可能数量) – amit

+0

我忘记说了,元素是可比较的,但只有精确匹配海明距离对任务来说是有意义的,所以不幸的是kd树不适合。 – Timo

+1

查看类似的问题[here](http://stackoverflow.com/questions/8734034/how-to-find-the-closest-pairs-hamming-distance-of-a-string-of-binary-bins-in- r)和[here](http://stackoverflow.com/questions/859441/algorithm-to-find-closest-string-using-same-characters)。 –

回答

3

可以将哈希表(字典/地图),其从一个元素映射(在元组)存储它出现在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树木也要求元素相媲美。

+0

k-d树应该可以工作。汉明距离是一个度量标准。分区可以在平等或不平等的基础上完成。搜索树应该比通过散列表方法迭代更低的复杂度。 –

+0

感谢您的回答,我会处理您的想法几分钟,并查看k-d树的细节,因为我从未完全使用过它。然后我会接受答案。 – Timo

+1

@ A.Webb:我不这么认为,但我从来没有真正想过 - 如果你只用平等/不平等而不是这个问题,那么你可能会有'a!= b,b! = c'但是'a = c'(不等式不是传递的)? – amit

1

如果数据足够大,你可能想在它创建一些inverted indexes

随着的Ñ元件矢量的数据。

数据:

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 

然后你想获得ň指标如下:

索引0

1: 0, 3 
2: 1 
5: 2 

指数1

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

沉重的过程是创建索引,一旦你建立索引,搜索将会非常快。

+0

嗯,你的解决方案类似于@amit的解决方案,虽然你清楚地表明元组中的不同位置需要不同的哈希表,但这个哈希表没有明确说出,但实际上却是需要的。但是,您的搜索程序似乎更好。您使用列表来存储可能的候选项,其中将包含一些重复项,并且最后需要明确使用距离函数。 Amit总结不同候选者的命中方式实际上计算了汉明距离(至少对于至少有一个匹配的元组)。 – Timo

+0

因此,amits解决方案也不需要显式循环来获取最小距离的候选项(因为在更新搜索函数中的哈希表中的计数期间可以更新具有最小距离的那些距离)。尽管如此,感谢您的意见。 +1。 – Timo