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