[英]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答案,尝试使用KShortestPaths
从JGraphT
库。
就我而言,我有一个包含25000个节点和250000个关系的图,并且KShortestPaths
永远保持运行。 在这种情况下,如果可以的话,建议您使用适用于Python语言的NetworkX
包。 这是迄今为止我找到的最完整的图形库。
看一下all_shortest_paths
函数。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.