“The shortest-path algorithms are all single-source algorithms, which begin at some starting point and compute the shortest paths from it to all vertices.” Weiss ALG0183 Algorithms & Data Structures Lecture 22 n negative weights present (Bellman-Ford algorithm) Chapter 14 Weiss 8/25/2009 ALG0183 Algorithms & Data Structures by Dr Andy Brooks 1 Java exception handling in Graph.java. • In u, d, n, and a, an exception is thrown if the start vertex is not found. Vertex w = vertexMap.get( startName ); if( w == null ) throw new NoSuchElementException(“Start vertex not found" ); • In printPath(String), an exception is thrown if the destination vertex is not found. Vertex w = vertexMap.get( destName ); if( w == null ) throw new NoSuchElementException( "Destination vertex not found" ); • In d (Dijkstra), an exception is thrown if the graph has an negative edge. if( cvw < 0 ) throw new GraphException( "Graph has negative edges" ); 8/25/2009 ALG0183 Algorithms & Data Structures by Dr Andy Brooks 2 Java exception handling in Graph.java. • In n (Bellman-Ford), an exception is thrown if a graph has an negative cycle. if( v.scratch++ > 2 * vertexMap.size( ) ) throw new GraphException( "Negative cycle detected" ); • In a (acyclic topological sort), an exception is thrown if a graph has a cycle. if( iterations != vertexMap.size( ) ) throw new GraphException( "Graph has a cycle!" ); 8/25/2009 ALG0183 Algorithms & Data Structures by Dr Andy Brooks 3 Figure 14.28 A graph with a negative cost cycle (Weiss ©Addison-Wesley) • The path from V3 to V4 has a cost of 2. • The path V3V4V1V3V4, going through the destination V4 twice, has a cost of -3! • We could stay in the cycle an arbitrary number of times, lowering the cost each cycle! • “Thus the shortest path between these two points (V3 & V4) is undefined.” Weiss 8/25/2009 ALG0183 Algorithms & Data Structures by Dr Andy Brooks 4 Figure 14.28 A graph with a negative cost cycle (Weiss ©Addison-Wesley) • The shortest path from V2 to V5 is also undefined i.e. the problem with a negative cost cycle is not restricted to nodes within the cycle (V1, V3, V4). • When a negative-cost cycle is present, many shortest paths in a graph can be undefined. • “Negative-cost edges by themselves are not necessarily bad; it is the cycles that are.” Weiss 8/25/2009 ALG0183 Algorithms & Data Structures by Dr Andy Brooks 5 Bellman-Ford Algorithm http://www.itl.nist.gov/div897/sqg/dads/HTML/bellmanford.html Definition: An efficient algorithm to solve the single-source shortest-path problem. Weights may be negative. The algorithm initializes the distance to the source vertex to 0 and all other vertices to ∞. It then does V-1 passes (V is the number of vertices) over all edges relaxing, or updating, the distance to the destination of each edge. Finally it checks each edge again to detect negative weight cycles, in which case it returns false. The time complexity is O(VE), where E is the number of edges. The algorithm has to iterate over the edges several times to make sure that the effect of any negative edge is fully propagated. 8/25/2009 ALG0183 Algorithms & Data Structures by Dr Andy Brooks 6 SUNY Binghamton CS480 mini-lectures -- Bellman-Ford http://www.youtube.com/watch?v=gzXSFdXqrH8 if a better path has been found |V| is the number of vertices |E| is the number of edges 8/25/2009 ALG0183 Algorithms & Data Structures by Dr Andy Brooks 7 Pseudocode implementation (http://en.wikipedia.org/wiki/Bellman-Ford_algorithm) // Step 1: Initialize graph for each vertex v in vertices: if v is source then v.distance := 0 else v.distance := infinity v.predecessor := null // Step 2: relax edges repeatedly for i from 1 to size(vertices)-1: for each edge uv in edges: // uv is the edge from u to v u := uv.source v := uv.destination if u.distance + uv.weight < v.distance: if a better path has been found v.distance := u.distance + uv.weight v.predecessor := u // Step 3: check for negative-weight cycles (-3) for each edge uv in edges: u := uv.source 3 -5 zero-cost cycle v := uv.destination (2) if u.distance + uv.weight < v.distance: 2 error "Graph contains a negative-weight cycle" 8/25/2009 ALG0183 Algorithms & Data Structures by Dr Andy Brooks 8 Example from Digraphs: Theory, Algorithms and Applications, 1st Edition , Jørgen Bang-Jensen and Gregory Gutin http://www.cs.rhul.ac.uk/books/dbook/main.pdf Initialize graph. For assessment purposes, students should be able to produce the working shown in (a)-(f) for any small graph. ALG0183 Algorithms & Data Structures by 8/25/2009 Dr Andy Brooks 9 e c b d a * Infinity is represented by a large finite number in code, so a distance cost to a node might be reduced from “infinity”. ab, b still infinite ac, c still infinite * ba, a still infinite bc, c still infinite * cb, b still infinite da, a still infinite * dc, c still infinite ec, c still infinite *ed, d still infinite sd, d->4 se, e->8 “In the inner loop of the second step of the algorithm the arcs are considered in the lexicographic order: ab, ac, ba, bc, cb, da, dc, ec, ed, sd, se.” 8/25/2009 ALG0183 Algorithms & Data Structures by Dr Andy Brooks 10 e c b d a * Infinity is represented by a large finite number in code, so a distance cost to a node might be reduced from “infinity”. ab, b still infinite ac, c still infinite * ba, a still infinite bc, c still infinite * cb, b still infinite da, a ->8 dc, c->2 ec, c no change ed, d->3 sd, d no change se, e no change “In the inner loop of the second step of the algorithm the arcs are considered in the lexicographic order: ab, ac, ba, bc, cb, da, dc, ec, ed, sd, se.” 8/25/2009 ALG0183 Algorithms & Data Structures by Dr Andy Brooks 11 e c b d a ab, b->17 ac, c no change ba, a no change bc, c no change cb, b->0 da, a ->7 dc, c->1 ec, c no change ed, d no change sd, d no change se, e no change “In the inner loop of the second step of the algorithm the arcs are considered in the lexicographic order: ab, ac, ba, bc, cb, da, dc, ec, ed, sd, se.” 8/25/2009 ALG0183 Algorithms & Data Structures by Dr Andy Brooks 12 e c b d a ab, b no change ac, c no change ba, a->-3 bc, c no change cb, b->-1 da, a no change dc, c no change ec, c no change ed, d no change sd, d no change se, e no change “In the inner loop of the second step of the algorithm the arcs are considered in the lexicographic order: ab, ac, ba, bc, cb, da, dc, ec, ed, sd, se.” 8/25/2009 ALG0183 Algorithms & Data Structures by Dr Andy Brooks 13 e c b d a 6 vertices 5th iteration ab, b no change ac, c no change ba, a->-4 bc, c no change cb, b no change da, a no change dc, c no change ec, c no change ed, d no change sd, d no change se, e no change “In the inner loop of the second step of the algorithm the arcs are considered in the lexicographic order: ab, ac, ba, bc, cb, da, dc, ec, ed, sd, se.” 8/25/2009 ALG0183 Algorithms & Data Structures by Dr Andy Brooks 14 Features of algorithm n by Weiss. • “Whenever a vertex has its distance lowered, it must be placed on a queue. This may happen repeatedly for each vertex.” • “Consequently, we use the queue as in the unweighted algorithm, but we use Dv + cv,w as the distance measure (as in Dijkstra´s algorithm). Note: In Weiss´s implementation, the outer loop is controlled by a test on the queue. Weiss´s implementation might require less computation than an implementation which is based on a fixed number of iterations through all the edges: we need an experiment! 8/25/2009 ALG0183 Algorithms & Data Structures by Dr Andy Brooks 15 Features of algorithm n by Weiss. • The variable scratch is incremented when a vertex is put on the queue (“enqueued”). • The variable scratch is also incremented when a vertex is taken off the queue (“dequeued”). • If the vertex is on the queue, scratch is odd. • The number of times a vertex has been dequeued is scratch/2. • “We do not enqueue a vertex if it is already on the queue.” 8/25/2009 ALG0183 Algorithms & Data Structures by Dr Andy Brooks 16 public void negative( String startName ) { clearAll( ); call to the reset method for each vertex Vertex start = vertexMap.get( startName ); get start vertex from the map if( start == null ) throw new NoSuchElementException( "Start vertex not found" ); Queue<Vertex> q = new LinkedList<Vertex>( ); make queue q.add( start ); add the start to the queue start.dist = 0; start to itself has distance zero start.scratch++; start is enqueued, so increment scratch The increment operator in Java is ++. The increment operator adds one. If a postfix increment is used (e.g. a++) then the value of a is used in the expression in which a resides, and then a is incremented by 1. 8/25/2009 ALG0183 Algorithms & Data Structures by Dr Andy Brooks 17 while( !q.isEmpty( ) ) { Vertex v = q.remove( ); remove the head of the queue if( v.scratch++ > 2 * vertexMap.size( ) ) scratch/2 is number times dequeued throw new GraphException( "Negative cycle detected" ); for( Edge e : v.adj ) { Vertex w = e.dest; double cvw = e.cost; iterate over a vertex´s edges if( w.dist > v.dist + cvw ) { if a better path has been found w.dist = v.dist + cvw; w.prev = v; note of previous vertext (v) on the current shortest path // Enqueue only if not already on the queue if( w.scratch++ % 2 == 0 ) if w.scratch is odd, w is already on the queue q.add( w ); add to queue else w.scratch--; // undo the enqueue increment w not added to queue } } } } 8/25/2009 When better paths are no longer found, vertices are no longer added to the queue, and the algorithm terminates when the queue is empty. ALG0183 Algorithms & Data Structures by Dr Andy Brooks 18 Note this graph also contains a positive-cost cycle. NegGraphTest1.txt V2 V0 4 V2 V5 5 V0 V1 2 V0 V3 1 V3 V2 2 V3 V5 8 V3 V6 4 V6 V5 1 V3 V4 2 V1 V3 3 V4 V1 -10 V4 V6 6 File read... 7 vertices Enter start node:V2 Enter destination node:V4 Enter algorithm (u, d, n, a ): n gr.GraphException: Negative cycle detected Enter start node: 8/25/2009 ALG0183 Algorithms & Data Structures by Dr Andy Brooks 19 NegGraphTest1.txt V2 V0 4 V2 V5 5 V0 V1 2 V0 V3 1 V3 V2 2 V3 V5 8 V3 V6 4 V6 V5 1 V3 V4 2 X V1 V3 3 V4 V1 -10 V4 V6 6 Skipping ill-formatted line File read... 7 vertices Enter start node:V2 Enter destination node:V1 Enter algorithm (u, d, n, a ): n (Cost is: -3.0) V2 to V0 to V3 to V4 to V1 Enter start node: ALG0183 Algorithms & Data Structures by 8/25/2009 Dr Andy Brooks 20