marci@280: #ifndef MARCI_BFS_HH marci@280: #define MARCI_BFS_HH marci@280: marci@280: #include marci@280: marci@280: #include marci@280: marci@280: namespace hugo { marci@280: marci@280: template marci@280: struct bfs { marci@280: typedef typename graph_type::node_iterator node_iterator; marci@280: typedef typename graph_type::edge_iterator edge_iterator; marci@280: typedef typename graph_type::each_node_iterator each_node_iterator; marci@280: typedef typename graph_type::out_edge_iterator out_edge_iterator; marci@280: graph_type& G; marci@280: node_iterator s; marci@280: node_property_vector reached; marci@280: node_property_vector pred; marci@280: node_property_vector dist; marci@280: std::queue bfs_queue; marci@280: bfs(graph_type& _G, node_iterator _s) : G(_G), s(_s), reached(_G), pred(_G), dist(_G) { marci@280: bfs_queue.push(s); marci@280: for(each_node_iterator i=G.first_node(); i.valid(); ++i) marci@280: reached.put(i, false); marci@280: reached.put(s, true); marci@280: dist.put(s, 0); marci@280: } marci@280: marci@280: void run() { marci@280: while (!bfs_queue.empty()) { marci@280: node_iterator v=bfs_queue.front(); marci@280: out_edge_iterator e=G.first_out_edge(v); marci@280: bfs_queue.pop(); marci@280: for( ; e.valid(); ++e) { marci@280: node_iterator w=G.head(e); marci@280: std::cout << "scan node " << G.id(w) << " from node " << G.id(v) << std::endl; marci@280: if (!reached.get(w)) { marci@280: std::cout << G.id(w) << " is newly reached :-)" << std::endl; marci@280: bfs_queue.push(w); marci@280: dist.put(w, dist.get(v)+1); marci@280: pred.put(w, e); marci@280: reached.put(w, true); marci@280: } else { marci@280: std::cout << G.id(w) << " is already reached" << std::endl; marci@280: } marci@280: } marci@280: } marci@280: } marci@280: }; marci@280: marci@280: template marci@280: struct bfs_visitor { marci@280: typedef typename graph_type::node_iterator node_iterator; marci@280: typedef typename graph_type::edge_iterator edge_iterator; marci@280: typedef typename graph_type::out_edge_iterator out_edge_iterator; marci@280: graph_type& G; marci@280: bfs_visitor(graph_type& _G) : G(_G) { } marci@280: void at_previously_reached(out_edge_iterator& e) { marci@280: //node_iterator v=G.tail(e); marci@280: node_iterator w=G.head(e); marci@280: std::cout << G.id(w) << " is already reached" << std::endl; marci@280: } marci@280: void at_newly_reached(out_edge_iterator& e) { marci@280: //node_iterator v=G.tail(e); marci@280: node_iterator w=G.head(e); marci@280: std::cout << G.id(w) << " is newly reached :-)" << std::endl; marci@280: } marci@280: }; marci@280: marci@280: template marci@280: struct bfs_iterator { marci@280: typedef typename graph_type::node_iterator node_iterator; marci@280: typedef typename graph_type::edge_iterator edge_iterator; marci@280: typedef typename graph_type::out_edge_iterator out_edge_iterator; marci@280: graph_type& G; marci@280: std::queue& bfs_queue; marci@280: reached_type& reached; marci@280: visitor_type& visitor; marci@280: void process() { marci@280: while ( !bfs_queue.empty() && !bfs_queue.front().valid() ) { bfs_queue.pop(); } marci@280: if (bfs_queue.empty()) return; marci@280: out_edge_iterator e=bfs_queue.front(); marci@280: //node_iterator v=G.tail(e); marci@280: node_iterator w=G.head(e); marci@280: if (!reached.get(w)) { marci@280: visitor.at_newly_reached(e); marci@280: bfs_queue.push(G.first_out_edge(w)); marci@280: reached.put(w, true); marci@280: } else { marci@280: visitor.at_previously_reached(e); marci@280: } marci@280: } marci@280: bfs_iterator(graph_type& _G, std::queue& _bfs_queue, reached_type& _reached, visitor_type& _visitor) : G(_G), bfs_queue(_bfs_queue), reached(_reached), visitor(_visitor) { marci@280: //while ( !bfs_queue.empty() && !bfs_queue.front().valid() ) { bfs_queue.pop(); } marci@280: valid(); marci@280: } marci@280: bfs_iterator& operator++() { marci@280: //while ( !bfs_queue.empty() && !bfs_queue.front().valid() ) { bfs_queue.pop(); } marci@280: //if (bfs_queue.empty()) return *this; marci@280: if (!valid()) return *this; marci@280: ++(bfs_queue.front()); marci@280: //while ( !bfs_queue.empty() && !bfs_queue.front().valid() ) { bfs_queue.pop(); } marci@280: valid(); marci@280: return *this; marci@280: } marci@280: //void next() { marci@280: // while ( !bfs_queue.empty() && !bfs_queue.front().valid() ) { bfs_queue.pop(); } marci@280: // if (bfs_queue.empty()) return; marci@280: // ++(bfs_queue.front()); marci@280: // while ( !bfs_queue.empty() && !bfs_queue.front().valid() ) { bfs_queue.pop(); } marci@280: //} marci@280: bool valid() { marci@280: while ( !bfs_queue.empty() && !bfs_queue.front().valid() ) { bfs_queue.pop(); } marci@280: if (bfs_queue.empty()) return false; else return true; marci@280: } marci@280: //bool finished() { marci@280: // while ( !bfs_queue.empty() && !bfs_queue.front().valid() ) { bfs_queue.pop(); } marci@280: // if (bfs_queue.empty()) return true; else return false; marci@280: //} marci@280: operator edge_iterator () { return bfs_queue.front(); } marci@280: marci@280: }; marci@280: marci@280: template marci@280: struct bfs_iterator1 { marci@280: typedef typename graph_type::node_iterator node_iterator; marci@280: typedef typename graph_type::edge_iterator edge_iterator; marci@280: typedef typename graph_type::out_edge_iterator out_edge_iterator; marci@280: graph_type& G; marci@280: std::queue& bfs_queue; marci@280: reached_type& reached; marci@280: bool _newly_reached; marci@280: bfs_iterator1(graph_type& _G, std::queue& _bfs_queue, reached_type& _reached) : G(_G), bfs_queue(_bfs_queue), reached(_reached) { marci@280: valid(); marci@280: if (!bfs_queue.empty() && bfs_queue.front().valid()) { marci@280: out_edge_iterator e=bfs_queue.front(); marci@280: node_iterator w=G.head(e); marci@280: if (!reached.get(w)) { marci@280: bfs_queue.push(G.first_out_edge(w)); marci@280: reached.put(w, true); marci@280: _newly_reached=true; marci@280: } else { marci@280: _newly_reached=false; marci@280: } marci@280: } marci@280: } marci@280: bfs_iterator1& operator++() { marci@280: if (!valid()) return *this; marci@280: ++(bfs_queue.front()); marci@280: valid(); marci@280: if (!bfs_queue.empty() && bfs_queue.front().valid()) { marci@280: out_edge_iterator e=bfs_queue.front(); marci@280: node_iterator w=G.head(e); marci@280: if (!reached.get(w)) { marci@280: bfs_queue.push(G.first_out_edge(w)); marci@280: reached.put(w, true); marci@280: _newly_reached=true; marci@280: } else { marci@280: _newly_reached=false; marci@280: } marci@280: } marci@280: return *this; marci@280: } marci@280: bool valid() { marci@280: while ( !bfs_queue.empty() && !bfs_queue.front().valid() ) { bfs_queue.pop(); } marci@280: if (bfs_queue.empty()) return false; else return true; marci@280: } marci@280: operator edge_iterator () { return bfs_queue.front(); } marci@280: bool newly_reached() { return _newly_reached; } marci@280: marci@280: }; marci@280: marci@280: } // namespace hugo marci@280: marci@280: #endif //MARCI_BFS_HH