alpar@2: // -*-mode: c++; -*- alpar@2: #ifndef _BFS_H_ alpar@2: #define _BFS_H_ alpar@2: alpar@2: #include alpar@2: #include alpar@2: alpar@2: namespace NEGRO alpar@2: { alpar@2: using namespace std; alpar@2: alpar@4: // template class bfs_T alpar@4: // { alpar@4: // typedef G Graph; alpar@4: // typedef Graph::OutEdgeIterator EdgeIterator; //Ez kell alpar@4: // typedef Graph::NodeIterator NodeIterator; alpar@2: alpar@4: // class bfs_node_D alpar@4: // { alpar@4: // EdgeIterator Tree; alpar@4: // int Dist; alpar@4: // int Priority; alpar@4: // } alpar@4: // } alpar@2: alpar@2: alpar@4: // // template > alpar@4: // // void bfs(bfs_T::Graph &G,const bfs_T::NodeIterator &start_node,const &maps) alpar@2: alpar@2: alpar@2: alpar@4: // template alpar@4: // class bfs_maps_T alpar@4: // { alpar@4: // typedef visited; //node->bool (RW) alpar@4: // typedef tree; //node->EdgeIterator (W) alpar@4: // typedef dist; //node->int (W) alpar@4: // typedef priority; //node->int (W) alpar@4: // }; alpar@2: alpar@2: alpar@4: // Nem jo! Osszeakad a masik Put-tal alpar@4: // class do_nothing_map {}; alpar@4: // template alpar@4: // void Put(const do_nothing_map &p,const V &v,const T &t) {} alpar@2: alpar@2: struct do_nothing_map { alpar@4: template alpar@4: static void Put(V v,T t) {} alpar@2: }; alpar@2: alpar@2: alpar@2: template alpar@2: class class_element_map { alpar@2: public: alpar@2: typedef T value_type; alpar@3: static void Put(const I &i, const T &t) {(*i).*M=t;} alpar@2: static T Get(const I i) {return (*i).*M;} alpar@2: T &operator[](I i) {return (*i).*M;} alpar@2: }; alpar@2: alpar@2: /* alpar@2: template alpar@3: void Put(class_element_map p,I i, T t) alpar@2: { alpar@2: i->*M=t; alpar@2: }; alpar@2: */ alpar@2: alpar@2: template alpar@3: inline void Put(P &p,const I &i, const T &t) alpar@2: { alpar@3: p.Put(i,t); alpar@2: }; alpar@2: template alpar@2: inline typename P::value_type Get(const P &p,const I &i) alpar@2: { alpar@2: return p.Get(i); alpar@2: }; alpar@2: alpar@2: /* alpar@4: template alpar@4: T Get(edge_element_map p,G::EdgeIterator i) alpar@4: { alpar@2: return i->*M; alpar@4: }; alpar@2: */ alpar@2: alpar@2: /* alpar@4: template alpar@4: class default_bfs_maps alpar@4: { alpar@4: public: alpar@4: typedef typename G::NodeType NodeType; alpar@2: alpar@4: class_element_map visited; //node->bool (RW) alpar@4: do_nothing_map tree; //node->EdgeIterator (W) alpar@4: do_nothing_map dist; //node->int (W) alpar@4: do_nothing_map priority; //node->int (W) alpar@4: }; alpar@2: */ alpar@2: alpar@2: template alpar@2: struct bfs_node_data alpar@2: { alpar@2: bool visited; alpar@2: typename G::EdgeIterator tree; alpar@2: int dist; alpar@2: int priority; alpar@2: }; alpar@2: alpar@2: template alpar@2: class bfs_static_maps alpar@2: { alpar@2: public: alpar@2: typedef typename G::NodeType NodeType; alpar@2: alpar@2: /* class_element_map,&NT::D> n_d; //node-> data alpar@2: */ alpar@2: class alpar@2: { alpar@2: public: alpar@2: bfs_node_data NodeType::*d; alpar@2: typedef bool value_type; alpar@3: void Put(typename G::NodeIterator &i, const value_type &t) alpar@2: {((*i).*d).visited=t;} alpar@2: value_type Get(const typename G::NodeIterator &i) const alpar@2: {return ((*i).*d).visited;} alpar@2: } visited; alpar@2: alpar@2: class alpar@2: { alpar@2: public: alpar@2: bfs_node_data NodeType::*d; alpar@2: typedef typename G::EdgeIterator value_type; alpar@3: void Put(typename G::NodeIterator &i, const value_type &t) alpar@2: {((*i).*d).tree=t;} alpar@2: value_type Get(const typename G::NodeIterator &i) const alpar@2: {return ((*i).*d).tree;} alpar@2: } tree; alpar@2: alpar@2: class alpar@2: { alpar@2: public: alpar@2: bfs_node_data NodeType::*d; alpar@2: typedef int value_type; alpar@3: void Put(typename G::NodeIterator &i, const value_type &t) alpar@2: {((*i).*d).dist=t;} alpar@2: value_type Get(const typename G::NodeIterator &i) const alpar@2: {return ((*i).*d).dist;} alpar@2: } dist; alpar@2: alpar@2: class alpar@2: { alpar@2: public: alpar@2: bfs_node_data NodeType::*d; alpar@2: typedef int value_type; alpar@3: void Put(typename G::NodeIterator &i, const value_type &t) alpar@2: {((*i).*d).priority=t;} alpar@2: value_type Get(const typename G::NodeIterator &i) const alpar@2: {return ((*i).*d).priority;} alpar@2: } priority; alpar@2: alpar@2: //do_nothing_map tree; //node->EdgeIterator (W) alpar@2: // do_nothing_map dist; //node->int (W) alpar@2: // do_nothing_map priority; //node->int (W) alpar@2: alpar@2: void SetDataField(const bfs_node_data NodeType::*dd) alpar@2: { alpar@2: tree.d=visited.d=dist.d=priority.d=dd; alpar@2: } alpar@2: alpar@2: bfs_static_maps(const bfs_node_data NodeType::*dd) alpar@2: { alpar@3: PutDataField(dd); alpar@2: } alpar@2: alpar@2: bfs_static_maps(const bfs_static_maps &B) alpar@2: { alpar@2: tree.d=B.tree.d;visited.d=B.visited.d; alpar@2: dist.d=B.dist.d;priority.d=B.priority.d; alpar@2: } alpar@2: alpar@2: }; alpar@2: alpar@2: template alpar@2: struct BFS_Q alpar@2: { alpar@2: I n; alpar@2: int dist; alpar@2: // BFS_Q() {} alpar@2: // BFS_Q(BFS_Q &b) {n=b.n;dist=b.dist;} alpar@2: }; alpar@2: alpar@2: template alpar@4: void bfs_fn(G &Gr,const typename G::NodeIterator &start_node,M &maps) alpar@2: { alpar@2: using namespace std; alpar@2: alpar@2: typedef BFS_Q Q_T; alpar@2: alpar@2: Q_T q; alpar@2: alpar@2: int pr=0; alpar@2: typename G::NodeIterator n,m; alpar@2: typename G::OutEdgeIterator e; alpar@2: int d; alpar@2: alpar@2: for(Gr.GetFirst(n);n.isValid();++n) alpar@3: Put(maps.visited,n,false); alpar@2: alpar@2: queue Q; alpar@2: alpar@2: q.n=start_node; alpar@2: q.dist=0; alpar@2: Q.push(q); alpar@3: Put(maps.visited,start_node,true); alpar@3: // Put(maps::tree,start_node,?????); alpar@3: Put(maps.dist,start_node,0); alpar@3: Put(maps.priority,start_node,pr++); alpar@2: alpar@2: do { alpar@2: n=Q.front().n;d=Q.front().dist+1; alpar@2: Q.pop(); alpar@2: for(Gr.GetFirst(e,n);e.isValid();++e) alpar@2: if(!Get(maps.visited,(m=e.Bnode()))) { alpar@2: q.n=m; alpar@2: q.dist=d; alpar@2: Q.push(q); alpar@3: Put(maps.visited,m,true); alpar@3: Put(maps.tree,m,e); alpar@3: Put(maps.dist,m,d); alpar@3: Put(maps.priority,m,pr++); alpar@2: } alpar@2: } while(!Q.empty()); alpar@2: }; alpar@4: alpar@4: // bfs algorithm class alpar@4: template alpar@4: class Bfs alpar@4: { alpar@4: public: alpar@4: typedef typename T::Graph_t Graph; alpar@4: typedef typename Graph::NodeIterator NodeIterator; alpar@4: typedef typename Graph::EdgeIterator EdgeIterator; alpar@4: alpar@4: typedef typename T::SearchEdgeIterator SearchEdgeIterator; alpar@4: alpar@4: typename T::visited_map_t visited_map; alpar@4: typename T::tree_map_t tree_map; alpar@4: typename T::dist_map_t dist_map; alpar@4: typename T::priority_map_t priority_map; alpar@4: alpar@4: struct bfs_queue_cont alpar@4: { alpar@4: NodeIterator n; alpar@4: int dist; alpar@4: }; alpar@4: alpar@4: std::queue bfs_queue; alpar@4: alpar@4: int priority; alpar@4: Graph *G; alpar@4: alpar@4: void SetG(Graph &Gr) alpar@4: { alpar@4: G=&Gr; alpar@4: } alpar@4: alpar@4: void Init() alpar@4: { alpar@4: //There must be a better way to do this: alpar@4: while(!bfs_queue.empty()) bfs_queue.pop(); alpar@4: alpar@4: for(NodeIterator n(*G);n.isValid();++n) alpar@4: Put(visited_map,n,false); alpar@4: alpar@4: priority=0; alpar@4: } alpar@4: alpar@4: void AddStartNode(const NodeIterator &start_node,int dist=0) alpar@4: { alpar@4: bfs_queue_cont q; alpar@4: q.n=start_node; alpar@4: q.dist=dist; alpar@4: bfs_queue.push(q); alpar@4: alpar@4: Put(visited_map,start_node,true); alpar@4: // Put(tree_map,start_node,?????); alpar@4: Put(dist_map,start_node,dist); alpar@4: Put(priority_map,start_node,priority++); alpar@4: } alpar@4: alpar@4: void Init(const NodeIterator &start_node,int dist=0) alpar@4: { alpar@4: Init(); alpar@4: AddStartNode(start_node,dist); alpar@4: } alpar@4: alpar@4: void Run() alpar@4: { alpar@4: NodeIterator n,m; alpar@4: int d; alpar@4: alpar@4: bfs_queue_cont q; alpar@4: while(!(bfs_queue.empty()/* && other stop conditions */)) { alpar@4: n=bfs_queue.front().n;d=bfs_queue.front().dist+1; alpar@4: bfs_queue.pop(); alpar@4: for(SearchEdgeIterator e(*G,n);e.isValid();++e) alpar@4: if(!Get(visited_map,(m=e.Bnode()))) { alpar@4: q.n=m; alpar@4: q.dist=d; alpar@4: bfs_queue.push(q); alpar@4: Put(visited_map,m,true); alpar@4: Put(tree_map,m,e); alpar@4: Put(dist_map,m,d); alpar@4: Put(priority_map,m,priority++); alpar@4: } alpar@4: } alpar@4: } alpar@4: }; alpar@4: alpar@2: } alpar@4: alpar@2: #endif