5

In my implementation of Dijkstra's algorithm I have 1 array with all nodes and 1 priority queue with all nodes. Whenever a node is dequeued I update all adjacent nodes with new distance and where it came from, so I can backtrack the path.

The node in the priority queue is updated with new distance and the node in the array is updated where it came from and with new distance. When a node is dequeued the final distance in the array is updated:

  PathInfo current = pq.remove();
  path[current.pos].distance = current.distance;

Is it acceptable to update both the array with info about previous node and the priority queue with distance?

This happens whenever a better distance is found:

      PathInfo key(i, newDistance);
      path[i].distance = newDistance;
      path[i].previous = current.pos;
      pq.decreaseKey(key);

It seems a bit redundant to update my array and priority queue with basically the same info.

I'm currently using a regular array as a data structure in the PQ. Updating the priority is done in linear time and dequeueing is also done in linear time.

What data structure should I use in the priority queue and how should I change a nodes priority?

I'm using C++

Carlj901
  • 1,329
  • 4
  • 24
  • 39

2 Answers2

1

You have two kinds of distances here: your priority queue has "tentative distances" which are subject to update, while your array has "final distances", which are not (because Dijkstra's algorithm doesn't need to update nodes that have been removed from the priority queue).

It appears that you are unnecessarily updating the distances in your array. Perhaps it would also be a good idea to change the field name in your array node to document this: from arrayNode.distance to arrayNode.finalDistance.

In other words: it appears you are using your array nodes to output the results from your Dijkstra's algorithm -- so you should only set the distance in each array node once, when it is removed from the priority queue.


If your priority-queue implementation doesn't provide the ability to query the current distance associated with a given key, please check the behavior of its decreaseKey() operation. If the decreaseKey() operation rejects updates for which the new priority does not actually decrease, then you shouldn't need to perform that check yourself -- you can just call it for each neighbor of the current node.

However, if the decreaseKey() function does not handle that case correctly, and there is no auxiliary query function that would let you perform that check manually, and there is no opportunity to fix either deficiency, then you'll need to maintain redundant information for that purpose....

comingstorm
  • 25,557
  • 3
  • 43
  • 67
  • I have to update the distances in the array. How else am I supposed to compare if the node from my PQ can give a better distance to adjacent nodes? – Carlj901 Feb 19 '13 at 21:41
  • Ideally, you should be able to look it up from your PQ. If this operation is unavailable (and cannot be added to your PQ implementation), then you will need to maintain the redundant information. [I will add a section on this to my answer] – comingstorm Feb 19 '13 at 21:57
  • The most preferable would be if I could maintain a heap in my PQ and have a hash function that map each nodes name (position in 2D array) to it's distance. Not sure how I'd implement this though. – Carlj901 Feb 19 '13 at 22:10
  • Please check my edit -- if `decreaseKey()` is implemented properly for your PQ, I don't think you need anything else. – comingstorm Feb 19 '13 at 22:11
  • That makes sense. Just loop through adjacent nodes and use decreaseKey on each one. Do you have any thoughts on how to implement decreaseKey() in a heap? – Carlj901 Feb 19 '13 at 22:24
  • Maintain a `heapIndex` field in your regular array. It will need to be updated for each heap node you move. – comingstorm Feb 19 '13 at 22:52
0

Data structures which you may use:

Maybe some other to find minimal in array.

When you update priority to node you also must sync datastructure which you preffer.

Note: If you used matrix to check connected node, you may simply not use data structure as it not change algo complexity I will be still O(N^2) (use direct cycle to find node with appropriate priority) Data structure effective when you graph has a lot of nodes and small amount of connections and stored as list of connected nodes (discharged graphs)

Толя
  • 2,839
  • 15
  • 23