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

Java 查找2个给定节点之间的所有路径,java,Java,我想找到2个节点之间的所有路径,并将它们保存到列表中。这是问题的一部分,我需要找到两个城市之间的最短路径。我必须使用BFS,所以我想在我的图表上应用BFS,并将这两个城市之间的所有路径保存在一个列表中。到目前为止,我已经实现了这一点,但我仍然坚持使用这些城市和路线。我希望我的列表是一个路线的列表,但我不知道如何做到这一点 public class Route { private final City node; private final int cost; p

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

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;
      }
公共类路由{
私人最终城市节点;
私人最终成本;
公共路线(城市节点,内部成本){
this.node=节点;
成本=成本;
}
公共城市{
返回节点;
}
公共int getCost(){
退货成本;
}
@凌驾
公共字符串toString(){
返回“{”+节点+”,“+成本+”}”;
}
}
公共类图{
私人最终名单城市;
私人最终名单路线;
私有最终映射myGraph=newHashMap();
访问的私有列表=新建LinkedList();
private List beenThere=new LinkedList();
公共列表BFS(图表、城市起点、城市终点){
List rute=new ArrayList();
Queue toVisit=new LinkedList();
toVisit.add(from);
beenThere.add(from);
而(!toVisit.isEmpty()){
城市节点=toVisit.remove();
添加(节点);
队列邻居=新的LinkedList();
邻居=this.getNeights(节点);
而(!neights.isEmpty()){
invested.add(neights.element());
选中路由(neights.remove());
}
if(beenThere.get(beenThere.size()-1).equals(to))
添加(beenThere);
beenThere.clear();
beenThere.add(from);
}
返回车辙;
}
我已经修改了BFS并添加了一个新函数。它不起作用。请你帮我找出我做错了什么。

使用Dijkstra的算法


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

您可以使用JGraphT库中的
kshortestpath

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

该算法以递增的方式确定k条最短简单路径 权重顺序。权重可以是负数(但不允许出现负循环) 允许),并且路径可以由最大数量的边约束。 允许使用多重图形

该算法是 Bellman-Ford算法,而不是只存储它的最佳路径 在每个过程中存储“k”个最佳路径,产生的复杂性为 O(kn(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;
}
@测试
公共void findAllPaths(){
DirectedGraph DirectedGraph=buildDirectedGraph();
KShortestPaths路径检查器=
新kshortestpath(
定向图,
“A”,
Integer.MAX_值,
Integer.MAX_值
);
列表路径=pathInspector.getPaths(“D”);
assertThat(路径)。hasSize(2);
断言(
path.stream()
.平面图(
graph->graph.getEdgeList().stream()
)
.collect(收集器.toList())
)具体包括(新边(“A”、“B”)、新边(“B”、“D”)、新边(“A”、“C”)、新边(“C”、“D”);
}
/**
*它构建包含以下节点的基本图形:
* 
* 
*-->B--
*   |    |
*A-->D
*   |    |
*-->C--
*   
* 
* 
*@返回包含四个连接节点的有向图
*/
专用DirectedGraph buildDirectedGraph(){
定向图定向图=
新的DefaultDirectedGraph(Edge.class);
directedGraph.addVertex(“A”);
directedGraph.addVertex(“B”);
directedGraph.addVertex(“C”);
directedGraph.addVertex(“D”);
directedGraph.附录(“A”、“B”);
directedGraph.addEdge(“A”、“C”);
directedGraph.addEdge(“B”、“D”);
directedGraph.addEdge(“C”、“D”);
返回方向图;
}

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

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


看看这个函数。

你试过“什么”吗?是的,对于给定的图形,BFS只找到一条路径,我想找到所有的路径,然后最好共享您的代码,这样您不仅可以获得问题的解决方案,而且可以获得第一种方法的错误。我已经用我的所有代码更新了问题。没有人会帮助我,即使您已经放置了整个代码?:(我被特别告知不要使用Dijkstra。我必须使用BFS。如果我可以使用Dijkstra,对我来说会简单得多,但现在我正在努力。)