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