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

时间:2014-03-22 09:00:21

标签: java

我想找到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并添加了一个新功能。它不起作用。你能不能帮我搞清楚我做错了什么..

3 个答案:

答案 0 :(得分:1)

您可以使用JGraphT库中的KShortestPaths

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

  

算法确定增加的k个最短简单路径   重量顺序。权重可以是负数(但没有负循环   允许),路径可以由最大边数限制。   允许使用多图。

     

该算法是一种变体   贝尔曼 - 福特算法,而不是只存储它的最佳路径   存储&#34; k&#34;每次通过的最佳路径,产生复杂性   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;
}

答案 1 :(得分:0)

使用Dijkstra的算法 Refer Here

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

答案 2 :(得分:0)

我同意@jfcorugedo的回答,尝试使用KShortestPaths库中的JGraphT

在我的情况下,我有一个包含25000个节点和250000个关系的图表,KShortestPaths只是永远在运行。在这种情况下,如果可以,我建议您使用NetworkX包作为Python语言。这是我迄今为止发现的最完整的图库。

查看all_shortest_paths功能。