I need to implement dijkstra's algorithm and I've done so using this Wikipedia page. I've done it both with priority queue and without.
Both versions work 100% correct, however I need the faster one (priority queue one). The problem is that it isn't faster. My tests show "faster" one runs in more than double the time that "slower" one does, it shouldn't do that. What am I doing wrong?
//more primitive version that in fact runs faster (it shouldn't)
//source is starting node, adj adjacency list, Road represents one edge
private static int dijkstra (int source, ArrayList<Road>[] adj) {
HashSet<Integer> vertices = new HashSet<>();
int[] dist = new int[adj.length];
int[] prev = new int[adj.length];
for (int i = 0; i < adj.length; i++) {
dist[i] = Integer.MAX_VALUE;
prev[i] = Integer.MAX_VALUE;
vertices.add(i);
}
dist[source] = 0;
while (!vertices.isEmpty()) {
int currentPathLen = Integer.MAX_VALUE, current = -1;
for (int v: vertices) {
if (dist[v] < currentPathLen) {
current = v;
currentPathLen = dist[current];
}
}
vertices.remove(current);
for (Road v: adj[current]) {
int alt = dist[current] + v.distance;
if (alt < dist[v.end]) {
dist[v.end] = alt;
prev[v.end] = current;
}
}
}
}
//this one should run faster
//same variables as primitive version, except for Node,
//which is made only for PQ prioritizing
private static int improvedDijkstra(int source, ArrayList<Road>[] adj) {
PriorityQueue<Node> vertices = new PriorityQueue<>();
int[] dist = new int[adj.length];
int[] prev = new int[adj.length];
dist[source] = 0;
for (int i = 0; i < adj.length; i++) {
if (i != source) {
dist[i] = Integer.MAX_VALUE;
prev[i] = Integer.MAX_VALUE;
}
vertices.add(new Node(i, dist[i]));
}
while (!vertices.isEmpty()) { //O(n)
Node u = vertices.poll(); //this should have O(logn)
for(Road v: adj[u.value]) { // I suspect the problem is this loop, but it is same
// as in Wikipedia page
int alt = dist[u.value] + v.distance;
if (alt < dist[v.end]) {
dist[v.end] = alt;
prev[v.end] = alt;
vertices.add(new Node(v.end, alt)); //this should have O(logn)
}
}
}
insert
takes O(logn). This makes your PQ version is O( |V|log|V| + |E|log|V| ). If your graph is fully connected, that's O( |V|^2 log|V| ). \$\endgroup\$