src/work/jacint/dijkstra.h
author marci
Thu, 22 Apr 2004 13:59:37 +0000
changeset 371 b2acba449222
parent 217 fc549fac0dd0
child 372 e6a156fc186d
permissions -rw-r--r--
misc
     1 // -*- C++ -*-
     2 /* 
     3  *template <Graph, T, Heap=FibHeap, LengthMap=Graph::EdgeMap<T> >
     4  *
     5  *Constructor: 
     6  *
     7  *Dijkstra(Graph G, LengthMap length)
     8  *
     9  *
    10  *Methods:
    11  *
    12  *void run(Node s)
    13  *
    14  *T dist(Node v) : After run(s) was run, it returns the distance from s to v. 
    15  *   Returns T() if v is not reachable from s.
    16  *
    17  *Edge pred(Node v) : After run(s) was run, it returns the last 
    18  *   edge of a shortest s-v path. It is INVALID for s and for 
    19  *   the nodes not reachable from s.
    20  *
    21  *bool reached(Node v) : After run(s) was run, it is true iff v is 
    22  *   reachable from s
    23  *
    24  */
    25 
    26 #ifndef HUGO_DIJKSTRA_H
    27 #define HUGO_DIJKSTRA_H
    28 
    29 #include <fib_heap.h>
    30 #include <invalid.h>
    31 
    32 namespace hugo {
    33   
    34   template <typename Graph, typename T, 
    35     typename Heap=FibHeap<typename Graph::Node, T, 
    36     typename Graph::NodeMap<int> >, 
    37     typename LengthMap=typename Graph::EdgeMap<T> >
    38   class Dijkstra{
    39     typedef typename Graph::Node Node;
    40     typedef typename Graph::NodeIt NodeIt;
    41     typedef typename Graph::Edge Edge;
    42     typedef typename Graph::OutEdgeIt OutEdgeIt;
    43     
    44     const Graph& G;
    45     const LengthMap& length;
    46     typename Graph::NodeMap<Edge> predecessor;
    47     typename Graph::NodeMap<T> distance;
    48     //FIXME:
    49     typename Graph::NodeMap<bool> reach;
    50     //typename Graph::NodeMap<int> reach;
    51     
    52   public :
    53     
    54     /*
    55       The distance of the nodes is 0.
    56     */
    57     Dijkstra(Graph& _G, LengthMap& _length) : G(_G), 
    58       length(_length), predecessor(_G), distance(_G), reach(_G) { }
    59     
    60 
    61     void run(Node s) {
    62       
    63       NodeIt u;
    64       for ( G.first(u) ; G.valid(u) ; G.next(u) ) {
    65 	predecessor.set(u,INVALID);
    66 	distance.set(u,0);
    67 	reach.set(u,false);
    68       }
    69      
    70       //FIXME:
    71       typename Graph::NodeMap<bool> scanned(G,false);
    72       //typename Graph::NodeMap<int> scanned(G,false);
    73       typename Graph::NodeMap<int> heap_map(G,-1);
    74       
    75       Heap heap(heap_map);
    76 
    77       heap.push(s,0); 
    78       reach.set(s, true);
    79 
    80       while ( !heap.empty() ) {
    81 	
    82 	Node v=heap.top(); 
    83 	T oldvalue=heap.get(v);
    84 	heap.pop();
    85 	distance.set(v, oldvalue);
    86 	scanned.set(v,true);
    87 
    88 	OutEdgeIt e;
    89 	for( G.first(e,v); G.valid(e); G.next(e)) {
    90 	  Node w=G.head(e); 
    91 	    
    92 	  if ( !scanned[w] ) {
    93 	    if ( !reach[w] ) {
    94 	      reach.set(w,true);
    95 	      heap.push(w,oldvalue+length[e]); 
    96 	      predecessor.set(w,e);
    97 	    } else if ( oldvalue+length[e] < heap.get(w) ) {
    98 	      predecessor.set(w,e);
    99 	      heap.decrease(w, oldvalue+length[e]); 
   100 	    }
   101 	  }
   102 	}
   103       }
   104     }
   105     
   106     T dist(Node v) {
   107       return distance[v];
   108     }
   109 
   110     Edge pred(Node v) {
   111       return predecessor[v];
   112     }
   113      
   114     bool reached(Node v) {
   115       return reach[v];
   116     }
   117     
   118   };
   119   
   120 }
   121 
   122 #endif
   123 
   124