如何在图表中搜索路径?

时间:2009-03-26 02:15:35

标签: java algorithm data-structures

假设我有一个边列表,每个边包含两个节点(往返)。找到两个给定节点的边缘的最佳方法是什么?请注意,边缘中的节点可能会重复。

说我有这种格式的优势:

  

1< - > 5

     

3 - < - > 7

     

5 - < - > 6

     

2'; - > 6

然后查询如1 5将返回 true

然后查询如5 2将返回 true ,因为5连接6和6连接到2。

然后查询如1 7将返回 false

然后查询如7 4将返回 false ,因为4不存在,这意味着它是无边节点。

4 个答案:

答案 0 :(得分:8)

听起来我只是在询问无向图中两个顶点之间是否存在路径,但不一定是该路径可能是什么。这与询问两个顶点是否在图的同一连通分量中相同。

如果你真的只需要知道两个顶点是否在同一个连通组件中,那么使用Disjoint-set data structure就可以得到一个简单而有效的算法。

initialize the disjoint set structure (DSS)
for each edge:
  for each vertex in edge:
    if the vertex does not exist in the DSS:
      create a new subset in the DSS containing only the vertex
  merge the subsets of the two vertices

要确定在处理完所有边之后两个顶点之间是否存在路径,只需检查两个顶点是否在同一子集中。如果是,那么它们之间就存在一些路径。

通过有效实施DSS,该算法实现了比线性时间略差,即使使用DSS的简单链接列表实现,它也是O(n * log(n))。正如j _随机_黑客提到的那样,Floyd-Warshall是O(n ^ 3)时间和O(n ^ 2)存储,无论你是否只计算传递闭包,并使用Dijkstra's算法需要对每个查询进行O(n * log(n))计算。

答案 1 :(得分:1)

您基本上期待测试一对节点是否在它们之间有路径。这是最短路径问题的一般情况。但是,请注意,如果我们能够找到所讨论的节点对之间的最短路径就足够了。使用适合您的任何表示(邻接矩阵,邻接列表,边集,联合查找...),并为所有节点对继续进行BFS / Djikstra实现。这只是服务查询的问题。或者,您可以在惰性基础上运行Djikstra / BFS(并以增量方式缓存过去的计算)。

答案 2 :(得分:0)

查看JGraphT库,它专门研究图算法并完成您所需的工作。

答案 3 :(得分:0)

您可能需要Floyd算法的一些变体来查找所有图形椎体之间的最短路径。据我所知,您只需要transitive closure无向图。这是伪代码:

for k = 1 to n
  for i = 1 to n
    for j = 1 to n
      W[i][j] = W[i][j] or (W[i][k] and W[k][j])
在运行此代码之前,

W应该是图表的二元邻接矩阵(W[i][j] == 1 <->存在从ij的边缘。 之后它将是一个传递性的封闭。即当且仅当W[i][j]可以从1访问时,j将等于i