找到给定节点和坐标列表的最近节点

时间:2012-11-03 16:10:40

标签: algorithm graph-algorithm

假设我有一系列位置及其X,Y坐标:

L1(X1,Y1) L2(X2,Y2) L3(X3,Y3) ... L10000(X10000,Y10000)

我有一个函数可以返回两个位置之间的距离:距离(L1,L2)= 5英里

对于指定地点,如何查找100英里范围内的所有地点?或者,如果它更容易,50个最近的位置

我们的设置是SQL Server的位置及其邮政编码表。该功能需要2个邮政编码,查找每个纬度/经度并返回距离。我们可以缓存结果,因为它们不会经常更改。

4 个答案:

答案 0 :(得分:1)

如果可以将所有位置存储在内存中(lat / lon / id),请使用Kd树。查看我对another question的回答 Kd树允许有效的最近邻搜索和k近邻搜索。平均时间复杂度为O(log n)。 如果无法将所有位置存储在内存中,请检查数据库是否支持空间索引。

答案 1 :(得分:0)

你必须循环遍历它们并简单地扔掉距离100英里远的所有位置,它将是O(N)

SELECT Location FROM Table WHERE (POWER(Location.X-Selected.X,2) + POWER(Location.Y-Selected.Y,2)) < POWER(Distance,2)

位置将是位置条目。选择将是您选择的城市,只需将其X和Y替换为相应的位置。

如果出现错误,我的SQL会有点生气,所以我会解决它。

答案 2 :(得分:0)

您并没有真正向我们提供有关表结构的大量信息,因此很难给出确切的答案。但是,假设目标邮政编码作为参数P1提供给查询。进一步说,表T有id,name和zip字段。要查找100英里范围内的所有位置,我们可以使用

select id, name, zip, distance(zip,P1) as distance
from T
where distance(zip,P1) <= 100

前50名查询

select top 50 id, name, zip, distance(zip,P1) as distance
from T
order by distance(zip,P1)

更好的解决方案是计算每个位置的纬度和经度并将其存储在数据库中。您可以考虑跳过功能中的纬度/经度查找并显着提高速度。我假设您已经获得了计算现有函数中大圆距离的代码。

答案 3 :(得分:0)

一种解决方案是编写类似以下的函数,它是通用的,并允许cutstomization:

Location[] findLocationsWithinDist(Location L1, Integer dist, LocationsList locations){
    LocationList results;
    foreach(location : locations){
        if(dist(L1, location) <= dist)
            results.add(location);
    }
    return results;
}

您可以拥有一个数据结构,用于存储每个位置以及特定范围内的位置列表。然后,每次添加新位置时都需要更新此数据结构。这似乎是一个单独的问题。