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