src/work/jacint/dijkstra.h
changeset 159 0defa5aa1229
child 160 f1a7005e9dff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/src/work/jacint/dijkstra.h	Tue Mar 09 15:32:40 2004 +0000
     1.3 @@ -0,0 +1,124 @@
     1.4 +// -*- C++ -*-
     1.5 +/* 
     1.6 + *template <Graph, T, Heap=FibHeap>
     1.7 + *
     1.8 + *
     1.9 + *Constructor: 
    1.10 + *
    1.11 + *Dijkstra(Graph G, NodeIt s, Graph::EdgeMap<T> length)
    1.12 + *
    1.13 + *
    1.14 + *
    1.15 + *Member functions:
    1.16 + *
    1.17 + *void run()
    1.18 + *
    1.19 + *  The following function should be used after run() was already run.
    1.20 + *
    1.21 + *
    1.22 + *T dist(NodeIt v) : returns the distance from s to v. 
    1.23 + *   It is 0 if v is not reachable from s.
    1.24 + *
    1.25 + *
    1.26 + *EdgeIt pred(NodeIt v) : returns the last edge 
    1.27 + *   of a shortest s-v path. Returns an invalid iterator 
    1.28 + *   if v=s or v is not reachable from s.
    1.29 + *
    1.30 + *
    1.31 + *bool reach(NodeIt v) : true iff v is reachable from s
    1.32 + *
    1.33 + */
    1.34 +
    1.35 +#ifndef DIJKSTRA_HH
    1.36 +#define DIJKSTRA_HH
    1.37 +
    1.38 +#include <fib_heap.h>
    1.39 +
    1.40 +namespace hugo {
    1.41 +
    1.42 +  template <typename Graph, typename T, 
    1.43 +    typename Heap=FibHeap<typename Graph::NodeIt, T, 
    1.44 +    typename Graph::NodeMap<int> > >
    1.45 +    class Dijkstra{
    1.46 +      typedef typename Graph::NodeIt NodeIt;
    1.47 +      typedef typename Graph::EdgeIt EdgeIt;
    1.48 +      typedef typename Graph::OutEdgeIt OutEdgeIt;
    1.49 +      
    1.50 +      Graph& G;
    1.51 +      NodeIt s;
    1.52 +      typename Graph::NodeMap<EdgeIt> predecessor;
    1.53 +      typename Graph::NodeMap<T> distance;
    1.54 +      typename Graph::EdgeMap<T>& length;
    1.55 +      typename Graph::NodeMap<bool> reached;
    1.56 +          
    1.57 +  public :
    1.58 +
    1.59 +    /*
    1.60 +      The distance of the nodes is 0.
    1.61 +    */
    1.62 +    Dijkstra(Graph& _G, NodeIt const _s, 
    1.63 +	     typename Graph::EdgeMap<T>& _length) : 
    1.64 +      G(_G), s(_s), predecessor(G), distance(G), 
    1.65 +      length(_length), reached(G, false) { }
    1.66 +    
    1.67 +      
    1.68 +      void run() {
    1.69 +	
    1.70 +	typename Graph::NodeMap<bool> scanned(G, false);
    1.71 +	typename Graph::NodeMap<int> heap_map(G,-1);
    1.72 +
    1.73 +	Heap heap(heap_map);
    1.74 +
    1.75 +	heap.push(s,0); 
    1.76 +	reached.set(s, true);
    1.77 +
    1.78 +	while ( !heap.empty() ) {
    1.79 +
    1.80 +	  NodeIt v=heap.top(); 
    1.81 +	  T oldvalue=heap.get(v);
    1.82 +	  distance.set(v, oldvalue);
    1.83 +	  heap.pop();
    1.84 +	  
    1.85 +	  OutEdgeIt e;
    1.86 +	  for( G.getFirst(e,v); G.valid(e); G.next(e)) {
    1.87 +	    NodeIt w=G.head(e); 
    1.88 +	    
    1.89 +	    if ( !scanned.get(w) ) {
    1.90 +	      if ( !reached.get(w) ) {
    1.91 +		reached.set(w,true);
    1.92 +		heap.push(w,oldvalue+length.get(e)); 
    1.93 +		predecessor.set(w,e);
    1.94 +
    1.95 +	      } else if ( oldvalue+length.get(e) < heap.get(w) ) {
    1.96 +		predecessor.set(w,e);
    1.97 +		heap.decrease(w, oldvalue+length.get(e)); 
    1.98 +	      }
    1.99 +	    }
   1.100 +	  }
   1.101 +	  scanned.set(v,true);
   1.102 +	}
   1.103 +      } 
   1.104 +      
   1.105 +
   1.106 +      T dist(NodeIt v) {
   1.107 +	return distance.get(v);
   1.108 +      }
   1.109 +
   1.110 +
   1.111 +      EdgeIt pred(NodeIt v) {
   1.112 +	if ( v!=s ) return predecessor.get(v);
   1.113 +	else return EdgeIt();
   1.114 +      }
   1.115 +     
   1.116 +
   1.117 +      bool reach(NodeIt v) {
   1.118 +	return reached.get(v);
   1.119 +      }
   1.120 +
   1.121 +    };
   1.122 +
   1.123 +}
   1.124 +
   1.125 +#endif
   1.126 +
   1.127 +