问题
Given a weighted directed graph, how can the Dijkstra algorithm be modified to test for the presence of multiple lowest-cost paths between a given pair of nodes?
My current algorithm is as follows: (credit to Weiss)
/**
* Single-source weighted shortest-path algorithm. (Dijkstra)
* using priority queues based on the binary heap
*/
public void dijkstra( String startName )
{
PriorityQueue<Path> pq = new PriorityQueue<Path>( );
Vertex start = vertexMap.get( startName );
if( start == null )
throw new NoSuchElementException( "Start vertex not found" );
clearAll( );
pq.add( new Path( start, 0 ) ); start.dist = 0;
int nodesSeen = 0;
while( !pq.isEmpty( ) && nodesSeen < vertexMap.size( ) )
{
Path vrec = pq.remove( );
Vertex v = vrec.dest;
if( v.scratch != 0 ) // already processed v
continue;
v.scratch = 1;
nodesSeen++;
for( Edge e : v.adj )
{
Vertex w = e.dest;
double cvw = e.cost;
if( cvw < 0 )
throw new GraphException( "Graph has negative edges" );
if( w.dist > v.dist + cvw )
{
w.dist = v.dist +cvw;
w.prev = v;
pq.add( new Path( w, w.dist ) );
}
}
}
}
回答1:
Replace field prev
, the link to previous vertex with a collection prevs
, and change the code slightly:
...
if( w.dist >= v.dist + cvw ) {
if ( w.dist > v.dist + cvw ) {
w.dist = v.dist +cvw;
w.prevs.clear();
}
w.prevs.add(v);
pq.add( new Path( w, w.dist ) );
}
...
回答2:
If you only want to find a single other equal-cost path
Let's suppose you already ran Dijkstra's algorithm once to get a shortest path P
. You can add a tiny cost epsilon
to each edge in P
and run Dijkstra's a second time on the modified graph to get a new path P'
. If P
and P'
contain the same edges, then you can conclude that P
is the unique shortest path. Otherwise, we undo the epsilon
change and compare the lengths of P
and P'
. If the lengths are equal, then clearly P'
is another distinct shortest path. Otherwise, P
is the unique shortest path.
If we want to find all shortest paths
Such an algorithm would necessarily be exponential-time. This is because a graph can have exponentially-many equal-cost paths between two nodes. For example, consider the graph:
A --> B1 --> C --> D1 --> E ...
\ -> \ ->
-> B2 / -> D2 /
There are 4 paths from A
to E
, and if we assume that all edges are equal cost, then all of those paths have equal total cost. By repeating this pattern we can get exponentially-many paths of equal cost.
来源:https://stackoverflow.com/questions/50411987/using-dijkstra-to-detect-multiple-shortest-paths