I’m working on a Dijkstra algorithm for university using a PriorityQueue to store the remaining vertices of my graph, ordered by shortest traversal distance.
The Comparator I use:
class DistanceComparator implements Comparator<Integer> {
int[] dist;
public DistanceComparator(int[] d) {
dist = d;
}
@Override
public int compare(Integer i, Integer j)
{
if((dist[i]-dist[j]) < 0) {
return -1;
}
if((dist[i]-dist[j]) > 0) {
return 1;
}
return 0;
}
}
Now the problem I’m facing is that the distances are changing, so the Comparator of my queue would need to be updated frequently.
static PriorityQueue<Integer> refreshQueue(int[] d) {
Comparator<Integer> comp = new DistanceComparator(d);
PriorityQueue<Integer> q = new PriorityQueue<Integer>(adj.length, comp);
for(int i = 0; i < adj.length; i++) {
q.add(i);
}
return q;
}
This does the trick, however it would also strain the required runtime O(num Edges*log(num Vertices)).
How can I eliminate the need to adjust the Comparator each time?
The traditional way to implement Dijkstra’s algorithm in Java is to create a separate class that contains a node and a distance:
and to put those into your priority queue.
You’ll end up with out-of-date
Distobjects reflecting a suboptimal path, but only after you’ve already seen the “optimal” path, so just ignore vertices you’ve already taken out from the priority queue.Basically, don’t change the
Comparator: change the objects being compared.