Various answers above propose simply Dijkstra algorithm with a modified weight function. For example, w(e) = -c(e)
, or 'w(e) = 1/c(e)', where w(e)
is the weight of an edge, used by the algorithm, and c(e)
is the capacity of the edge in the original problem formulation.
These don't work.
One can easily create counter-examples that this would yield incorrect results. For example, consider the graph:
a---3-->b---3--->c---3-->d
\ ^
\ |
\----------3----------|
Assume the value of a
('distance of node a
in the algorithm formulation) is zero. The two paths from a
to d
are equivalent in this problem. Yet, if we just negate the edge capacity, distance(d), using the long path, is (-3)+(-3)+(-3) = -9
while using the short path it would be -3
. If we inverse the edge capacity, distance(d) using the long path would be (1/3)+(1/3)+(1/3)=1
, while it would just be (1/3)
using the short one.
What will work is modifying the relaxation step of the algorithm, i.e. instead of using the functions of addition (+
) and less-than (<
), using respectively functions min
and greater-than (>
), and use a max-heap instead of a min-heap. We could avoid the last two modifications if we negate the edge weights and use less-than, but no way we can avoid replacing +
, since we need some operator @
where a @ a = a
for all a
values, whereas +
only works for a=0
.
So, the only correct answer I see is the very first one given, by Keith Randall.
A nice exercise would be to formally prove that the modified algorithm is correct. What needs to be proved is:
- if u
is the node with maximum value d(u)
at any loop iteration, then no path involving unmarked nodes can create a path to u
yield a distance larger than d(u)
.
Intuitively it is easy to see, since all other unmarked nodes have distance less than (or equal to) the distance of 'u' (because we choose u
as the one with maximum distance), and the distance of the generated paths is produced by successive invocations of min
, thus it can only grow smaller, not larger.