jacint@384: //Tests dijsktra.h with two heap implementations:
jacint@384: //the default binary heap of bin_heap.h, and the 
jacint@384: //Fibonacci heap of fib_heap.h.
jacint@384: 
jacint@384: //The input is a graph in standard dimacs format from the standard input (like
jacint@422: //in /hugo_loc/testfiles/dimacs). It runs dijkstra.h on this graph with both
jacint@422: //heaps, checking two postconditions:
jacint@384: 
jacint@384: //- if the edges e=uv of the shortest path tree reported by dijkstra.h have
jacint@384: //dist(v)-dist(u)=length(e)
jacint@384: 
jacint@384: // - if all edges e=uv with u reachable from the root have
jacint@384: //dist(v)-dist(u)>=length(e)
jacint@384: #include <iostream>
jacint@384: #include <math.h>
jacint@384: 
ladanyi@542: #include <hugo/smart_graph.h>
ladanyi@542: #include <hugo/dimacs.h>
ladanyi@542: #include <hugo/dijkstra.h>
ladanyi@542: #include <hugo/time_measure.h>
ladanyi@542: #include <hugo/bin_heap.h>
ladanyi@542: #include <hugo/fib_heap.h>
jacint@384: 
jacint@384: using namespace hugo;
jacint@384: 
jacint@384: int main(int, char **) {
jacint@384:   
jacint@384:   typedef SmartGraph Graph;
jacint@384: 
jacint@384:   typedef Graph::Edge Edge;
jacint@384:   typedef Graph::Node Node;
jacint@384:   typedef Graph::EdgeIt EdgeIt;
jacint@384:   typedef Graph::NodeIt NodeIt;
jacint@384:   typedef Graph::EdgeMap<int> LengthMap;
jacint@384: 
jacint@384:   Graph G;
jacint@384:   Node s, t;
jacint@384:   LengthMap cap(G);
jacint@384:   readDimacsMaxFlow(std::cin, G, s, t, cap);
jacint@384:   Timer ts;
jacint@384:     
jacint@384:   std::cout <<
jacint@384:     "\n  Testing dijkstra.h with binary heap implementation bin_heap.h,"
jacint@384: 	    <<std::endl;
jacint@384:   std::cout<<"  on a graph with " << 
jacint@384:     G.nodeNum() << " nodes and " << G.edgeNum() << " edges..."
jacint@384: 	   << std::endl<<std::endl;
jacint@384:   
jacint@384:   Dijkstra<Graph, LengthMap> 
jacint@384:     dijkstra_test(G, cap);
jacint@384:   ts.reset();
jacint@384:   dijkstra_test.run(s);
jacint@384:   std::cout << "elapsed time: " << ts << std::endl;
jacint@384:   
jacint@384:   int error1=0;
jacint@384:   int error2=0;
jacint@384: 
jacint@449:   EdgeIt e;
jacint@449:   for(G.first(e); G.valid(e); G.next(e)) {
jacint@384:     Node u=G.tail(e);
jacint@384:     Node v=G.head(e);
jacint@384:     if ( dijkstra_test.dist(v) - dijkstra_test.dist(u) > cap[e] )
jacint@384:       if ( dijkstra_test.reached(u) ) {
jacint@384: 	std::cout<<"Error! dist(head)-dist(tail)- edge_length= " 
jacint@384: 		 <<dijkstra_test.dist(v) - dijkstra_test.dist(u) 
jacint@384: 	  - cap[e]<<std::endl;
jacint@384: 	++error1;
jacint@384:       }
jacint@384:   }
jacint@384: 
jacint@449:   NodeIt v;
jacint@449:   for(G.first(v); G.valid(v); G.next(v)) {
jacint@384:     if ( dijkstra_test.reached(v) ) {
jacint@384:       Edge e=dijkstra_test.pred(v);
jacint@384:       Node u=G.tail(e);
jacint@384:       if ( dijkstra_test.dist(v) - dijkstra_test.dist(u) != cap[e] ) {
jacint@384: 	std::cout<<"Error in a shortest path tree edge! Difference: " 
jacint@384: 		 <<std::abs(dijkstra_test.dist(v) - dijkstra_test.dist(u) 
jacint@384: 			    - cap[e])<<std::endl;
jacint@384: 	++error2;
jacint@384:       }
jacint@384:     }
jacint@384:   }
jacint@384: 
jacint@384: 
jacint@384:   
jacint@384:   std::cout << error1 << " non-tree and " << error2 
jacint@384: 	    << " shortest path tree edge is erroneous."<<std::endl;
jacint@384: 
jacint@384: 
jacint@384: 
jacint@384:   std::cout <<
jacint@449:     "\n\n  Testing dijkstra.h with Fibonacci heap implementation fib_heap.h,"
jacint@384: 	    <<std::endl;
jacint@384:   std::cout<<"  on a graph with " << 
jacint@384:     G.nodeNum() << " nodes and " << G.edgeNum() << " edges..."
jacint@384: 	   << std::endl<<std::endl;
jacint@384:   
jacint@384:   Dijkstra<Graph, LengthMap, FibHeap> 
jacint@384:     dijkstra_test2(G, cap);
jacint@384:   ts.reset();
jacint@384:   dijkstra_test2.run(s);
jacint@384:   std::cout << "elapsed time: " << ts << std::endl;
jacint@384:   
jacint@384:   error1=0;
jacint@384:   error2=0;
jacint@384: 
jacint@449:   for(G.first(e); G.valid(e); G.next(e)) {
jacint@384:     Node u=G.tail(e);
jacint@384:     Node v=G.head(e);
jacint@384:     if ( dijkstra_test2.dist(v) - dijkstra_test2.dist(u) > cap[e] )
jacint@384:       if ( dijkstra_test2.reached(u) ) {
jacint@384: 	std::cout<<"Error! dist(head)-dist(tail)- edge_length= " 
jacint@384: 		 <<dijkstra_test2.dist(v) - dijkstra_test2.dist(u) 
jacint@384: 	  - cap[e]<<std::endl;
jacint@384: 	++error1;
jacint@384:       }
jacint@384:   }
jacint@384: 
jacint@449:   for(G.first(v); G.valid(v); G.next(v)) {
jacint@384:     if ( dijkstra_test2.reached(v) ) {
jacint@384:       Edge e=dijkstra_test2.pred(v);
jacint@384:       Node u=G.tail(e);
jacint@384:       if ( dijkstra_test2.dist(v) - dijkstra_test2.dist(u) != cap[e] ) {
jacint@384: 	std::cout<<"Error in a shortest path tree edge! Difference: " 
jacint@384: 		 <<std::abs(dijkstra_test2.dist(v) - dijkstra_test2.dist(u) 
jacint@384: 			    - cap[e])<<std::endl;
jacint@384: 	++error2;
jacint@384:       }
jacint@384:     }
jacint@384:   }
jacint@384: 
jacint@384: 
jacint@384:   std::cout << error1 << " non-tree and " << error2 
jacint@384: 	    << " shortest path tree edge is erroneous."<<std::endl;
jacint@384: 
jacint@384: 
jacint@384:   return 0;
jacint@384: }