在100万个点中搜索给定点的最近点

时间:2014-07-25 15:42:30

标签: database algorithm sorting search binary-search-tree

这是一个算法问题。

给定100万个点,每个点都有x和y坐标,它们是浮点数。

尽可能快地找到给定点的10个最近点。

接近度可以测量为平面上的欧几里德距离或地球上的其他距离。由于点数很多,我更喜欢二分搜索。

我的想法:

   save the points in a database

1. Amplify x by a large integer e.g. 10^4 and cut off the decimal part and then Amplify x integer part by 10^4 again. 

2. Amplify y by a large integer e.g. 10^4 

3. Sum the above result from step 1 and 2 , we call the sum as associate_value

4. Repeat 1 to 3 for each number in the database

E.g。

    x = 12.3456789 , y = 98.7654321
    x times 10^4 = 123456 and then times 10^4 to get 1234560000
    y times 10^2 =  9876.54321 and then get 9876
    Sum them, get 1234560000 + 9876 = 1234569876 

通过这种方式,我将2-d数据转换为1-d数据。在数据库中,每个点都与一个整数(associate_value)相关联。可以在数据库中将整数列设置为索引以进行快速搜索。

对于给定点(x,y),我为它执行步骤1 - 3,然后在数据库中找到它们的associate_value接近给定点associate_value的点。

e.g。

    x = 59.469797 , y = 96.4976416
   their associated value is 5946979649 

然后在数据库中,我搜索接近5946979649的associate_values,例如,5946979649 + 50,5946979649 - 50以及5946979649 + 50000000,5946979649 - 500000000.这可以通过数据库中的索引搜索来完成。 / p>

通过这种方式,我可以找到一组接近给定点的点。我可以大大减少搜索空间。然后,我可以使用欧几里得或其他距离公式来找到最近的点。

我不确定算法的效率,尤其是生成associate_values的过程。

我的想法是否有效?有更好的想法吗?

由于

3 个答案:

答案 0 :(得分:0)

您的想法似乎可能有效,但我会关注退化情况(例如,如果您的指定范围内没有任何点,但考虑到约束,这可能是不可能的)。无论哪种方式,因为你要求其他想法,这里是我的捅:将所有点存储在四叉树中。然后沿着四叉树向下走,直到你有一个足够小的组来搜索。由于这些点是固定的,因此创建四边形的成本是恒定的,这应该是您拥有的点数的对数。

答案 1 :(得分:0)

你可以做得更好,只需连接x和y协同的二进制值。它不是直线,而是沿着z曲线对点进行排序。然后,您可以使用最重要的位计算上限。 z曲线通常用于映射应用程序:http://msdn.microsoft.com/en-us/library/bb259689.aspx

答案 2 :(得分:-1)

我读取你的算法的方法就是沿着一条斜率为-1的线区分值,这些斜率与你的点类似。也就是说,如果您的点数是2,2,那么您将看到点1,3 0,4和-1,5并且可能会更接近点。解决这个问题的大多数算法都是O(n),这并不是非常糟糕。

解决此问题的一种简单算法是在迭代整个集合时保持最接近的十个优先级队列和十个点的最远距离的度量。如果x或y值不在最远距离内,则立即将其丢弃。否则,使用您使用的任何距离测量计算它,并查看它是否插入队列。如果是这样,那就更新你的前十名门槛,并继续迭代。

如果您的点在其中一个轴上预先排序,则可以通过从匹配该轴上的点开始向外辐射,直到您的距离大于距离第十个最近点的距离,从而进一步优化算法。我没有在上面段落的描述中包括排序,因为排序是O(nlogn),它比O(n)慢。如果您在同一组上多次这样做,那么对它进行排序可能是有益的。