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