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