src/work/jacint/dijkstra.h
author klao
Thu, 11 Mar 2004 19:19:52 +0000
changeset 171 ec3d3596e3c9
parent 170 9091b1ebca27
child 211 9222a9b8b323
permissions -rw-r--r--
hurokeles bug
jacint@159
     1
// -*- C++ -*-
jacint@170
     2
jacint@170
     3
//ha predecessor az elejen nem invalid, akkor hagyd csak ugy
jacint@170
     4
//scanned mutatja hogy jo ertek van-e benne vagy szemet
jacint@170
     5
jacint@159
     6
/* 
jacint@159
     7
 *template <Graph, T, Heap=FibHeap>
jacint@159
     8
 *
jacint@159
     9
 *Constructor: 
jacint@159
    10
 *
jacint@159
    11
 *Dijkstra(Graph G, NodeIt s, Graph::EdgeMap<T> length)
jacint@159
    12
 *
jacint@159
    13
 *
jacint@159
    14
 *Member functions:
jacint@159
    15
 *
jacint@159
    16
 *void run()
jacint@159
    17
 *
jacint@159
    18
 *  The following function should be used after run() was already run.
jacint@159
    19
 *
jacint@159
    20
 *T dist(NodeIt v) : returns the distance from s to v. 
jacint@159
    21
 *   It is 0 if v is not reachable from s.
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
 *bool reach(NodeIt v) : true iff v is reachable from s
jacint@159
    28
 *
jacint@159
    29
 */
jacint@159
    30
jacint@170
    31
#ifndef DIJKSTRA_H
jacint@170
    32
#define DIJKSTRA_H
jacint@159
    33
jacint@159
    34
#include <fib_heap.h>
jacint@159
    35
jacint@159
    36
namespace hugo {
jacint@159
    37
jacint@159
    38
  template <typename Graph, typename T, 
jacint@159
    39
    typename Heap=FibHeap<typename Graph::NodeIt, T, 
jacint@159
    40
    typename Graph::NodeMap<int> > >
jacint@159
    41
    class Dijkstra{
jacint@159
    42
      typedef typename Graph::NodeIt NodeIt;
jacint@159
    43
      typedef typename Graph::EdgeIt EdgeIt;
jacint@159
    44
      typedef typename Graph::OutEdgeIt OutEdgeIt;
jacint@159
    45
      
jacint@159
    46
      Graph& G;
jacint@159
    47
      NodeIt s;
jacint@159
    48
      typename Graph::NodeMap<EdgeIt> predecessor;
jacint@159
    49
      typename Graph::NodeMap<T> distance;
jacint@159
    50
      typename Graph::EdgeMap<T>& length;
jacint@159
    51
      typename Graph::NodeMap<bool> reached;
jacint@159
    52
          
jacint@159
    53
  public :
jacint@159
    54
jacint@159
    55
    /*
jacint@159
    56
      The distance of the nodes is 0.
jacint@159
    57
    */
jacint@159
    58
    Dijkstra(Graph& _G, NodeIt const _s, 
jacint@159
    59
	     typename Graph::EdgeMap<T>& _length) : 
jacint@159
    60
      G(_G), s(_s), predecessor(G), distance(G), 
jacint@159
    61
      length(_length), reached(G, false) { }
jacint@159
    62
    
jacint@159
    63
      
jacint@159
    64
      void run() {
jacint@159
    65
	
jacint@159
    66
	typename Graph::NodeMap<bool> scanned(G, false);
jacint@159
    67
	typename Graph::NodeMap<int> heap_map(G,-1);
jacint@159
    68
jacint@159
    69
	Heap heap(heap_map);
jacint@159
    70
jacint@159
    71
	heap.push(s,0); 
jacint@159
    72
	reached.set(s, true);
jacint@159
    73
jacint@159
    74
	while ( !heap.empty() ) {
jacint@159
    75
jacint@159
    76
	  NodeIt v=heap.top(); 
jacint@159
    77
	  T oldvalue=heap.get(v);
jacint@167
    78
	  heap.pop();
jacint@159
    79
	  distance.set(v, oldvalue);
klao@171
    80
	  scanned.set(v,true);
jacint@167
    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
	      } else if ( oldvalue+length.get(e) < heap.get(w) ) {
jacint@159
    92
		predecessor.set(w,e);
jacint@159
    93
		heap.decrease(w, oldvalue+length.get(e)); 
jacint@159
    94
	      }
jacint@159
    95
	    }
jacint@159
    96
	  }
jacint@159
    97
	}
jacint@159
    98
      } 
jacint@159
    99
      
jacint@159
   100
jacint@159
   101
      T dist(NodeIt v) {
jacint@159
   102
	return distance.get(v);
jacint@159
   103
      }
jacint@159
   104
jacint@159
   105
jacint@159
   106
      EdgeIt pred(NodeIt v) {
jacint@159
   107
	if ( v!=s ) return predecessor.get(v);
jacint@159
   108
	else return EdgeIt();
jacint@159
   109
      }
jacint@159
   110
     
jacint@159
   111
jacint@159
   112
      bool reach(NodeIt v) {
jacint@159
   113
	return reached.get(v);
jacint@159
   114
      }
jacint@167
   115
      
jacint@159
   116
    };
jacint@167
   117
  
jacint@159
   118
}
jacint@159
   119
jacint@159
   120
#endif
jacint@159
   121
jacint@159
   122