src/work/jacint/prim.h
author marci
Fri, 12 Mar 2004 09:19:54 +0000
changeset 174 44700ed9ffaa
child 211 9222a9b8b323
permissions -rw-r--r--
towards on ListGraph, SmartGraph compatibility
jacint@173
     1
// -*- C++ -*-
jacint@173
     2
jacint@173
     3
//kell hogy tree_edge invalid elekbol alljon, Szep 
jacint@173
     4
//lenne ha az elejen a konstrualas ilyet adna, de
jacint@173
     5
//ugy fest nem igy lesz, ekkor invalidalni kell
jacint@173
     6
jacint@173
     7
/* 
jacint@173
     8
 *template <Graph, T, Heap=FibHeap>
jacint@173
     9
 *
jacint@173
    10
 *Constructor: 
jacint@173
    11
 *
jacint@173
    12
 *Prim(Graph G, Graph::EdgeMap<T> weight, NodeIt root=[G.first()])
jacint@173
    13
 *
jacint@173
    14
 *
jacint@173
    15
 *Methods:
jacint@173
    16
 *
jacint@173
    17
 *void run()
jacint@173
    18
 *
jacint@173
    19
 *  The followings functions should be used after run() was already run.
jacint@173
    20
 *
jacint@173
    21
 *T weight() : returns the minimum weight of a spanning tree of the
jacint@173
    22
 *   component of the root. 
jacint@173
    23
 *
jacint@173
    24
 *EdgeIt tree(NodeIt v) : returns the first edge in the path from v
jacint@173
    25
 *   to the root. Returns an invalid iterator if v=s or v is 
jacint@173
    26
 *   not reachable from the root.
jacint@173
    27
 *
jacint@173
    28
 *bool conn() : true iff G is connected
jacint@173
    29
 *
jacint@173
    30
 *bool reach(NodeIt v) : true iff v is in the same component as the root
jacint@173
    31
 *
jacint@173
    32
 *NodeIt root() : returns the root
jacint@173
    33
 *
jacint@173
    34
 */
jacint@173
    35
jacint@173
    36
#ifndef PRIM_H
jacint@173
    37
#define PRIM_H
jacint@173
    38
jacint@173
    39
#include <fib_heap.h>
jacint@173
    40
jacint@173
    41
#include <iostream>
jacint@173
    42
jacint@173
    43
namespace hugo {
jacint@173
    44
jacint@173
    45
  template <typename Graph, typename T, 
jacint@173
    46
    typename Heap=FibHeap<typename Graph::NodeIt, T, 
jacint@173
    47
    typename Graph::NodeMap<int> > >
jacint@173
    48
    class Prim{
jacint@173
    49
      typedef typename Graph::NodeIt NodeIt;
jacint@173
    50
      typedef typename Graph::EachNodeIt EachNodeIt;
jacint@173
    51
      typedef typename Graph::EdgeIt EdgeIt;
jacint@173
    52
      typedef typename Graph::OutEdgeIt OutEdgeIt;
jacint@173
    53
      typedef typename Graph::InEdgeIt InEdgeIt;  
jacint@173
    54
jacint@173
    55
      Graph& G;
jacint@173
    56
      NodeIt r;
jacint@173
    57
      typename Graph::NodeMap<EdgeIt> tree_edge;
jacint@173
    58
      typename Graph::NodeMap<T> min_weight;
jacint@173
    59
      typename Graph::EdgeMap<T>& edge_weight;
jacint@173
    60
      typename Graph::NodeMap<bool> reached;
jacint@173
    61
          
jacint@173
    62
  public :
jacint@173
    63
jacint@173
    64
      Prim(Graph& _G, typename Graph::EdgeMap<T>& _edge_weight, 
jacint@173
    65
	   NodeIt const _r) : 
jacint@173
    66
      G(_G), r(_r), tree_edge(G), min_weight(G), 
jacint@173
    67
      edge_weight(_edge_weight), reached(G, false) { }
jacint@173
    68
jacint@173
    69
      Prim(Graph& _G, typename Graph::EdgeMap<T>& _edge_weight) : 
jacint@173
    70
      G(_G), tree_edge(G), min_weight(G), edge_weight(_edge_weight), reached(G, false)
jacint@173
    71
      { 
jacint@173
    72
	EachNodeIt _r;	   //FIXME
jacint@173
    73
	G.getFirst(_r);
jacint@173
    74
	r=_r;
jacint@173
    75
      }
jacint@173
    76
jacint@173
    77
jacint@173
    78
      void run() {
jacint@173
    79
jacint@173
    80
	typename Graph::NodeMap<bool> scanned(G, false);
jacint@173
    81
	typename Graph::NodeMap<int> heap_map(G,-1);
jacint@173
    82
	
jacint@173
    83
	Heap heap(heap_map);
jacint@173
    84
jacint@173
    85
	heap.push(r,0); 
jacint@173
    86
	reached.set(r, true);
jacint@173
    87
jacint@173
    88
	while ( !heap.empty() ) {
jacint@173
    89
jacint@173
    90
	  NodeIt v=heap.top(); 
jacint@173
    91
	  min_weight.set(v, heap.get(v));
jacint@173
    92
	  heap.pop();
jacint@173
    93
	  scanned.set(v,true);
jacint@173
    94
jacint@173
    95
	  OutEdgeIt e;
jacint@173
    96
	  for( G.getFirst(e,v); G.valid(e); G.next(e)) {
jacint@173
    97
	    NodeIt w=G.head(e); 
jacint@173
    98
	    
jacint@173
    99
	    if ( !scanned.get(w) ) {
jacint@173
   100
	      if ( !reached.get(w) ) {
jacint@173
   101
		reached.set(w,true);
jacint@173
   102
		heap.push(w, edge_weight.get(e)); 
jacint@173
   103
		tree_edge.set(w,e);
jacint@173
   104
	      } else if ( edge_weight.get(e) < heap.get(w) ) {
jacint@173
   105
		tree_edge.set(w,e);
jacint@173
   106
		heap.decrease(w, edge_weight.get(e)); 
jacint@173
   107
	      }
jacint@173
   108
	    }
jacint@173
   109
	  }
jacint@173
   110
jacint@173
   111
	  InEdgeIt f;
jacint@173
   112
	  for( G.getFirst(f,v); G.valid(f); G.next(f)) {
jacint@173
   113
	    NodeIt w=G.tail(f); 
jacint@173
   114
	    
jacint@173
   115
	    if ( !scanned.get(w) ) {
jacint@173
   116
	      if ( !reached.get(w) ) {
jacint@173
   117
		reached.set(w,true);
jacint@173
   118
		heap.push(w, edge_weight.get(f)); 
jacint@173
   119
		tree_edge.set(w,f);
jacint@173
   120
	      } else if ( edge_weight.get(f) < heap.get(w) ) {
jacint@173
   121
		tree_edge.set(w,f);
jacint@173
   122
		heap.decrease(w, edge_weight.get(f)); 
jacint@173
   123
	      }
jacint@173
   124
	    }
jacint@173
   125
	  }
jacint@173
   126
	}
jacint@173
   127
      } 
jacint@173
   128
 
jacint@173
   129
jacint@173
   130
      T weight() {
jacint@173
   131
	T w=0;
jacint@173
   132
	EachNodeIt u;
jacint@173
   133
	for ( G.getFirst(u) ; G.valid(u) ; G.next(u) ) w+=min_weight.get(u);
jacint@173
   134
	return w;
jacint@173
   135
      }
jacint@173
   136
     
jacint@173
   137
jacint@173
   138
      EdgeIt tree(NodeIt v) {
jacint@173
   139
	return tree_edge.get(v);
jacint@173
   140
      } 
jacint@173
   141
jacint@173
   142
jacint@173
   143
      bool conn() {
jacint@173
   144
	bool c=true;
jacint@173
   145
	EachNodeIt u;
jacint@173
   146
	for ( G.getFirst(u) ; G.valid(u) ; G.next(u) ) 
jacint@173
   147
	  if ( !reached.get(u) ) { 
jacint@173
   148
	    c=false;
jacint@173
   149
	    break;
jacint@173
   150
	  }
jacint@173
   151
	return c;
jacint@173
   152
      }
jacint@173
   153
jacint@173
   154
jacint@173
   155
      bool reach(NodeIt v) {
jacint@173
   156
	return reached.get(v);
jacint@173
   157
      }
jacint@173
   158
jacint@173
   159
jacint@173
   160
      NodeIt root() {
jacint@173
   161
	return r;
jacint@173
   162
      }
jacint@173
   163
jacint@173
   164
    };
jacint@173
   165
jacint@173
   166
}
jacint@173
   167
jacint@173
   168
#endif
jacint@173
   169
jacint@173
   170