src/work/jacint/dijkstra.h
author jacint
Thu, 11 Mar 2004 12:55:50 +0000
changeset 167 7949a29a334e
parent 160 f1a7005e9dff
child 170 9091b1ebca27
permissions -rw-r--r--
*** empty log message ***
jacint@159
     1
// -*- C++ -*-
jacint@159
     2
/* 
jacint@159
     3
 *template <Graph, T, Heap=FibHeap>
jacint@159
     4
 *
jacint@159
     5
 *Constructor: 
jacint@159
     6
 *
jacint@159
     7
 *Dijkstra(Graph G, NodeIt s, Graph::EdgeMap<T> length)
jacint@159
     8
 *
jacint@159
     9
 *
jacint@159
    10
 *Member functions:
jacint@159
    11
 *
jacint@159
    12
 *void run()
jacint@159
    13
 *
jacint@159
    14
 *  The following function should be used after run() was already run.
jacint@159
    15
 *
jacint@159
    16
 *T dist(NodeIt v) : returns the distance from s to v. 
jacint@159
    17
 *   It is 0 if v is not reachable from s.
jacint@159
    18
 *
jacint@159
    19
 *EdgeIt pred(NodeIt v) : returns the last edge 
jacint@159
    20
 *   of a shortest s-v path. Returns an invalid iterator 
jacint@159
    21
 *   if v=s or v is not reachable from s.
jacint@159
    22
 *
jacint@159
    23
 *bool reach(NodeIt v) : true iff v is reachable from s
jacint@159
    24
 *
jacint@159
    25
 */
jacint@159
    26
jacint@159
    27
#ifndef DIJKSTRA_HH
jacint@159
    28
#define DIJKSTRA_HH
jacint@159
    29
jacint@159
    30
#include <fib_heap.h>
jacint@159
    31
jacint@159
    32
namespace hugo {
jacint@159
    33
jacint@159
    34
  template <typename Graph, typename T, 
jacint@159
    35
    typename Heap=FibHeap<typename Graph::NodeIt, T, 
jacint@159
    36
    typename Graph::NodeMap<int> > >
jacint@159
    37
    class Dijkstra{
jacint@159
    38
      typedef typename Graph::NodeIt NodeIt;
jacint@159
    39
      typedef typename Graph::EdgeIt EdgeIt;
jacint@159
    40
      typedef typename Graph::OutEdgeIt OutEdgeIt;
jacint@159
    41
      
jacint@159
    42
      Graph& G;
jacint@159
    43
      NodeIt s;
jacint@159
    44
      typename Graph::NodeMap<EdgeIt> predecessor;
jacint@159
    45
      typename Graph::NodeMap<T> distance;
jacint@159
    46
      typename Graph::EdgeMap<T>& length;
jacint@159
    47
      typename Graph::NodeMap<bool> reached;
jacint@159
    48
          
jacint@159
    49
  public :
jacint@159
    50
jacint@159
    51
    /*
jacint@159
    52
      The distance of the nodes is 0.
jacint@159
    53
    */
jacint@159
    54
    Dijkstra(Graph& _G, NodeIt const _s, 
jacint@159
    55
	     typename Graph::EdgeMap<T>& _length) : 
jacint@159
    56
      G(_G), s(_s), predecessor(G), distance(G), 
jacint@159
    57
      length(_length), reached(G, false) { }
jacint@159
    58
    
jacint@159
    59
      
jacint@159
    60
      void run() {
jacint@159
    61
	
jacint@159
    62
	typename Graph::NodeMap<bool> scanned(G, false);
jacint@159
    63
	typename Graph::NodeMap<int> heap_map(G,-1);
jacint@159
    64
jacint@159
    65
	Heap heap(heap_map);
jacint@159
    66
jacint@159
    67
	heap.push(s,0); 
jacint@159
    68
	reached.set(s, true);
jacint@159
    69
jacint@159
    70
	while ( !heap.empty() ) {
jacint@159
    71
jacint@159
    72
	  NodeIt v=heap.top(); 
jacint@159
    73
	  T oldvalue=heap.get(v);
jacint@167
    74
	  heap.pop();
jacint@159
    75
	  distance.set(v, oldvalue);
jacint@167
    76
jacint@159
    77
	  OutEdgeIt e;
jacint@159
    78
	  for( G.getFirst(e,v); G.valid(e); G.next(e)) {
jacint@160
    79
	    NodeIt w=G.bNode(e); 
jacint@159
    80
	    
jacint@159
    81
	    if ( !scanned.get(w) ) {
jacint@159
    82
	      if ( !reached.get(w) ) {
jacint@159
    83
		reached.set(w,true);
jacint@159
    84
		heap.push(w,oldvalue+length.get(e)); 
jacint@159
    85
		predecessor.set(w,e);
jacint@159
    86
	      } else if ( oldvalue+length.get(e) < heap.get(w) ) {
jacint@159
    87
		predecessor.set(w,e);
jacint@159
    88
		heap.decrease(w, oldvalue+length.get(e)); 
jacint@159
    89
	      }
jacint@159
    90
	    }
jacint@159
    91
	  }
jacint@159
    92
	  scanned.set(v,true);
jacint@159
    93
	}
jacint@159
    94
      } 
jacint@159
    95
      
jacint@159
    96
jacint@159
    97
      T dist(NodeIt v) {
jacint@159
    98
	return distance.get(v);
jacint@159
    99
      }
jacint@159
   100
jacint@159
   101
jacint@159
   102
      EdgeIt pred(NodeIt v) {
jacint@159
   103
	if ( v!=s ) return predecessor.get(v);
jacint@159
   104
	else return EdgeIt();
jacint@159
   105
      }
jacint@159
   106
     
jacint@159
   107
jacint@159
   108
      bool reach(NodeIt v) {
jacint@159
   109
	return reached.get(v);
jacint@159
   110
      }
jacint@167
   111
      
jacint@159
   112
    };
jacint@167
   113
  
jacint@159
   114
}
jacint@159
   115
jacint@159
   116
#endif
jacint@159
   117
jacint@159
   118