如何解决Dijkstra 算法错误路径总是从 0 开始
我目前正在做数据结构和算法的最后一个作业。我作业中的编程问题之一是基于 Dijkstra 算法。我参考这个链接来帮助我的任务:https://algorithms.tutorialhorizon.com/print-all-paths-in-dijkstras-shortest-path-algorithm/。但是,我注意到这个程序实现中有一个错误。请允许我解释一下:
import java.util.Comparator;
import java.util.LinkedList;
import java.util.PriorityQueue;
import javafx.util.Pair;
public class Graph {
int vertices;
LinkedList<Edge>[] adjacencylist;
Graph(int vertices) {
this.vertices = vertices;
adjacencylist = new LinkedList[vertices];
//initialize adjacency lists for all the vertices
for (int i = 0; i <vertices ; i++) {
adjacencylist[i] = new LinkedList<>();
}
}
public void addEdge(int source,int destination,int weight) {
Edge edge = new Edge(source,destination,weight);
adjacencylist[source].addFirst(edge);
edge = new Edge(destination,source,weight);
adjacencylist[destination].addFirst(edge); //for undirected graph
}
public void dijkstra_PrintPaths(int sourceVertex){
boolean[] SPT = new boolean[vertices];
//distance used to store the distance of vertex from a source
int [] distance = new int[vertices];
int [] parentVertex = new int[vertices];
//parent of the source vertex will be -1
parentVertex[0] = -1;
//Initialize all the distance to infinity
for (int i = 0; i <vertices ; i++) {
distance[i] = Integer.MAX_VALUE;
}
//Initialize priority queue
//override the comparator to do the sorting based keys
PriorityQueue<Pair<Integer,Integer>> pq = new PriorityQueue<>(vertices,new
Comparator<Pair<Integer,Integer>>() {
@Override
public int compare(Pair<Integer,Integer> p1,Pair<Integer,Integer> p2) {
//sort using distance values
int key1 = p1.getKey();
int key2 = p2.getKey();
return key1-key2;
}
});
//create the pair for for the first index,0 distance 0 index
distance[0] = 0;
Pair<Integer,Integer> p0 = new Pair<>(distance[0],0);
//add it to pq
pq.offer(p0);
//while priority queue is not empty
while(!pq.isEmpty()){
//extract the min
Pair<Integer,Integer> extractedPair = pq.poll();
//extracted vertex
int extractedVertex = extractedPair.getValue();
if(SPT[extractedVertex]==false) {
SPT[extractedVertex] = true;
//iterate through all the adjacent vertices and update the keys
LinkedList<Edge> list = adjacencylist[extractedVertex];
for (int i = 0; i < list.size(); i++) {
Edge edge = list.get(i);
int destination = edge.destination;
//only if edge destination is not present in mst
if (SPT[destination] == false) {
///check if distance needs an update or not
//means check total weight from source to vertex_V is less than
//the current distance value,if yes then update the distance
int newKey = distance[extractedVertex] + edge.weight ;
int currentKey = distance[destination];
if(currentKey>newKey){
Pair<Integer,Integer> p = new Pair<>(newKey,destination);
pq.offer(p);
distance[destination] = newKey;
parentVertex[destination] = extractedVertex;
}
}
}
}
}
//print Shortest Path Tree
printDijkstra(parentVertex,distance,sourceVertex);
}
public void printDijkstra(int[] parent,int [] distance,int sourceVertex){
System.out.println("Dijkstra Algorithm: (With all paths)");
for (int i = 0; i <vertices ; i++) {
System.out.print(" " + sourceVertex + "--> " + + i + ": distance="+distance[i] + " Path : ");
printPathUtil(parent,i);
System.out.println();
}
}
public void printPathUtil(int parent[],int destination){
//if vertex is source then stop recursion
if(parent[destination] == -1) {
System.out.print("0 ");
return;
}
printPathUtil(parent,parent[destination]);
System.out.print(destination + " ");
}
public static void main(String[] args) {
int vertices = 6;
Graph graph = new Graph(vertices);
graph.addEdge(0,1,5);
graph.addEdge(0,2,3);
graph.addEdge(1,1);
graph.addEdge(1,3,2);
graph.addEdge(2,4);
graph.addEdge(3,4,2);
graph.addEdge(4,5,6);
graph.dijkstra_PrintPaths(0);
System.out.println();
graph.dijkstra_PrintPaths(3);
}
边缘类:
public class Edge {
int source;
int destination;
int weight;
public Edge(int source,int weight) {
this.source = source;
this.destination = destination;
this.weight = weight;
}
}
对于图类中的main方法,我调用了dijkstra_PrintPaths函数2次来打印从不同节点开始的路径。
Output:
Dijkstra Algorithm: (With all paths)
0--> 0: distance=0 Path : 0
0--> 1: distance=4 Path : 0 2 1
0--> 2: distance=3 Path : 0 2
0--> 3: distance=6 Path : 0 2 1 3
0--> 4: distance=8 Path : 0 2 1 3 4
0--> 5: distance=14 Path : 0 2 1 3 4 5
Dijkstra Algorithm: (With all paths)
3--> 0: distance=0 Path : 0
3--> 1: distance=4 Path : 0 2 1
3--> 2: distance=3 Path : 0 2
3--> 3: distance=6 Path : 0 2 1 3
3--> 4: distance=8 Path : 0 2 1 3 4
3--> 5: distance=14 Path : 0 2 1 3 4 5
这是错误出现的地方,如输出的第二部分所示。它是从 3 开始,但打印出来的路径与 0 类似。只有路径从 3 开始,然后从节点到节点,直到目的地才有意义。希望大家帮帮忙,谢谢。
解决方法
简单看一下:参数 sourceVertex
并没有真正用于 dijkstra_PrintPaths
。所以我想这就是问题所在。
我猜这个初始化是错误的:
//create the pair for for the first index,0 distance 0 index
distance[0] = 0;
Pair<Integer,Integer> p0 = new Pair<>(distance[0],0);
//add it to pq
pq.offer(p0);
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。