next up previous index
Next: Shortest path methods Up: Java implementation Previous: The heap   Index

The basic algorithm

We shall implement Dijkstra's algorithm in a class which is an extension of the WeightedGraph class called PositiveWeightedGraph. The code for the basic algorithm is shown in Figure 13.3.

Figure 13.3: The basic code for Dijkstra's algorithm.
private void dijkstra(Node origin) {

    Iterator i = nodeMap.iterator();
    while (i.hasNext()) {
        Node n = (Node) ((LookupTable.Entry) i.next()).value();
        ((WorkSpace) n.work).visited = false;
        ((WorkSpace) n.work).settled = false;
    }
    ((WorkSpace) origin.work).visited = true;
    ((WorkSpace) origin.work).distance = 0;

    PriorityQueue q = new BinaryHeap();
    q.add(new HeapItem(origin, 0));
    while (!q.isEmpty()) {
        Node v = ((HeapItem) q.remove()).node;
        WorkSpace vv = (WorkSpace) v.work;
        if (!vv.settled) {
            vv.settled = true;
            Iterator tips = v.adjacent.iterator();
            while (tips.hasNext()) {
                Tip t = (Tip) tips.next();
                Node w = t.head;
                int c = t.weight;
                if (c < 0) {
                    throw new ArithmeticException("Negative weight in graph");
                }
                int d = vv.distance + c;
                WorkSpace ww = (WorkSpace) w.work;
                if (!ww.visited || ww.distance > d) {
                    ww.visited = true;
                    ww.distance = d;
                    ww.previous = v;
                    q.add(new HeapItem(w, d));
                }
            }
        }
    }
}

This assumes that an instance of the WeightedGraph class is in scope, and that we can access its nodeMap, its lists of adjacent arcs, etc. We shall also assume that the required workspace has been allocated and assigned. This means that for each node n in the graph, n.work refers to an instance of the WorkSpace class (compare above). Finally it is assumed that the source node, from which we wish to find shortest paths, is referred to by origin.

The code follows very closely the statement of the algorithm above. The principal point of difference concerns initialisation, where we have adopted a simplification. Remember that $s$ corresponds to origin, $S$ corresponds to settled and $S^{\ast}$ corresponds to visited. The initialisation in the first eight lines corresponds to $S = \emptyset$ and $S^{\ast} = \{s\}$ with $D(s)=0$. However we shall get exactly the initialisation given in the proof above after the first time round the main while loop.

The main while loop first removes the item from the top of the heap. This corresponds to D1. If v is not already settled, then settle it and consider all nodes w adjacent to it by using the tips iterator. If w has not yet been visited, or if there is now a shorter path to w of length d, then insert the pair $({\tt w},{\tt d})$ into the heap. The algorithm terminates when the heap is empty.

This implementation uses the simple PriorityQueue that was implemented before. Ideally the heap should represent the function $D$ and a function only assigns a single value to its argument. For any node w, the heap should contain at most one entry of the form $({\tt w},{\tt d})$; it ought not to contain both $({\tt w},{\tt d})$ and $({\tt w},{\tt d'})$. This means that in the last line of code, if $({\tt w},{\tt d}')$ is already in the heap, and ${\tt d} < {\tt d}'$, we ought to replace $({\tt w},{\tt d}')$ by $({\tt w},{\tt d})$, and then reorder the heap if necessary. This is not difficult in principle, though it requires lengthier code and book-keeping. The code in Figure 13.3 simply leaves the old entry in the heap and ignores it when it emerges. This is the reason for the check

if (!vv.settled) {..}
at the beginning of the main while loop. Once v has emerged from the heap, any other entry for v in the heap is out of date and can be ignored. This also provides a simple way of dealing with multiple arcs between nodes. They all get thrown into the heap (if they are visited in decreasing order) and the heap decides which is the smallest.


next up previous index
Next: Shortest path methods Up: Java implementation Previous: The heap   Index
Peter Williams 2005-06-07