查找具有短中间跳的可达到的2D点

时间:2017-02-08 19:24:53

标签: algorithm graph depth-first-search path-finding adjacency-list

我有一个大约60,000个节点的列表allNodes,对应于2D点。我正在构建一个像

这样的邻接列表
for(i in allNodes)
  for(j in allNodes)
    if(distance(i, j) <= 10) addEdge between i and j

然后从一组sourceNodes执行深度优先搜索,以查找可从sourceNodes到达的节点集。我怎样才能比二次更快?我正在使用C ++。

2 个答案:

答案 0 :(得分:0)

简单的方法是将平面划分为d-by-d,其中d> d。 10个箱子并将每个点放在由楼层(x / d),楼层(y / d)索引的箱子中。然后,而不是遍历所有点对,

for bin1 in bins:
   for i in bin1:
      for bin2 in bins neighboring bin in nine directions (including bin):
         for j in bin2:
            if(distance(i, j) <= 10) addEdge between i and j

如果积分很好,这将使事情变得更快,但最坏的情况仍然是二次的。

对于保证的O(n log n)时间算法,计算Delaunay三角剖分并丢弃长于10的边。这可能会删除距离小于或等于10的节点之间的某些直接连接,但它们仍然会间接连接。

答案 1 :(得分:0)

如果您希望点数是均匀分布的,那么David Eisenstat建议的分箱方法是有效的,这不是您为数据指定的属性。另外,如上所述,Delaunay triangulation仍然需要在诱导图上进行局部搜索,以确保找到指定距离内的所有节点。

获得保证性能的一种方法是使用kd-tree。您可以在 O(2n log n)时间内构建一个(如果您不关心保证并使用随机化,则可以更快)并使用它来执行总时间为 O(2n√n)

我不清楚Delaunay三角剖分或kd树在实践中是否会更快,但在我看来,如果你担心的话,找到并使用适当的kd树库将是一个快速而简单的解决方案发展时间。