src/work/jacint/dijkstra.h
author alpar
Sat, 20 Mar 2004 16:07:19 +0000
changeset 215 b3c4e6646f7f
parent 171 ec3d3596e3c9
child 217 fc549fac0dd0
permissions -rw-r--r--
bool map problems solved.
(now operator[] gives back 'std::vector<T>::reference' rather that 'T&')
     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     typename Graph::NodeMap<bool> reach;
    49     
    50   public :
    51     
    52     /*
    53       The distance of the nodes is 0.
    54     */
    55     Dijkstra(Graph& _G, LengthMap& _length) : G(_G), 
    56       length(_length), predecessor(_G), distance(_G), reach(_G) { }
    57     
    58 
    59     void run(Node s) {
    60       
    61       NodeIt u;
    62       for ( G.first(u) ; G.valid(u) ; G.next(u) ) {
    63 	predecessor.set(u,INVALID);
    64 	distance.set(u,0);
    65 	reach.set(u,false);
    66       }
    67      
    68       typename Graph::NodeMap<bool> scanned(G,false);
    69       typename Graph::NodeMap<int> heap_map(G,-1);
    70       
    71       Heap heap(heap_map);
    72 
    73       heap.push(s,0); 
    74       reach.set(s, true);
    75 
    76       while ( !heap.empty() ) {
    77 	
    78 	Node v=heap.top(); 
    79 	T oldvalue=heap.get(v);
    80 	heap.pop();
    81 	distance.set(v, oldvalue);
    82 	scanned.set(v,true);
    83 
    84 	OutEdgeIt e;
    85 	for( G.first(e,v); G.valid(e); G.next(e)) {
    86 	  Node w=G.head(e); 
    87 	    
    88 	  if ( !scanned[w] ) {
    89 	    if ( !reach[w] ) {
    90 	      reach.set(w,true);
    91 	      heap.push(w,oldvalue+length[e]); 
    92 	      predecessor.set(w,e);
    93 	    } else if ( oldvalue+length[e] < heap.get(w) ) {
    94 	      predecessor.set(w,e);
    95 	      heap.decrease(w, oldvalue+length[e]); 
    96 	    }
    97 	  }
    98 	}
    99       }
   100     } 
   101     
   102 
   103     T dist(Node v) {
   104       return distance[v];
   105     }
   106 
   107 
   108     Edge pred(Node v) {
   109       return predecessor[v];
   110     }
   111      
   112 
   113     bool reached(Node v) {
   114       return reach[v];
   115     }
   116     
   117   };
   118   
   119 }
   120 
   121 #endif
   122 
   123