【问题标题】:Find closest nodes given list of nodes and coordinates在给定节点和坐标列表的情况下查找最近的节点
【发布时间】:2012-10-24 00:58:54
【问题描述】:

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

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

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

对于给定位置,如何找到 100 英里内的所有位置?或者如果更简单,50 个最近的位置

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

【问题讨论】:

  • 看到这个问题:stackoverflow.com/questions/1751698/…我没有时间断言这两个问题是否重复,但我相信你可以从旧问题中找到解决上述问题的好线索。
  • 我认为您正在寻找的可能是 SQL Server 的spatial indexes。从算法上讲,在没有特殊索引支持的情况下,您几乎无法阻止此类查询的 O(n)(半径内的所有点)或 O(n lg k)(k 个最近点)时间。
  • 使用空间索引(他们使用R-Tree's
  • 我在 mjv 的转介中找到了答案。我应该将什么标记为已接受?还是我应该将问题作为重复项删除?

标签: algorithm graph-algorithm


【解决方案1】:

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

【讨论】:

    【解决方案2】:

    您必须遍历它们并简单地丢弃所有距离 100 英里远的位置,这将是 O(N)

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

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

    我的 SQL 有点生疏了,如果有错误请大声疾呼,我会修复它。

    【讨论】:

      【解决方案3】:

      您并没有真正向我们提供有关表结构的大量信息,因此很难给您一个准确的答案。但是,假设目标邮政编码作为参数 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)
      

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

      【讨论】:

        【解决方案4】:

        一种解决方案是编写一个如下所示的通用函数,并允许切割:

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

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2017-03-09
          • 2015-11-10
          • 1970-01-01
          • 1970-01-01
          • 2013-06-15
          • 2016-10-10
          • 2011-07-24
          • 1970-01-01
          相关资源
          最近更新 更多