我有一个graph实现。我的图表类如下所示:
public class Graph<V> {
private HashMap<V, ArrayList<Edge<V>>> adjacencyList;
/**
* This list holds all the vertices so that we can iterate over them in the
* toString function
*/
private ArrayList<V> vertexList;
private boolean directed;
public Graph(boolean isDirected) {
directed = isDirected;
adjacencyList = new HashMap<V, ArrayList<Edge<V>>>();
vertexList = new ArrayList<V>();
}
}
此外,我的驱动程序类上有一个方法,用于计算来自另一个顶点的最短路径。它工作得很好,并从一个源顶点到所有其他顶点显示最短路径的权重:
public static <V> HashMap<V, ArrayList<Sehir>> dijkstraShortestPath(Graph<V> graph, V source, V son) {
HashMap<V, Double> distances = new HashMap<V, Double>();
HashMap<V, ArrayList<Sehir>> path = new HashMap<V, ArrayList<Sehir>>();//This is not working!
//ArrayList<Sehir> arrList = new ArrayList<>();
ArrayList<V> queue = new ArrayList<V>();
ArrayList<V> visited = new ArrayList<V>();
queue.add(0, source);
distances.put(source, 0.0);
path.put(source, new ArrayList<>());
while (!queue.isEmpty()) {
V currentVertex = queue.remove(queue.size() - 1);
if(path.get(currentVertex)==null){
path.put(currentVertex, new ArrayList<>());
}
// to save time we initialize all the distances to infinity as we go
if (distances.get(currentVertex) == null) {
distances.put(currentVertex, Double.POSITIVE_INFINITY);
}
// if(distances.get(currentVertex))
for (V adjacentVertex : graph.getAdjacentVertices(currentVertex)) {
if (distances.get(adjacentVertex) == null) {
distances.put(adjacentVertex, Double.POSITIVE_INFINITY);
}
// if (!graph.getEdgeBetween(currentVertex,
// adjacentVertex).isGidebilirMi()) {
// // System.out.println(graph.getEdgeBetween(currentVertex,
// // adjacentVertex).toString());
// distances.put(adjacentVertex, Double.POSITIVE_INFINITY);
// }
// if the distance between the source and the adjacent vertex is
// greater than the distance between the source and the current
// vertex PLUS the weight between the current and adjacent
// vertex, then we have found a shorter path than already
// existed
if (true) {
if (distances.get(adjacentVertex) > graph.getDistanceBetween(currentVertex, adjacentVertex)
+ distances.get(currentVertex)) {
distances.put(adjacentVertex,
graph.getDistanceBetween(currentVertex, adjacentVertex) + distances.get(currentVertex));
path.get(currentVertex).add((Sehir) adjacentVertex);
}
}
if (!visited.contains(adjacentVertex) && !queue.contains(adjacentVertex)) {
queue.add(0, adjacentVertex);
}
}
visited.add(currentVertex);
}
// since the above statments only added the vertices as needed,
// verticies that are completely unconnected to the source are not added
// yet, so this adds them now
for (V v : graph.getVertexList()) {
if (!distances.containsKey(v)) {
distances.put(v, Double.POSITIVE_INFINITY);
}
}
return path;
}
在这里,如果我返回距离,它可以正常工作。但路径 HashMap不存储有关路径的正确信息。我怎样才能解决这个问题?我想获取路径,例如对象arrayList。顺便说一句,“Sehir”的意思是“城市”,这是我在Graph上的对象。
答案 0 :(得分:1)
也许这可以帮到你
// Shortest path algorithm
//
// Algorithm to find distance from a given vertex, to each of the remaining
// Vertices
//
// Distance = 0...max - 1
//
for(each vertex, v) {
if(V not visited AND V.Distance == Distance) {
V is visited;
for(each vertex w directly reachable from v) {
if(w.dist == -1) {
w.dist = dist + 1;
w.prev = v;
}
}
}
}
答案 1 :(得分:1)
使用以下代码(来自http://www.baeldung.com/java-dijkstra)
1.定义存储图形的对象
public class Graph {
private Set<Node> nodes = new HashSet<>();
public void addNode(Node nodeA) {
nodes.add(nodeA);
}
// getters and setters
}
2.定义节点对象
public class Node {
private String name;
private List<Node> shortestPath = new LinkedList<>();
private Integer distance = Integer.MAX_VALUE;
Map<Node, Integer> adjacentNodes = new HashMap<>();
public void addDestination(Node destination, int distance) {
adjacentNodes.put(destination, distance);
}
public Node(String name) {
this.name = name;
}
// getters and setters
}
3.计算来自源头的最短路径:
public static Graph calculateShortestPathFromSource(Graph graph, Node source) {
source.setDistance(0);
Set<Node> settledNodes = new HashSet<>();
Set<Node> unsettledNodes = new HashSet<>();
unsettledNodes.add(source);
while (unsettledNodes.size() != 0) {
Node currentNode = getLowestDistanceNode(unsettledNodes);
unsettledNodes.remove(currentNode);
for (Entry < Node, Integer> adjacencyPair:
currentNode.getAdjacentNodes().entrySet()) {
Node adjacentNode = adjacencyPair.getKey();
Integer edgeWeight = adjacencyPair.getValue();
if (!settledNodes.contains(adjacentNode)) {
calculateMinimumDistance(adjacentNode, edgeWeight, currentNode);
unsettledNodes.add(adjacentNode);
}
}
settledNodes.add(currentNode);
}
return graph;
}
private static Node getLowestDistanceNode(Set < Node > unsettledNodes) {
Node lowestDistanceNode = null;
int lowestDistance = Integer.MAX_VALUE;
for (Node node: unsettledNodes) {
int nodeDistance = node.getDistance();
if (nodeDistance < lowestDistance) {
lowestDistance = nodeDistance;
lowestDistanceNode = node;
}
}
return lowestDistanceNode;
}
4.计算最短路径:
private static void CalculateMinimumDistance(Node evaluationNode,
Integer edgeWeigh, Node sourceNode) {
Integer sourceDistance = sourceNode.getDistance();
if (sourceDistance + edgeWeigh < evaluationNode.getDistance()) {
evaluationNode.setDistance(sourceDistance + edgeWeigh);
LinkedList<Node> shortestPath = new LinkedList<>(sourceNode.getShortestPath());
shortestPath.add(sourceNode);
evaluationNode.setShortestPath(shortestPath);
}
}
测试一些场景,例如:
Node nodeA = new Node("A");
Node nodeB = new Node("B");
Node nodeC = new Node("C");
Node nodeD = new Node("D");
Node nodeE = new Node("E");
Node nodeF = new Node("F");
nodeA.addDestination(nodeB, 10);
nodeA.addDestination(nodeC, 15);
nodeB.addDestination(nodeD, 12);
nodeB.addDestination(nodeF, 15);
nodeC.addDestination(nodeE, 10);
nodeD.addDestination(nodeE, 2);
nodeD.addDestination(nodeF, 1);
nodeF.addDestination(nodeE, 5);
Graph graph = new Graph();
graph.addNode(nodeA);
graph.addNode(nodeB);
graph.addNode(nodeC);
graph.addNode(nodeD);
graph.addNode(nodeE);
graph.addNode(nodeF);
graph = Dijkstra.calculateShortestPathFromSource(graph, nodeA);
您也可以使用此实现:https://gist.github.com/gennad/791938