在数字列表中查找数字对最接近匹配的算法

时间:2014-02-28 10:24:27

标签: algorithm search

我有一个具有非常特定的算法需求的程序。我需要搜索一个数字列表,以找到最符合一对搜索号的列表中的位置。我将“最佳对齐”定义为该对齐时差异的总和。

例如,如果我有以下数字列表:

12  18 -20  45  11  34   6  -8

...而且我正在搜索 44 13 对,那么算法应该返回3,因为这种对齐最好(总差异只有5),而3是对齐开始的位置索引

index:             0   1   2   3   4   5   6   7
list:             12  18 -20  45  11  34   6  -8
search alignment: --  --  --  43  14  --  --  -- 
difference:       --  --  --   2   3  --  --  -- 

我目前正在使用一种明显的蛮力方法 - 只需找到每个路线的差异并记住最佳路线。但是,这对我的程序来说是一个瓶颈,所以任何改进都会有所帮助。

我提出的唯一优化有点微不足道:如果对齐,则对中第一个数字的差异超过当前最佳总差异,跳到下一个对齐而不必费心检查对中的第二个数字。它有所帮助,但并不多。

如果相关,则会多次搜索列表,因此如果有某种初始排序可以加快未来的搜索速度,我会感兴趣。

我很欣赏任何人的想法,即使它只是指向相关算法的维基百科页面的链接。谢谢!

3 个答案:

答案 0 :(得分:2)

您可以将此问题重新设置为2D中的最近邻搜索。取所有数字对,并将它们视为2D平面的点。您的距离函数称为1范数(绝对差值之和)。使用查询对,您正在寻找最近的点。

因此,您正在寻找的是具有1范数距离的2D最近邻搜索的快速解决方案。众所周知,在O(N.Log(N))预处理需要O(N)存储(构建Voronoi图)之后,所有查询都可以在时间O(Log(N))内得到答案。

或者(对于更简单的实现),您可以使用2D树(2D维度中的kD树)。 http://en.wikipedia.org/wiki/Kd-tree

如果您能够负担得起存储空间,也可以使用网格化解决方案:在点上绘制一个方格,并按照每个图块对它们进行分组。对于查询对,请在网格中找到它,然后在同心圆圈中探索此图块"邻近的瓷砖,并与它们包含的点进行详尽的比较。

答案 1 :(得分:1)

正如@Yves_Daoust所说,你可以将列表中的对表示为2D点。 然后,您可以将它们放在四叉树http://en.wikipedia.org/wiki/Quadtree中。搜索最近的任意点在此结构中以O(lg(n))时间执行。

答案 2 :(得分:0)

您可以保留一个辅助数组,用中间点(l, u)和宽度m加上列表中的原始索引来描述对w。对该数组进行排序并使用二进制搜索来查找中心点的最接近匹配。那么你最好的对齐就应该在那场比赛的附近。

您的标准

d = abs(l1 - l2) + abs(u1 - u2)
然后

将成为

d = abs(dm - dw/2) + abs(dm + dw/2), dm = m1 - m2, dw = w1 - w2

这就留下了你应该看二进制搜索找到的匹配程度的问题。你可以从那里开始,在列表中向前和向后工作,直到中间点之间的差异大于你的最佳距离。