src/work/alpar/dijkstra/dijkstra.h
author alpar
Sun, 21 Mar 2004 14:58:48 +0000
changeset 223 02948c4c68e1
child 224 5bc1c83257f8
permissions -rw-r--r--
Dijkstra, bin_heap, fib_heap added to the doc.
alpar@222
     1
// -*- C++ -*-
alpar@222
     2
/* 
alpar@222
     3
 *template <Graph, T, Heap=FibHeap, LengthMap=Graph::EdgeMap<T> >
alpar@222
     4
 *
alpar@222
     5
 *Constructor: 
alpar@222
     6
 *
alpar@222
     7
 *Dijkstra(Graph G, LengthMap length)
alpar@222
     8
 *
alpar@222
     9
 *
alpar@222
    10
 *Methods:
alpar@222
    11
 *
alpar@222
    12
 *void run(Node s)
alpar@222
    13
 *
alpar@222
    14
 *T dist(Node v) : After run(s) was run, it returns the distance from s to v. 
alpar@222
    15
 *   Returns T() if v is not reachable from s.
alpar@222
    16
 *
alpar@222
    17
 *Edge pred(Node v) : After run(s) was run, it returns the last 
alpar@222
    18
 *   edge of a shortest s-v path. It is INVALID for s and for 
alpar@222
    19
 *   the nodes not reachable from s.
alpar@222
    20
 *
alpar@222
    21
 *bool reached(Node v) : After run(s) was run, it is true iff v is 
alpar@222
    22
 *   reachable from s
alpar@222
    23
 *
alpar@222
    24
 */
alpar@222
    25
alpar@222
    26
#ifndef HUGO_DIJKSTRA_H
alpar@222
    27
#define HUGO_DIJKSTRA_H
alpar@222
    28
alpar@222
    29
#include <fib_heap.h>
alpar@222
    30
#include <invalid.h>
alpar@222
    31
alpar@222
    32
namespace hugo {
alpar@222
    33
  
alpar@222
    34
  //Alpar: Changed the order of the parameters
alpar@222
    35
  template <typename Graph,
alpar@222
    36
	    typename LengthMap=typename Graph::EdgeMap<int>,
alpar@222
    37
	    typename Heap=FibHeap<typename Graph::Node,
alpar@222
    38
				  typename LengthMap::ValueType, 
alpar@222
    39
				  typename Graph::NodeMap<int> > >
alpar@222
    40
  class Dijkstra{
alpar@222
    41
  public:
alpar@222
    42
    typedef typename LengthMap::ValueType ValueType;
alpar@222
    43
alpar@222
    44
  private:
alpar@222
    45
    typedef typename Graph::Node Node;
alpar@222
    46
    typedef typename Graph::NodeIt NodeIt;
alpar@222
    47
    typedef typename Graph::Edge Edge;
alpar@222
    48
    typedef typename Graph::OutEdgeIt OutEdgeIt;
alpar@222
    49
    
alpar@222
    50
    const Graph& G;
alpar@222
    51
    const LengthMap& length;
alpar@222
    52
    typedef typename Graph::NodeMap<Edge> PredMap;
alpar@222
    53
    PredMap predecessor;
alpar@222
    54
    //In place of reach:
alpar@222
    55
    typedef typename Graph::NodeMap<Node> PredNodeMap;
alpar@222
    56
    PredNodeMap pred_node;
alpar@222
    57
    typedef typename Graph::NodeMap<ValueType> DistMap;
alpar@222
    58
    DistMap distance;
alpar@222
    59
    //I don't like this:
alpar@222
    60
    //     //FIXME:
alpar@222
    61
    //     typename Graph::NodeMap<bool> reach;
alpar@222
    62
    //     //typename Graph::NodeMap<int> reach;
alpar@222
    63
    
alpar@222
    64
  public :
alpar@222
    65
    
alpar@222
    66
    /*
alpar@222
    67
      The distance of the nodes is 0.
alpar@222
    68
    */
alpar@222
    69
    Dijkstra(Graph& _G, LengthMap& _length) :
alpar@222
    70
      G(_G), length(_length), predecessor(_G), pred_node(_G), distance(_G) { }
alpar@222
    71
    
alpar@222
    72
alpar@222
    73
    void run(Node s);
alpar@222
    74
    
alpar@222
    75
    ValueType dist(Node v) const { return distance[v]; }
alpar@222
    76
    Edge pred(Node v) const { return predecessor[v]; }
alpar@222
    77
    Node predNode(Node v) const { return pred_node[v]; }
alpar@222
    78
    
alpar@222
    79
    const DistMap &distMap() const { return distance;}
alpar@222
    80
    const PredMap &predMap() const { return predecessor;}
alpar@222
    81
    const PredNodeMap &predNodeMap() const { return pred_node;}
alpar@222
    82
alpar@222
    83
    //    bool reached(Node v) { return reach[v]; }
alpar@222
    84
    ///\warning \c s is not reached!
alpar@222
    85
    ///
alpar@222
    86
    bool reached(Node v) { return G.valid(predecessor[v]); }
alpar@222
    87
    
alpar@222
    88
  };
alpar@222
    89
  
alpar@222
    90
alpar@222
    91
  // IMPLEMENTATIONS
alpar@222
    92
alpar@222
    93
  template <typename Graph, typename LengthMap, typename Heap >
alpar@222
    94
  void Dijkstra<Graph,LengthMap,Heap>::run(Node s) {
alpar@222
    95
    
alpar@222
    96
    NodeIt u;
alpar@222
    97
    for ( G.first(u) ; G.valid(u) ; G.next(u) ) {
alpar@222
    98
      predecessor.set(u,INVALID);
alpar@222
    99
      // If a node is unreacheable, then why should be the dist=0?
alpar@222
   100
      // distance.set(u,0);
alpar@222
   101
      //      reach.set(u,false);
alpar@222
   102
    }
alpar@222
   103
    
alpar@222
   104
    //We don't need it at all.
alpar@222
   105
    //     //FIXME:
alpar@222
   106
    //     typename Graph::NodeMap<bool> scanned(G,false);
alpar@222
   107
    //     //typename Graph::NodeMap<int> scanned(G,false);
alpar@222
   108
    typename Graph::NodeMap<int> heap_map(G,-1);
alpar@222
   109
    
alpar@222
   110
    Heap heap(heap_map);
alpar@222
   111
    
alpar@222
   112
    heap.push(s,0); 
alpar@222
   113
    //    reach.set(s, true);
alpar@222
   114
    
alpar@222
   115
      while ( !heap.empty() ) {
alpar@222
   116
	
alpar@222
   117
	Node v=heap.top(); 
alpar@222
   118
	ValueType oldvalue=heap[v];
alpar@222
   119
	heap.pop();
alpar@222
   120
	distance.set(v, oldvalue);
alpar@222
   121
	
alpar@222
   122
	for(OutEdgeIt e(G,v); G.valid(e); G.next(e)) {
alpar@222
   123
	  Node w=G.head(e); 
alpar@222
   124
	  
alpar@222
   125
	  switch(heap.state(w)) {
alpar@222
   126
	  case Heap::PRE_HEAP:
alpar@222
   127
	    //	    reach.set(w,true);
alpar@222
   128
	    heap.push(w,oldvalue+length[e]); 
alpar@222
   129
	    predecessor.set(w,e);
alpar@222
   130
	    pred_node.set(w,v);
alpar@222
   131
	    break;
alpar@222
   132
	  case Heap::IN_HEAP:
alpar@222
   133
	    if ( oldvalue+length[e] < heap[w] ) {
alpar@222
   134
	      heap.decrease(w, oldvalue+length[e]); 
alpar@222
   135
	      predecessor.set(w,e);
alpar@222
   136
	      pred_node.set(w,v);
alpar@222
   137
	    }
alpar@222
   138
	    break;
alpar@222
   139
	  case Heap::POST_HEAP:
alpar@222
   140
	    break;
alpar@222
   141
	  }
alpar@222
   142
	}
alpar@222
   143
      }
alpar@222
   144
  }
alpar@222
   145
  
alpar@222
   146
} //END OF NAMESPACE HUGO
alpar@222
   147
alpar@222
   148
#endif
alpar@222
   149
alpar@222
   150