src/test/dijkstra_heap_test.cc
author alpar
Fri, 08 Apr 2005 14:02:43 +0000
changeset 1324 eca073533990
parent 1194 7bce0ef61d6b
permissions -rw-r--r--
Only lp_xyz's are linked against -lglpk
alpar@906
     1
/* -*- C++ -*-
alpar@921
     2
 * src/test/dijkstra_heap_test.cc - Part of LEMON, a generic C++ optimization library
alpar@906
     3
 *
alpar@1164
     4
 * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
alpar@906
     5
 * (Egervary Combinatorial Optimization Research Group, EGRES).
alpar@906
     6
 *
alpar@906
     7
 * Permission to use, modify and distribute this software is granted
alpar@906
     8
 * provided that this copyright notice appears in all copies. For
alpar@906
     9
 * precise terms see the accompanying LICENSE file.
alpar@906
    10
 *
alpar@906
    11
 * This software is provided "AS IS" with no warranty of any kind,
alpar@906
    12
 * express or implied, and with no claim as to its suitability for any
alpar@906
    13
 * purpose.
alpar@906
    14
 *
alpar@906
    15
 */
alpar@906
    16
jacint@384
    17
//Tests dijsktra.h with two heap implementations:
jacint@384
    18
//the default binary heap of bin_heap.h, and the 
jacint@384
    19
//Fibonacci heap of fib_heap.h.
jacint@384
    20
jacint@384
    21
//The input is a graph in standard dimacs format from the standard input (like
alpar@921
    22
//in /lemon_loc/testfiles/dimacs). It runs dijkstra.h on this graph with both
jacint@422
    23
//heaps, checking two postconditions:
jacint@384
    24
jacint@384
    25
//- if the edges e=uv of the shortest path tree reported by dijkstra.h have
jacint@384
    26
//dist(v)-dist(u)=length(e)
jacint@384
    27
jacint@384
    28
// - if all edges e=uv with u reachable from the root have
jacint@384
    29
//dist(v)-dist(u)>=length(e)
jacint@384
    30
#include <iostream>
jacint@384
    31
#include <math.h>
jacint@384
    32
alpar@921
    33
#include <lemon/smart_graph.h>
deba@1194
    34
deba@1194
    35
#include <lemon/graph_writer.h>
deba@1194
    36
#include <lemon/map_utils.h>
deba@1194
    37
deba@1194
    38
alpar@921
    39
#include <lemon/dimacs.h>
alpar@921
    40
#include <lemon/dijkstra.h>
alpar@921
    41
#include <lemon/time_measure.h>
deba@1194
    42
#include <lemon/graph_utils.h>
deba@1194
    43
alpar@921
    44
#include <lemon/bin_heap.h>
alpar@921
    45
#include <lemon/fib_heap.h>
deba@1194
    46
#include <lemon/radix_heap.h>
jacint@384
    47
alpar@921
    48
using namespace lemon;
jacint@384
    49
deba@1194
    50
typedef ListGraph Graph;
deba@1194
    51
deba@1194
    52
typedef Graph::Edge Edge;
deba@1194
    53
typedef Graph::Node Node;
deba@1194
    54
typedef Graph::EdgeIt EdgeIt;
deba@1194
    55
typedef Graph::NodeIt NodeIt;
deba@1194
    56
typedef Graph::EdgeMap<int> LengthMap;
deba@1194
    57
deba@1194
    58
deba@1194
    59
struct FibTraits : public DijkstraDefaultTraits<Graph, LengthMap> {
deba@1194
    60
  typedef FibHeap<Graph::Node, LengthMap::Value, Graph::NodeMap<int> > Heap;
deba@1194
    61
};
deba@1194
    62
deba@1194
    63
struct RadixTraits : public DijkstraDefaultTraits<Graph, LengthMap> {
deba@1194
    64
  typedef RadixHeap<Graph::Node, Graph::NodeMap<int> > Heap;
deba@1194
    65
};
deba@1194
    66
deba@1194
    67
deba@1194
    68
int main(int argc, const char* argv[]) {
jacint@384
    69
  
jacint@384
    70
deba@1194
    71
  Graph graph;
deba@1194
    72
  Node s, t;
deba@1194
    73
  LengthMap cap(graph);
deba@1194
    74
  readDimacs(std::cin, graph, cap, s, t);
deba@1194
    75
  Timer ts;
jacint@384
    76
deba@1194
    77
  GraphWriter<Graph> writer(std::cout, graph);
deba@1194
    78
deba@1194
    79
  IdMap<Graph, Node> nodeIdMap(graph);
deba@1194
    80
  writer.addNodeMap("id", nodeIdMap);
deba@1194
    81
deba@1194
    82
  IdMap<Graph, Edge> edgeIdMap(graph);
deba@1194
    83
  writer.addEdgeMap("id", edgeIdMap);
deba@1194
    84
deba@1194
    85
  writer.addEdgeMap("cap", cap);
deba@1194
    86
deba@1194
    87
  writer.run();
jacint@384
    88
    
jacint@384
    89
  std::cout <<
jacint@384
    90
    "\n  Testing dijkstra.h with binary heap implementation bin_heap.h,"
jacint@384
    91
	    <<std::endl;
jacint@384
    92
  std::cout<<"  on a graph with " << 
deba@1194
    93
    countNodes(graph) << " nodes and " << countEdges(graph) << " edges..."
jacint@384
    94
	   << std::endl<<std::endl;
deba@1194
    95
deba@1194
    96
jacint@384
    97
  Dijkstra<Graph, LengthMap> 
deba@1194
    98
    dijkstra_test(graph, cap);
jacint@384
    99
  ts.reset();
deba@1194
   100
   dijkstra_test.run(s);
jacint@384
   101
  std::cout << "elapsed time: " << ts << std::endl;
deba@1194
   102
jacint@384
   103
  int error1=0;
jacint@384
   104
  int error2=0;
jacint@384
   105
deba@1194
   106
  for(EdgeIt e(graph); e!=INVALID; ++e) {
deba@1194
   107
    Node u=graph.source(e); 
deba@1194
   108
    Node v=graph.target(e);
jacint@384
   109
    if ( dijkstra_test.dist(v) - dijkstra_test.dist(u) > cap[e] )
jacint@384
   110
      if ( dijkstra_test.reached(u) ) {
alpar@986
   111
	std::cout<<"Error! dist(target)-dist(source)- edge_length= " 
jacint@384
   112
		 <<dijkstra_test.dist(v) - dijkstra_test.dist(u) 
jacint@384
   113
	  - cap[e]<<std::endl;
jacint@384
   114
	++error1;
jacint@384
   115
      }
jacint@384
   116
  }
jacint@384
   117
jacint@449
   118
  NodeIt v;
deba@1194
   119
  for(NodeIt v(graph); v!=INVALID; ++v) {
jacint@384
   120
    if ( dijkstra_test.reached(v) ) {
jacint@384
   121
      Edge e=dijkstra_test.pred(v);
alpar@1195
   122
      if(e!=INVALID) {
alpar@1195
   123
	Node u=graph.source(e);
alpar@1195
   124
	if ( dijkstra_test.dist(v) - dijkstra_test.dist(u) != cap[e] ) {
alpar@1195
   125
	  std::cout<<"Error in a shortest path tree edge! Difference: " 
alpar@1195
   126
		   <<std::abs(dijkstra_test.dist(v) - dijkstra_test.dist(u) 
alpar@1195
   127
			      - cap[e])<<std::endl;
alpar@1195
   128
	  ++error2;
alpar@1195
   129
	}
jacint@384
   130
      }
jacint@384
   131
    }
jacint@384
   132
  }
alpar@1195
   133
  
jacint@384
   134
jacint@384
   135
  
jacint@384
   136
  std::cout << error1 << " non-tree and " << error2 
jacint@384
   137
	    << " shortest path tree edge is erroneous."<<std::endl;
jacint@384
   138
jacint@384
   139
jacint@384
   140
jacint@384
   141
  std::cout <<
jacint@449
   142
    "\n\n  Testing dijkstra.h with Fibonacci heap implementation fib_heap.h,"
jacint@384
   143
	    <<std::endl;
jacint@384
   144
  std::cout<<"  on a graph with " << 
deba@1194
   145
    countNodes(graph) << " nodes and " << countEdges(graph) << " edges..."
jacint@384
   146
	   << std::endl<<std::endl;
jacint@384
   147
  
deba@1194
   148
deba@1194
   149
  Dijkstra<Graph, LengthMap, FibTraits> 
deba@1194
   150
    dijkstra_test2(graph, cap);
jacint@384
   151
  ts.reset();
jacint@384
   152
  dijkstra_test2.run(s);
jacint@384
   153
  std::cout << "elapsed time: " << ts << std::endl;
jacint@384
   154
  
jacint@384
   155
  error1=0;
jacint@384
   156
  error2=0;
jacint@384
   157
deba@1194
   158
  for(EdgeIt e(graph); e!=INVALID; ++e) {
deba@1194
   159
    Node u=graph.source(e);
deba@1194
   160
    Node v=graph.target(e);
jacint@384
   161
    if ( dijkstra_test2.dist(v) - dijkstra_test2.dist(u) > cap[e] )
jacint@384
   162
      if ( dijkstra_test2.reached(u) ) {
alpar@986
   163
	std::cout<<"Error! dist(target)-dist(source)- edge_length= " 
jacint@384
   164
		 <<dijkstra_test2.dist(v) - dijkstra_test2.dist(u) 
jacint@384
   165
	  - cap[e]<<std::endl;
jacint@384
   166
	++error1;
jacint@384
   167
      }
jacint@384
   168
  }
jacint@384
   169
deba@1194
   170
  for(NodeIt n(graph); v!=INVALID; ++v) {
jacint@384
   171
    if ( dijkstra_test2.reached(v) ) {
jacint@384
   172
      Edge e=dijkstra_test2.pred(v);
alpar@1195
   173
      if(e!=INVALID) {
alpar@1195
   174
	Node u=graph.source(e);
alpar@1195
   175
	if ( dijkstra_test2.dist(v) - dijkstra_test2.dist(u) != cap[e] ) {
alpar@1195
   176
	  std::cout<<"Error in a shortest path tree edge! Difference: " 
alpar@1195
   177
		   <<std::abs(dijkstra_test2.dist(v) - dijkstra_test2.dist(u) 
alpar@1195
   178
			      - cap[e])<<std::endl;
alpar@1195
   179
	  ++error2;
alpar@1195
   180
	}
jacint@384
   181
      }
jacint@384
   182
    }
jacint@384
   183
  }
alpar@1195
   184
  
jacint@384
   185
jacint@384
   186
  std::cout << error1 << " non-tree and " << error2 
jacint@384
   187
	    << " shortest path tree edge is erroneous."<<std::endl;
jacint@384
   188
deba@1194
   189
  std::cout <<
deba@1194
   190
    "\n\n  Testing dijkstra.h with Radix heap implementation radix_heap.h,"
deba@1194
   191
	    <<std::endl;
deba@1194
   192
  std::cout<<"  on a graph with " << 
deba@1194
   193
    countNodes(graph) << " nodes and " << countEdges(graph) << " edges..."
deba@1194
   194
	   << std::endl<<std::endl;
deba@1194
   195
deba@1194
   196
deba@1194
   197
  Dijkstra<Graph, LengthMap, RadixTraits> 
deba@1194
   198
    dijkstra_test3(graph, cap);
deba@1194
   199
  ts.reset();
deba@1194
   200
  dijkstra_test3.run(s);
deba@1194
   201
  std::cout << "elapsed time: " << ts << std::endl;
deba@1194
   202
  
deba@1194
   203
deba@1194
   204
  error1=0;
deba@1194
   205
  error2=0;
deba@1194
   206
deba@1194
   207
  for(EdgeIt e(graph); e!=INVALID; ++e) {
deba@1194
   208
    Node u=graph.source(e);
deba@1194
   209
    Node v=graph.target(e);
deba@1194
   210
    if ( dijkstra_test3.dist(v) - dijkstra_test3.dist(u) > cap[e] )
deba@1194
   211
      if ( dijkstra_test3.reached(u) ) {
deba@1194
   212
	std::cout<<"Error! dist(target)-dist(source)- edge_length= " 
deba@1194
   213
		 <<dijkstra_test3.dist(v) - dijkstra_test3.dist(u) 
deba@1194
   214
	  - cap[e]<<std::endl;
deba@1194
   215
	++error1;
deba@1194
   216
      }
deba@1194
   217
  }
deba@1194
   218
deba@1194
   219
  for(NodeIt n(graph); v!=INVALID; ++v) {
deba@1194
   220
    if ( dijkstra_test3.reached(v) ) {
deba@1194
   221
      Edge e=dijkstra_test3.pred(v);
alpar@1195
   222
      if(e!=INVALID) {
alpar@1195
   223
	Node u=graph.source(e);
alpar@1195
   224
	if ( dijkstra_test3.dist(v) - dijkstra_test3.dist(u) != cap[e] ) {
alpar@1195
   225
	  std::cout<<"Error in a shortest path tree edge! Difference: " 
alpar@1195
   226
		   <<std::abs(dijkstra_test3.dist(v) - dijkstra_test3.dist(u) 
alpar@1195
   227
			      - cap[e])<<std::endl;
alpar@1195
   228
	  ++error2;
alpar@1195
   229
	}
deba@1194
   230
      }
deba@1194
   231
    }
deba@1194
   232
  }
alpar@1195
   233
  
deba@1194
   234
deba@1194
   235
  std::cout << error1 << " non-tree and " << error2 
deba@1194
   236
	    << " shortest path tree edge is erroneous."<<std::endl;
jacint@384
   237
jacint@384
   238
  return 0;
jacint@384
   239
}