繁体   English   中英

查找2个给定节点之间的所有路径

[英]Find all paths between 2 given nodes

我想找到2个节点之间的所有路径,并将它们保存到列表中。 这是我需要找到两个城市之间最短路径的问题的一部分。 我必须使用BFS,因此我想在图表上应用BFS并将两个城市之间的所有路径保存在列表中。到目前为止,我已经实现了此功能,但是我仍然坚持使用那些城市和路线。 我希望我的列表成为Routes列表,但我不知道该怎么做。

public class Route {

    private final City node;
    private final int cost; 

      public Route(City node, int cost) {
        this.node = node;
        this.cost = cost;
      }

      public City getCity() {
        return node;
      }
      public int getCost() {
        return cost;
      }

      @Override
      public String toString() {
          return "{" + node + ", " + cost + "}";
      }

}

    public class Graph {

    private final List<City> cities;
    private final List<Route> routes;
    private final Map<City, List<Route>> myGraph = new HashMap<City,List<Route>>();
private List<City> visited = new LinkedList<City>();
    private List<City> beenThere = new LinkedList<City>();


      public List<List<City>> BFS(Graph graph, City from, City to) {
          List<List<City>> rute = new ArrayList<List<City>>();
          Queue<City> toVisit = new LinkedList<City>();
          toVisit.add(from);
          beenThere.add(from);
          while(!toVisit.isEmpty()) {
              City node = toVisit.remove();
              visited.add(node);
              Queue<City> neighbors = new LinkedList<City>();
              neighbors = this.getNeighbors(node);
              while(!neighbors.isEmpty()) {
                  visited.add(neighbors.element());
                  checkRoute(neighbors.remove());
              }
              if (beenThere.get(beenThere.size()-1).equals(to))
                  rute.add(beenThere);
              beenThere.clear();
              beenThere.add(from);
          }
          return rute;
      }

我已经修改了BFS并添加了新功能。 没用 您能帮我弄清楚我在做什么错..

您可以使用KShortestPaths从JGraphT库。

根据文档,此实现使用Bellman-Ford算法:

该算法以权重递增的顺序确定k条最短的简单路径。 权重可以为负(但不允许负周期),并且路径可能受最大边数限制。 允许多图。

该算法是Bellman-Ford算法的一种变体,但它不仅存储最佳路径,而且还在每次通过时存储“ k”条最佳路径,从而产生了O(k n (m ^ 2))的复杂度,其中m是数字边数,n是顶点数。

它还知道如何处理图中的循环。

一个简单的例子:

@Test
public void findAllPaths() {
    DirectedGraph<String, Edge> directedGraph = buildDirectedGraph();

    KShortestPaths<String, Edge> pathInspector = 
                                            new KShortestPaths<String, Edge>(
                                                        directedGraph, 
                                                        "A", 
                                                        Integer.MAX_VALUE, 
                                                        Integer.MAX_VALUE
                                                    );


    List<GraphPath<String, Edge>> paths = pathInspector.getPaths("D");

    assertThat(paths).hasSize(2);
    assertThat(
        paths.stream()
        .flatMap(
                graph -> graph.getEdgeList().stream()
        )
        .collect(Collectors.toList())
    ).containsExactly(newEdge("A", "B"), newEdge("B", "D"), newEdge("A", "C"), newEdge("C", "D"));
}

/**
 * it builds a basic graph containing these nodes:
 * 
 * <pre>
 *   -->B--
 *   |    |
 * A--    -->D
 *   |    |
 *   -->C--
 *   
 * </pre>
 * 
 * @return A directed graph containing four connected nodes
 */
private DirectedGraph<String, Edge> buildDirectedGraph() {
    DirectedGraph<String, Edge> directedGraph =
                                new DefaultDirectedGraph<String, Edge>(Edge.class);

    directedGraph.addVertex("A");
    directedGraph.addVertex("B");
    directedGraph.addVertex("C");
    directedGraph.addVertex("D");

    directedGraph.addEdge("A", "B");
    directedGraph.addEdge("A", "C");
    directedGraph.addEdge("B", "D");
    directedGraph.addEdge("C", "D");

    return directedGraph;
}

使用Dijkstra的算法参考这里

这用于查找从一个节点到所有其他节点的最短路径。 但是,您可以使用此算法找到2点之间的最短路径。

我同意@jfcorugedo答案,尝试使用KShortestPathsJGraphT库。

就我而言,我有一个包含25000个节点和250000个关系的图,并且KShortestPaths永远保持运行。 在这种情况下,如果可以的话,建议您使用适用于Python语言的NetworkX包。 这是迄今为止我找到的最完整的图形库。

看一下all_shortest_paths函数。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM