da2423 :
I am attempting to print Dijkstra's algorithm, but currently only the destination ID is printing from my getPath() method. My idea was to work backwards from the destination vertex and print each predecessor, until the start vertex was printed. If there is another way to store/print the path I would be more than open to trying it a different way, I appreciate any ideas!
class ShortestPathFinder {
private Graph graph = new Graph();
private Vertex source = new Vertex(0, null);
private Vertex destination = new Vertex(0,null);
private Map<Vertex,Vertex> previousVertex = new HashMap();
private Set<Vertex> visited = new HashSet();
public Optional<Path> findShortestPath(Graph graph, Vertex source, Vertex destination, ReadInput graphReader) {
this.destination = destination;
this.source = source;
Optional<Path> pathFound = Optional.empty();
source.setDistanceFromSource(0);
PriorityQueue<Vertex> priorityQueue = new PriorityQueue<>();
priorityQueue.add(source);
source.setVisited(true);
boolean destinationFound = false;
while( !priorityQueue.isEmpty() && destinationFound == false){
// Getting the minimum distance vertex from priority queue
Vertex actualVertex = priorityQueue.poll();
System.out.println("working on: " + actualVertex.getID());
actualVertex = graphReader.SetAdjList(actualVertex);
for(Edge edge : actualVertex.getAdjacenciesList()){
Vertex v = edge.getTargetVertex();
System.out.println("a Neighbor is: " + v.getID());
if(!v.isVisited()) {
if(v.getID() == destination.getID()) {
System.out.println("Destination found");
Path path = new Path(previousVertex);
pathFound = Optional.of(path);
destinationFound = true;
break;
}
double newDistance = actualVertex.getDistanceFromSource() + edge.getWeight();
if( newDistance < v.getDistanceFromSource() ){
priorityQueue.remove(v);
v.setDistanceFromSource(newDistance);
v.setPredecessor(actualVertex);
priorityQueue.add(v);
System.out.println("Added: " + v.getID());
}
}
}
actualVertex.setVisited(true);
}
return pathFound;
}
public List<Vertex> getPath() {
List<Vertex> path = new ArrayList<>();
for(Vertex vertex=destination;vertex!=null;vertex=vertex.getPredecessor()){
path.add(vertex);
}
Collections.reverse(path);
return path;
}
}
Arham Siddiqui :
The following portion in your code is called when the destination is reached:
if(v.getID() == destination.getID()) {
System.out.println("Destination found");
Path path = new Path(previousVertex);
pathFound = Optional.of(path);
destinationFound = true;
break;
}
That respective v never has its predecessor set, which is what your getPath()
method depends on. Consider setting it in the if-statement, as such:
if(v.getID() == destination.getID()) {
System.out.println("Destination found");
destination.setPredecessor(actualVertex); // sets the predecessor for backwards traversal
Path path = new Path(previousVertex);
pathFound = Optional.of(path);
destinationFound = true;
break;
}