All this discussion of weighted directed graphs has assumed that the weights are integers. Dijkstra's algorithm assumes they are non-negative. But evidently, they don't have to be integers. Floating point numbers would do just as well. A thoughtful person might ask what are the relevant properties these two categories share? This leads to the question, what are the weakest assumptions about the labels of arcs in weighted graphs necessary for the notions of path length, shortest path etc. to be well defined and computable?
Examination of Dijkstra's algorithm shows that these assumptions are
really quite weak. We certainly need an operation of addition and a
relation of ordering. We don't need multiplication or division, or
even subtraction. All we need is that addition is associative:
In short, we need an (additive) monoid with translation invariant total ordering. This can be considered as an extension of the Comparable interface. Let us call it Addable for simplicity:
public interface Addable extends Comparable {
public Addable plus(Addable other);
public Addable zero();
}
Naturally we cannot ensure when specifying the interface that the four
conditions above are satisfied; that must be left to the implementer.
Note, interestingly, that commutativity is not required by Dijkstra's
algorithm:
a.plus(b) does not have to equal
b.plus(a).
The implication of this approach is that our code for the WeightedGraph class should be formulated in terms of Addable weights. WeightedGraph should provide an arc insertion method
public void add(Object tail, Object head, Addable weight);and PositiveWeightedGraph class should provide
public Addable shortestPathLength(Object origin, Object destination);Implementing these ideas is straightforward and is left to the reader.