src/work/alpar/bfs.h
author marci
Fri, 14 May 2004 18:08:29 +0000
changeset 641 bfd6c14e2975
permissions -rw-r--r--
some documentation in stGraphWrapper<Gr> and BipartiteGraphWrapper<Gr>
alpar@302
     1
// -*-mode: c++; -*-
alpar@302
     2
#ifndef _BFS_H_
alpar@302
     3
#define _BFS_H_
alpar@302
     4
alpar@302
     5
#include <queue>
alpar@302
     6
#include <graph.h>
alpar@302
     7
alpar@302
     8
namespace NEGRO 
alpar@302
     9
{
alpar@302
    10
  using namespace std;
alpar@302
    11
  
alpar@302
    12
  //   template <typename G,typename> class bfs_T
alpar@302
    13
  //   {
alpar@302
    14
  //     typedef G Graph;
alpar@302
    15
  //     typedef Graph::OutEdgeIterator EdgeIterator; //Ez kell
alpar@302
    16
  //     typedef Graph::NodeIterator NodeIterator;
alpar@302
    17
    
alpar@302
    18
  //     class bfs_node_D 
alpar@302
    19
  //     {
alpar@302
    20
  //       EdgeIterator Tree;
alpar@302
    21
  //       int Dist;
alpar@302
    22
  //       int Priority;
alpar@302
    23
  //     }
alpar@302
    24
  //   }
alpar@302
    25
    
alpar@302
    26
alpar@302
    27
  //     //    template <bfs_T<G>>
alpar@302
    28
  //     //    void bfs(bfs_T::Graph &G,const bfs_T::NodeIterator &start_node,const &maps)
alpar@302
    29
alpar@302
    30
    
alpar@302
    31
  
alpar@302
    32
  //   template <class G>
alpar@302
    33
  //   class bfs_maps_T
alpar@302
    34
  //   {
alpar@302
    35
  //     typedef visited; //node->bool (RW)
alpar@302
    36
  //     typedef tree;    //node->EdgeIterator (W)
alpar@302
    37
  //     typedef dist;   //node->int (W)
alpar@302
    38
  //     typedef priority; //node->int (W)
alpar@302
    39
  //   };
alpar@302
    40
  
alpar@302
    41
  
alpar@302
    42
  //   Nem jo! Osszeakad a masik Put-tal
alpar@302
    43
  //   class do_nothing_map {};
alpar@302
    44
  //   template <typename V,typename T>
alpar@302
    45
  //   void Put(const do_nothing_map &p,const V &v,const T &t) {}
alpar@302
    46
  
alpar@302
    47
  struct do_nothing_map {
alpar@302
    48
    template <typename V,typename T> static void Put(V v,T t) {}
alpar@302
    49
    template <typename G> void SetG(G &g) {}
alpar@302
    50
  };
alpar@302
    51
  
alpar@302
    52
alpar@302
    53
  template <typename I,typename C, typename T, T C::*M>
alpar@302
    54
  class class_element_map {
alpar@302
    55
  public:
alpar@302
    56
    typedef T value_type;
alpar@302
    57
    static void Put(const I &i, const T &t) {(*i).*M=t;}
alpar@302
    58
    static T Get(const I i) {return (*i).*M;}
alpar@302
    59
    T &operator[](I i) {return (*i).*M;}
alpar@302
    60
  };
alpar@302
    61
alpar@302
    62
  /* 
alpar@302
    63
     template <typename C,typename I,typename T, T C::*M>
alpar@302
    64
     void Put(class_element_map<C,T,M> p,I i, T t)
alpar@302
    65
     {
alpar@302
    66
     i->*M=t;   
alpar@302
    67
     };
alpar@302
    68
  */
alpar@302
    69
alpar@302
    70
  template <typename P,typename I,typename T>
alpar@302
    71
  inline void Put(P &p,const I &i, const T &t)
alpar@302
    72
  {
alpar@302
    73
    p.Put(i,t);   
alpar@302
    74
  };
alpar@302
    75
  template <typename P,typename I>
alpar@302
    76
  inline typename P::value_type Get(const P &p,const I &i)
alpar@302
    77
  {
alpar@302
    78
    return p.Get(i);   
alpar@302
    79
  };
alpar@302
    80
alpar@302
    81
  /*
alpar@302
    82
    template <typename G,typename T, typename G::EdgeType::*M>
alpar@302
    83
    T Get(edge_element_map p,G::EdgeIterator i)
alpar@302
    84
    {
alpar@302
    85
    return i->*M;
alpar@302
    86
    };
alpar@302
    87
  */
alpar@302
    88
  
alpar@302
    89
  /* 
alpar@302
    90
     template <class G>
alpar@302
    91
     class default_bfs_maps
alpar@302
    92
     {
alpar@302
    93
     public:
alpar@302
    94
     typedef typename G::NodeType NodeType;
alpar@302
    95
    
alpar@302
    96
     class_element_map<typename G::NodeIterator,
alpar@302
    97
     typename G::NodeType,
alpar@302
    98
     bool,&NodeType::isVis> visited; //node->bool (RW)
alpar@302
    99
     do_nothing_map tree;   //node->EdgeIterator (W)
alpar@302
   100
     do_nothing_map dist;   //node->int (W)
alpar@302
   101
     do_nothing_map priority; //node->int (W)
alpar@302
   102
     };
alpar@302
   103
  */
alpar@302
   104
alpar@302
   105
  template<class G>
alpar@302
   106
  struct bfs_node_data 
alpar@302
   107
  {
alpar@302
   108
    bool visited;
alpar@302
   109
    typename G::EdgeIterator tree;
alpar@302
   110
    int dist;
alpar@302
   111
    int priority;
alpar@302
   112
  };
alpar@302
   113
  
alpar@302
   114
  template <class G>
alpar@302
   115
  class bfs_static_maps
alpar@302
   116
  {
alpar@302
   117
  public:
alpar@302
   118
    typedef typename G::NodeType NodeType;
alpar@302
   119
    
alpar@302
   120
    /*    class_element_map<typename G::NodeIterator,
alpar@302
   121
	  typename G::NodeType,
alpar@302
   122
	  bfs_node_data<G>,&NT::D> n_d; //node-> data
alpar@302
   123
    */
alpar@302
   124
    class 
alpar@302
   125
    {
alpar@302
   126
    public:
alpar@302
   127
      bfs_node_data<G> NodeType::*d;
alpar@302
   128
      typedef bool value_type;
alpar@302
   129
      void Put(typename G::NodeIterator &i, const value_type &t)
alpar@302
   130
      {((*i).*d).visited=t;}
alpar@302
   131
      value_type Get(const typename G::NodeIterator &i) const
alpar@302
   132
      {return ((*i).*d).visited;}
alpar@302
   133
    } visited;
alpar@302
   134
    
alpar@302
   135
    class 
alpar@302
   136
    {
alpar@302
   137
    public:
alpar@302
   138
      bfs_node_data<G> NodeType::*d;
alpar@302
   139
      typedef typename G::EdgeIterator value_type;
alpar@302
   140
      void Put(typename G::NodeIterator &i, const value_type &t)
alpar@302
   141
      {((*i).*d).tree=t;}
alpar@302
   142
      value_type Get(const typename G::NodeIterator &i) const
alpar@302
   143
      {return ((*i).*d).tree;}
alpar@302
   144
    } tree;
alpar@302
   145
    
alpar@302
   146
    class 
alpar@302
   147
    {
alpar@302
   148
    public:
alpar@302
   149
      bfs_node_data<G> NodeType::*d;
alpar@302
   150
      typedef int value_type;
alpar@302
   151
      void Put(typename G::NodeIterator &i, const value_type &t)
alpar@302
   152
      {((*i).*d).dist=t;}
alpar@302
   153
      value_type Get(const typename G::NodeIterator &i) const
alpar@302
   154
      {return ((*i).*d).dist;}
alpar@302
   155
    } dist;
alpar@302
   156
    
alpar@302
   157
    class 
alpar@302
   158
    {
alpar@302
   159
    public:
alpar@302
   160
      bfs_node_data<G> NodeType::*d;
alpar@302
   161
      typedef int value_type;
alpar@302
   162
      void Put(typename G::NodeIterator &i,  const value_type &t)
alpar@302
   163
      {((*i).*d).priority=t;}
alpar@302
   164
      value_type Get(const typename G::NodeIterator &i) const
alpar@302
   165
      {return ((*i).*d).priority;}
alpar@302
   166
    } priority;
alpar@302
   167
    
alpar@302
   168
    //do_nothing_map tree;   //node->EdgeIterator (W)
alpar@302
   169
    //    do_nothing_map dist;   //node->int (W)
alpar@302
   170
    //    do_nothing_map priority; //node->int (W)
alpar@302
   171
alpar@302
   172
    void SetDataField(const bfs_node_data<G> NodeType::*dd)
alpar@302
   173
    {
alpar@302
   174
      tree.d=visited.d=dist.d=priority.d=dd;
alpar@302
   175
    }
alpar@302
   176
    
alpar@302
   177
    bfs_static_maps(const bfs_node_data<G> NodeType::*dd) 
alpar@302
   178
    {
alpar@302
   179
      PutDataField(dd);
alpar@302
   180
    }
alpar@302
   181
    
alpar@302
   182
    bfs_static_maps(const bfs_static_maps<G> &B) 
alpar@302
   183
    {
alpar@302
   184
      tree.d=B.tree.d;visited.d=B.visited.d;
alpar@302
   185
      dist.d=B.dist.d;priority.d=B.priority.d;
alpar@302
   186
    }
alpar@302
   187
    
alpar@302
   188
  };
alpar@302
   189
  
alpar@302
   190
  template<typename I>
alpar@302
   191
  struct BFS_Q
alpar@302
   192
  {
alpar@302
   193
    I n;
alpar@302
   194
    int dist;
alpar@302
   195
    //  BFS_Q() {}
alpar@302
   196
    //  BFS_Q(BFS_Q<I> &b) {n=b.n;dist=b.dist;}
alpar@302
   197
  };
alpar@302
   198
  
alpar@302
   199
  template<class G,class M>
alpar@302
   200
  void bfs_fn(G &Gr,const typename G::NodeIterator &start_node,M &maps)
alpar@302
   201
  {
alpar@302
   202
    using namespace std;
alpar@302
   203
    
alpar@302
   204
    typedef BFS_Q<typename G::NodeIterator> Q_T;
alpar@302
   205
    
alpar@302
   206
    Q_T q;
alpar@302
   207
    
alpar@302
   208
    int pr=0;
alpar@302
   209
    typename G::NodeIterator n,m;
alpar@302
   210
    typename G::OutEdgeIterator e;
alpar@302
   211
    int d;
alpar@302
   212
    
alpar@302
   213
    for(Gr.GetFirst(n);n.isValid();++n)
alpar@302
   214
      Put(maps.visited,n,false);
alpar@302
   215
    
alpar@302
   216
    queue<Q_T> Q;
alpar@302
   217
    
alpar@302
   218
    q.n=start_node;
alpar@302
   219
    q.dist=0;
alpar@302
   220
    Q.push(q);
alpar@302
   221
    Put(maps.visited,start_node,true);
alpar@302
   222
    //      Put(maps::tree,start_node,?????);
alpar@302
   223
    Put(maps.dist,start_node,0);
alpar@302
   224
    Put(maps.priority,start_node,pr++);
alpar@302
   225
    
alpar@302
   226
    do {
alpar@302
   227
      n=Q.front().n;d=Q.front().dist+1;
alpar@302
   228
      Q.pop();
alpar@302
   229
      for(Gr.GetFirst(e,n);e.isValid();++e)
alpar@302
   230
	if(!Get(maps.visited,(m=e.Bnode()))) {
alpar@302
   231
	  q.n=m;
alpar@302
   232
	  q.dist=d;
alpar@302
   233
	  Q.push(q);
alpar@302
   234
	  Put(maps.visited,m,true);
alpar@302
   235
	  Put(maps.tree,m,e);
alpar@302
   236
	  Put(maps.dist,m,d);
alpar@302
   237
	  Put(maps.priority,m,pr++);
alpar@302
   238
	}
alpar@302
   239
    } while(!Q.empty());
alpar@302
   240
  };
alpar@302
   241
alpar@302
   242
  // bfs algorithm class
alpar@302
   243
alpar@302
   244
  template<class G>  //the default traits
alpar@302
   245
  class default_bfs_T
alpar@302
   246
  {
alpar@302
   247
  public:
alpar@302
   248
    
alpar@302
   249
    typedef G Graph;
alpar@302
   250
    typedef typename G::OutEdgeIterator SearchEdgeIterator;
alpar@302
   251
    
alpar@302
   252
    typedef typename G::NodeMap<bool> visited_map_t;
alpar@302
   253
    typedef typename G::NodeMap<typename G::EdgeIterator> tree_map_t;
alpar@302
   254
    
alpar@302
   255
    typedef typename G::NodeMap<int> dist_map_t;   //node->int (W)
alpar@302
   256
    typedef typename G::NodeMap<int> priority_map_t; //node->int (W)
alpar@302
   257
};
alpar@302
   258
alpar@302
   259
  template<class T>
alpar@302
   260
  class Bfs
alpar@302
   261
  {
alpar@302
   262
  public:
alpar@302
   263
    typedef typename T::Graph Graph;
alpar@302
   264
    typedef typename Graph::NodeIterator NodeIterator;
alpar@302
   265
    typedef typename Graph::EdgeIterator EdgeIterator;
alpar@302
   266
    
alpar@302
   267
    typedef typename T::SearchEdgeIterator SearchEdgeIterator;
alpar@302
   268
    
alpar@302
   269
    typename T::visited_map_t visited_map;
alpar@302
   270
    typename T::tree_map_t tree_map;
alpar@302
   271
    typename T::dist_map_t dist_map;
alpar@302
   272
    typename T::priority_map_t priority_map;
alpar@302
   273
    
alpar@302
   274
    struct bfs_queue_cont
alpar@302
   275
    {
alpar@302
   276
      NodeIterator n;
alpar@302
   277
      int dist;
alpar@302
   278
    };
alpar@302
   279
    
alpar@302
   280
    std::queue<bfs_queue_cont> bfs_queue;
alpar@302
   281
    
alpar@302
   282
    int priority;
alpar@302
   283
    Graph *G;
alpar@302
   284
    
alpar@302
   285
    //Bfs(int i): visited_map(G), tree_map(G), dist_map(G), priority_map(G) {}
alpar@302
   286
    Bfs() {}
alpar@302
   287
alpar@302
   288
    void SetG(Graph &Gr)
alpar@302
   289
    {
alpar@302
   290
      G=&Gr;
alpar@302
   291
      visited_map.SetG(Gr);
alpar@302
   292
      tree_map.SetG(Gr);
alpar@302
   293
      dist_map.SetG(Gr);
alpar@302
   294
      priority_map.SetG(Gr);
alpar@302
   295
    }
alpar@302
   296
    
alpar@302
   297
    void Init()
alpar@302
   298
    {
alpar@302
   299
      //There must be a better way to do this:
alpar@302
   300
      while(!bfs_queue.empty()) bfs_queue.pop();
alpar@302
   301
alpar@302
   302
      for(NodeIterator n(*G);n.isValid();++n)
alpar@302
   303
	Put(visited_map,n,false);
alpar@302
   304
      
alpar@302
   305
      priority=0;
alpar@302
   306
    }
alpar@302
   307
    
alpar@302
   308
    void AddStartNode(const NodeIterator &start_node,int dist=0)
alpar@302
   309
    {
alpar@302
   310
      bfs_queue_cont q;
alpar@302
   311
      q.n=start_node;
alpar@302
   312
      q.dist=dist;
alpar@302
   313
      bfs_queue.push(q);
alpar@302
   314
alpar@302
   315
      Put(visited_map,start_node,true);
alpar@302
   316
      //      Put(tree_map,start_node,?????);
alpar@302
   317
      Put(dist_map,start_node,dist);
alpar@302
   318
      Put(priority_map,start_node,priority++);    
alpar@302
   319
    }
alpar@302
   320
    
alpar@302
   321
    void Init(const NodeIterator &start_node,int dist=0)
alpar@302
   322
    {
alpar@302
   323
      Init();
alpar@302
   324
      AddStartNode(start_node,dist);
alpar@302
   325
    }
alpar@302
   326
alpar@302
   327
    void Run() 
alpar@302
   328
    {
alpar@302
   329
      NodeIterator n,m;
alpar@302
   330
      int d;
alpar@302
   331
alpar@302
   332
      bfs_queue_cont q;
alpar@302
   333
      while(!(bfs_queue.empty()/* && other stop conditions */)) {
alpar@302
   334
	n=bfs_queue.front().n;d=bfs_queue.front().dist+1;
alpar@302
   335
	bfs_queue.pop();
alpar@302
   336
	for(SearchEdgeIterator e(*G,n);e.isValid();++e)
alpar@302
   337
	  if(!Get(visited_map,(m=e.Bnode()))) {
alpar@302
   338
	    q.n=m;
alpar@302
   339
	    q.dist=d;
alpar@302
   340
	    bfs_queue.push(q);
alpar@302
   341
	    Put(visited_map,m,true);
alpar@302
   342
	    Put(tree_map,m,e);
alpar@302
   343
	    Put(dist_map,m,d);
alpar@302
   344
	    Put(priority_map,m,priority++);
alpar@302
   345
	  }
alpar@302
   346
      }
alpar@302
   347
    }
alpar@302
   348
  };
alpar@302
   349
  
alpar@302
   350
}
alpar@302
   351
  
alpar@302
   352
#endif