src/work/jacint/dijkstra.hh
author jacint
Sat, 21 Feb 2004 21:40:59 +0000
changeset 110 3c53698842dd
parent 78 ecc1171307be
permissions -rw-r--r--
leiras
jacint@50
     1
/*
jacint@50
     2
 *dijkstra
jacint@50
     3
 *by jacint
jacint@78
     4
 *Performs Dijkstra's algorithm from Node s. 
jacint@50
     5
 *
jacint@50
     6
 *Constructor: 
jacint@50
     7
 *
jacint@78
     8
 *dijkstra(graph_type& G, NodeIt s, EdgeMap& distance)
jacint@50
     9
 *
jacint@50
    10
 *
jacint@50
    11
 *
jacint@50
    12
 *Member functions:
jacint@50
    13
 *
jacint@50
    14
 *void run()
jacint@50
    15
 *
jacint@50
    16
 *  The following function should be used after run() was already run.
jacint@50
    17
 *
jacint@50
    18
 *
jacint@78
    19
 *T dist(NodeIt v) : returns the distance from s to v. 
jacint@50
    20
 *   It is 0 if v is not reachable from s.
jacint@50
    21
 *
jacint@50
    22
 *
jacint@78
    23
 *EdgeIt pred(NodeIt v)
jacint@78
    24
 *   Returns the last Edge of a shortest s-v path. 
jacint@50
    25
 *   Returns an invalid iterator if v=s or v is not
jacint@50
    26
 *   reachable from s.
jacint@50
    27
 *
jacint@50
    28
 *
jacint@78
    29
 *bool reach(NodeIt v) : true if v is reachable from s
jacint@50
    30
 *
jacint@50
    31
 *
jacint@50
    32
 *
jacint@50
    33
 *
jacint@50
    34
 *
jacint@50
    35
 *Problems: 
jacint@50
    36
 * 
jacint@50
    37
 *Heap implementation is needed, because the priority queue of stl
jacint@50
    38
 *does not have a mathod for key-decrease, so we had to use here a 
jacint@50
    39
 *g\'any solution.
jacint@50
    40
 * 
jacint@50
    41
 *The implementation of infinity would be desirable, see after line 100. 
jacint@50
    42
 */
jacint@50
    43
jacint@50
    44
#ifndef DIJKSTRA_HH
jacint@50
    45
#define DIJKSTRA_HH
jacint@50
    46
jacint@50
    47
#include <queue>
jacint@50
    48
#include <algorithm>
jacint@50
    49
jacint@50
    50
#include <marci_graph_traits.hh>
jacint@78
    51
#include <marciMap.hh>
jacint@50
    52
jacint@50
    53
jacint@50
    54
namespace std {
alpar@105
    55
  namespace hugo {
jacint@50
    56
jacint@50
    57
jacint@50
    58
jacint@50
    59
jacint@50
    60
jacint@50
    61
    template <typename graph_type, typename T>
jacint@50
    62
    class dijkstra{
jacint@78
    63
      typedef typename graph_traits<graph_type>::NodeIt NodeIt;
jacint@78
    64
      typedef typename graph_traits<graph_type>::EdgeIt EdgeIt;
jacint@78
    65
      typedef typename graph_traits<graph_type>::EachNodeIt EachNodeIt;
jacint@78
    66
      typedef typename graph_traits<graph_type>::InEdgeIt InEdgeIt;
jacint@78
    67
      typedef typename graph_traits<graph_type>::OutEdgeIt OutEdgeIt;
jacint@50
    68
      
jacint@50
    69
      
jacint@50
    70
      graph_type& G;
jacint@78
    71
      NodeIt s;
jacint@78
    72
      NodeMap<graph_type, EdgeIt> predecessor;
jacint@78
    73
      NodeMap<graph_type, T> distance;
jacint@78
    74
      EdgeMap<graph_type, T> length;
jacint@78
    75
      NodeMap<graph_type, bool> reached;
jacint@50
    76
          
jacint@50
    77
  public :
jacint@50
    78
jacint@50
    79
    /*
jacint@78
    80
      The distance of all the Nodes is 0.
jacint@50
    81
    */
jacint@78
    82
    dijkstra(graph_type& _G, NodeIt _s, EdgeMap<graph_type, T>& _length) : 
jacint@50
    83
      G(_G), s(_s), predecessor(G, 0), distance(G, 0), length(_length), reached(G, false) { }
jacint@50
    84
    
jacint@50
    85
jacint@50
    86
      
jacint@50
    87
      /*By Misi.*/
jacint@78
    88
      struct Node_dist_comp
jacint@50
    89
      {
jacint@78
    90
	NodeMap<graph_type, T> &d;
jacint@78
    91
	Node_dist_comp(NodeMap<graph_type, T> &_d) : d(_d) {} 
jacint@50
    92
	
jacint@78
    93
	bool operator()(const NodeIt& u, const NodeIt& v) const 
jacint@50
    94
	{ return d.get(u) < d.get(v); }
jacint@50
    95
      };
jacint@50
    96
jacint@50
    97
jacint@50
    98
      
jacint@50
    99
      void run() {
jacint@50
   100
	
jacint@78
   101
	NodeMap<graph_type, bool> scanned(G, false);
jacint@78
   102
	std::priority_queue<NodeIt, vector<NodeIt>, Node_dist_comp> 
jacint@78
   103
	  heap(( Node_dist_comp(distance) ));
jacint@50
   104
      
jacint@50
   105
	heap.push(s);
jacint@50
   106
	reached.put(s, true);
jacint@50
   107
jacint@50
   108
	while (!heap.empty()) {
jacint@50
   109
jacint@78
   110
	  NodeIt v=heap.top();	
jacint@50
   111
	  heap.pop();
jacint@50
   112
jacint@50
   113
jacint@50
   114
	  if (!scanned.get(v)) {
jacint@50
   115
	
jacint@78
   116
	    for(OutEdgeIt e=G.template first<OutEdgeIt>(v); e.valid(); ++e) {
jacint@78
   117
	      NodeIt w=G.head(e);
jacint@50
   118
jacint@50
   119
	      if (!scanned.get(w)) {
jacint@50
   120
		if (!reached.get(w)) {
jacint@50
   121
		  reached.put(w,true);
jacint@50
   122
		  distance.put(w, distance.get(v)-length.get(e));
jacint@50
   123
		  predecessor.put(w,e);
jacint@50
   124
		} else if (distance.get(v)-length.get(e)>distance.get(w)) {
jacint@50
   125
		  distance.put(w, distance.get(v)-length.get(e));
jacint@50
   126
		  predecessor.put(w,e);
jacint@50
   127
		}
jacint@50
   128
		
jacint@50
   129
		heap.push(w);
jacint@50
   130
	      
jacint@50
   131
	      } 
jacint@50
   132
jacint@50
   133
	    } 
jacint@50
   134
	    scanned.put(v,true);
jacint@50
   135
	    
jacint@50
   136
	  } // if (!scanned.get(v))
jacint@50
   137
	  
jacint@50
   138
	  
jacint@50
   139
	  
jacint@50
   140
	} // while (!heap.empty())
jacint@50
   141
jacint@50
   142
	
jacint@50
   143
      } //void run()
jacint@50
   144
      
jacint@50
   145
      
jacint@50
   146
      
jacint@50
   147
jacint@50
   148
jacint@50
   149
      /*
jacint@78
   150
       *Returns the distance of the Node v.
jacint@78
   151
       *It is 0 for the root and for the Nodes not
jacint@50
   152
       *reachable form the root.
jacint@50
   153
       */      
jacint@78
   154
      T dist(NodeIt v) {
jacint@50
   155
	return -distance.get(v);
jacint@50
   156
      }
jacint@50
   157
jacint@50
   158
jacint@50
   159
jacint@50
   160
      /*
jacint@78
   161
       *  Returns the last Edge of a shortest s-v path. 
jacint@50
   162
       *  Returns an invalid iterator if v=root or v is not
jacint@50
   163
       *  reachable from the root.
jacint@50
   164
       */      
jacint@78
   165
      EdgeIt pred(NodeIt v) {
jacint@50
   166
	if (v!=s) { return predecessor.get(v);}
jacint@78
   167
	else {return EdgeIt();}
jacint@50
   168
      }
jacint@50
   169
     
jacint@50
   170
jacint@50
   171
      
jacint@78
   172
      bool reach(NodeIt v) {
jacint@50
   173
	return reached.get(v);
jacint@50
   174
      }
jacint@50
   175
jacint@50
   176
jacint@50
   177
jacint@50
   178
jacint@50
   179
jacint@50
   180
jacint@50
   181
jacint@50
   182
jacint@50
   183
jacint@50
   184
    };// class dijkstra
jacint@50
   185
jacint@50
   186
jacint@50
   187
alpar@105
   188
  } // namespace hugo
jacint@50
   189
}
jacint@50
   190
#endif //DIJKSTRA_HH
jacint@50
   191
jacint@50
   192