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