如何有效地找到图的邻居

时间:2013-06-29 13:04:24

标签: algorithm search graph graph-algorithm path-finding

我有一个程序可以创建如下所示的图表

Structure of the created graph

算法从绿色节点开始并遍历图形。假设已将一个节点(具有4个参考左,右,上和下的链接列表类型节点)添加到图像中由红点描绘的图形中。为了将新创建的节点与其邻居集成,我需要找到四个对象并将其链接,以便保留图形连接。

以下是我需要澄清的内容

  1. 假设所有黄色节点都为空,并且我没有保留另一个数据结构来映射节点,找到新创建节点的邻居的存在的最有效方法是什么。我知道基本的图搜索算法,如DFS,BFS等和最短路径算法,但我认为这些算法中的任何一个都不够高效,因为图形可以有大约10000个节点并且可以使用图搜索算法(从绿色节点开始)来查找添加新节点时的邻居对我来说似乎计算成本很高。
  2. 如果无法避免图搜索,那么最佳替代结构是什么。我想到了一个大型的多维数组。但是,这会造成内存浪费,并且还存在没有负面索引的问题。由于图像中的图形可以在任何方向上生长。我的解决方案是编写一个单独的类,该类由基于数组的数据结构组成,以描绘负索引。但是,在采用这个选项之前,我想知道如果我不解决问题而不解决新的结构并节省大量的返工。
  3. 感谢您提供反馈并阅读此问题。

3 个答案:

答案 0 :(得分:1)

我不确定我是否理解正确。你想

吗?
  • 检查是否存在从(0,0)到(x1,y1)
  • 的路径

  • 检查(x1,y1)的任何邻居是否在图表中? (即使从(0,0)到任何一个邻居都没有路径)。

我假设您正在寻找路径(否则您将不使用链接列表),这意味着您无法存储没有路径(0,0)的点。

另外,您提到您不希望在2D链接列表旁边使用任何其他数据结构。

您无法避免完整的图搜索。 BFS和DFS是经典算法。我认为你并不关心最短路径 - 任何路径都可以。

您可以考虑的另一种方法是A *(简单解释here)或其变体之一(看here)。

备选数据结构将是一组节点(每个节点当然是一对< x,y>)。您可以轻松地运行4次检查,以查看其中的任何邻居是否已在该集合中。检查和添加都需要O(n)空间和O( logn )时间。如果您的编程语言不支持成对作为集合的节点,则可以使用单个整数(x *(Ymax + 1)+ Y)。

答案 1 :(得分:0)

您可以使用四叉树或r树等空间索引。

答案 2 :(得分:0)

您的数据结构可以正常工作,但可能效率不高。这将是很多工作。

使用您当前的数据结构,您可以使用A *搜索(请参阅https://en.wikipedia.org/wiki/A * _ search_algorithm获取基本描述)来查找该点的路径,该路径必然会找到邻居。然后假装你在那个时候有一个小家伙,把他的右手放在墙上,然后让他顺时针找到他的方向。当他回来时,他会找到其余的。

顺时针找到他的方式是什么意思?例如,假设你从邻居走下来,到达他的观点。然后你的家伙应该面对他有邻居的右,上,左的第一个。如果他能够走右路,他会,然后他会尝试向下,向右,向上和向左的方向。 (想象一下,试着用右手在墙上自己走过迷宫。)

这种方式就是精神错乱。

以下是两种更易于使用的替代数据结构。

您可以使用四叉树。有关说明,请参阅http://en.wikipedia.org/wiki/Quadtree。通过这种插入,节点在时间上是对数的。寻找邻居也是对数的。而且你只是为你拥有的数据使用空间,所以即使你的图表非常分散,这也是内存效率的。

或者,您可以为一类带有正索引和负索引的数组创建一个类。然后建立在2-d类的基础上,同时采用正负指数。在引擎盖下,该类将实现为常规数组和偏移量。所以一个数组可以从某个数字开始,正数或负数。如果您尝试插入偏移量之前的一段数据,则创建一个新的偏移量,该偏移量低于该块的长度的固定部分,创建一个新数组,并将数据从旧数据复制到新。现在插入/查找邻居通常是O(1),但它可能非常浪费内存。