在大型节点列表中查找路径?大约100,000个节点

时间:2017-02-10 08:58:00

标签: c++ spatial path-finding quadtree

我有一个节点列表作为2D坐标(浮点数组),目标是找到有多少节点链接到源节点(给定)。

如果节点之间的距离小于或等于10,则将两个节点定义为链接。另外,如果A和B之间的距离<= 10,则B和C之间的距离<= 10并且距离A和C之间>在图10中,即使这样,A和C被链接,因为路径将是A-> B-> C.因此,理论上这是典型的图搜索问题。

这是问题。我在列表中有大约100,000个节点。每个节点都是2D坐标点。由于列表是巨大的,传统的遍历和路径查找算法(如DFS或BFS)将占用O(n ^ 2)来构造邻接列表,这不是理想的而不是我正在寻找的。

我在互联网上进行了研究,发现在这种情况下,Quad Tree或kd Tree可能是最好的。我也制作了自己的Quad Tree课程,我只是不了解如何在其上实现像DFS这样的搜索算法。或者如果还有其他我错过的东西?

1 个答案:

答案 0 :(得分:3)

四叉树通过将2D空间划分为四分之一来分组,直到每个点都有一个自身的象限,或者直到达到最小尺寸,然后将象限内的所有点都集中到一个列表中。

由于您尝试在源列表中的每个点的最大距离内找到所有点,因此您不需要一直向下到每个单元格一个点。为了选择一个截止值,我会对一些不同的值进行性能测试,但作为最小象限大小的起点,点的最大连接距离可能是一个很好的猜测。

所以现在你将所有的点分组到树中,你需要知道如何实际找到附近的点。

由于四叉树编码空间信息,要查找任何给定点的特定距离内的点,您将下降四叉树并使用该空间信息从搜索中排除整个象限。为此,您需要检查每个象限的最近范围是否超出了您搜索点的最大距离。如果该象限的最近边缘超出最大距离,则该象限中的所有点都不可能在最大距离内,因此不需要探索该树的那一部分。 (这类似于二进制搜索不需要搜索已排序数组或树的部分,因为它知道这些部分不可能包含要搜索的值)。

一旦你达到四叉树的水平,你有一个点或一个点列表,你将与这些点进行常规的欧氏距离检查,看看它们是否实际上在最大距离内。 (不要忘记检查是否平等,否则你会发现你正在寻找的相同点。)

A quadtree example from wikipedia

因此,例如,如果您正在搜索此图像右下角其中一个点附近的点,则无需搜索其他三个顶级象限,因为它们中的所有三个都将是超出最大距离。这样可以避免在树的那些部分中探索所有子象限,并避免与所有这些点进行距离比较。

但是,如果您正在搜索象限边缘附近的点,则需要检查相邻象限,因为最近的边界将足够接近,您无法排除有效点在该象限中的可能性

在您的特定情况下,您可以通过构建四叉树一次,然后循环原始的点列表并执行上述搜索以查找该点附近的所有点来利用此功能。然后,您可以使用found-points来构建连接图,可以通过Depth / Breadth-First-Search有效地遍历,也可以使用edge-weight来与更复杂的加权搜索一起使用,例如Dijkstra&s; s算法或A *。

相关问题