| marci@280 |      1 | #ifndef MARCI_BFS_HH
 | 
| marci@280 |      2 | #define MARCI_BFS_HH
 | 
| marci@280 |      3 | 
 | 
| marci@280 |      4 | #include <queue>
 | 
| marci@280 |      5 | 
 | 
| marci@280 |      6 | #include <marci_property_vector.hh>
 | 
| marci@280 |      7 | 
 | 
| marci@280 |      8 | namespace hugo {
 | 
| marci@280 |      9 | 
 | 
| marci@280 |     10 |   template <typename graph_type>
 | 
| marci@280 |     11 |   struct bfs {
 | 
| marci@280 |     12 |     typedef typename graph_type::node_iterator node_iterator;
 | 
| marci@280 |     13 |     typedef typename graph_type::edge_iterator edge_iterator;
 | 
| marci@280 |     14 |     typedef typename graph_type::each_node_iterator each_node_iterator;
 | 
| marci@280 |     15 |     typedef typename graph_type::out_edge_iterator out_edge_iterator;
 | 
| marci@280 |     16 |     graph_type& G;
 | 
| marci@280 |     17 |     node_iterator s;
 | 
| marci@280 |     18 |     node_property_vector<graph_type, bool> reached;
 | 
| marci@280 |     19 |     node_property_vector<graph_type, edge_iterator> pred;
 | 
| marci@280 |     20 |     node_property_vector<graph_type, int> dist;
 | 
| marci@280 |     21 |     std::queue<node_iterator> bfs_queue;
 | 
| marci@280 |     22 |     bfs(graph_type& _G, node_iterator _s) : G(_G), s(_s), reached(_G), pred(_G), dist(_G) { 
 | 
| marci@280 |     23 |       bfs_queue.push(s); 
 | 
| marci@280 |     24 |       for(each_node_iterator i=G.first_node(); i.valid(); ++i) 
 | 
| marci@280 |     25 | 	reached.put(i, false);
 | 
| marci@280 |     26 |       reached.put(s, true);
 | 
| marci@280 |     27 |       dist.put(s, 0); 
 | 
| marci@280 |     28 |     }
 | 
| marci@280 |     29 |     
 | 
| marci@280 |     30 |     void run() {
 | 
| marci@280 |     31 |       while (!bfs_queue.empty()) {
 | 
| marci@280 |     32 | 	node_iterator v=bfs_queue.front();
 | 
| marci@280 |     33 | 	out_edge_iterator e=G.first_out_edge(v);
 | 
| marci@280 |     34 | 	bfs_queue.pop();
 | 
| marci@280 |     35 | 	for( ; e.valid(); ++e) {
 | 
| marci@280 |     36 | 	  node_iterator w=G.head(e);
 | 
| marci@280 |     37 | 	  std::cout << "scan node " << G.id(w) << " from node " << G.id(v) << std::endl;
 | 
| marci@280 |     38 | 	  if (!reached.get(w)) {
 | 
| marci@280 |     39 | 	    std::cout << G.id(w) << " is newly reached :-)" << std::endl;
 | 
| marci@280 |     40 | 	    bfs_queue.push(w);
 | 
| marci@280 |     41 | 	    dist.put(w, dist.get(v)+1);
 | 
| marci@280 |     42 | 	    pred.put(w, e);
 | 
| marci@280 |     43 | 	    reached.put(w, true);
 | 
| marci@280 |     44 | 	  } else {
 | 
| marci@280 |     45 | 	    std::cout << G.id(w) << " is already reached" << std::endl;
 | 
| marci@280 |     46 | 	  }
 | 
| marci@280 |     47 | 	}
 | 
| marci@280 |     48 |       }
 | 
| marci@280 |     49 |     }
 | 
| marci@280 |     50 |   };
 | 
| marci@280 |     51 | 
 | 
| marci@280 |     52 |   template <typename graph_type> 
 | 
| marci@280 |     53 |   struct bfs_visitor {
 | 
| marci@280 |     54 |     typedef typename graph_type::node_iterator node_iterator;
 | 
| marci@280 |     55 |     typedef typename graph_type::edge_iterator edge_iterator;
 | 
| marci@280 |     56 |     typedef typename graph_type::out_edge_iterator out_edge_iterator;
 | 
| marci@280 |     57 |     graph_type& G;
 | 
| marci@280 |     58 |     bfs_visitor(graph_type& _G) : G(_G) { }
 | 
| marci@280 |     59 |     void at_previously_reached(out_edge_iterator& e) { 
 | 
| marci@280 |     60 |       //node_iterator v=G.tail(e);
 | 
| marci@280 |     61 |       node_iterator w=G.head(e);
 | 
| marci@280 |     62 |       std::cout << G.id(w) << " is already reached" << std::endl;
 | 
| marci@280 |     63 |    }
 | 
| marci@280 |     64 |     void at_newly_reached(out_edge_iterator& e) { 
 | 
| marci@280 |     65 |       //node_iterator v=G.tail(e);
 | 
| marci@280 |     66 |       node_iterator w=G.head(e);
 | 
| marci@280 |     67 |       std::cout << G.id(w) << " is newly reached :-)" << std::endl;
 | 
| marci@280 |     68 |     }
 | 
| marci@280 |     69 |   };
 | 
| marci@280 |     70 | 
 | 
| marci@280 |     71 |   template <typename graph_type, typename reached_type, typename visitor_type>
 | 
| marci@280 |     72 |   struct bfs_iterator {
 | 
| marci@280 |     73 |     typedef typename graph_type::node_iterator node_iterator;
 | 
| marci@280 |     74 |     typedef typename graph_type::edge_iterator edge_iterator;
 | 
| marci@280 |     75 |     typedef typename graph_type::out_edge_iterator out_edge_iterator;
 | 
| marci@280 |     76 |     graph_type& G;
 | 
| marci@280 |     77 |     std::queue<out_edge_iterator>& bfs_queue;
 | 
| marci@280 |     78 |     reached_type& reached;
 | 
| marci@280 |     79 |     visitor_type& visitor;
 | 
| marci@280 |     80 |     void process() {
 | 
| marci@280 |     81 |       while ( !bfs_queue.empty() && !bfs_queue.front().valid() ) { bfs_queue.pop(); } 
 | 
| marci@280 |     82 |       if (bfs_queue.empty()) return;
 | 
| marci@280 |     83 |       out_edge_iterator e=bfs_queue.front();
 | 
| marci@280 |     84 |       //node_iterator v=G.tail(e);
 | 
| marci@280 |     85 |       node_iterator w=G.head(e);
 | 
| marci@280 |     86 |       if (!reached.get(w)) {
 | 
| marci@280 |     87 | 	visitor.at_newly_reached(e);
 | 
| marci@280 |     88 | 	bfs_queue.push(G.first_out_edge(w));
 | 
| marci@280 |     89 | 	reached.put(w, true);
 | 
| marci@280 |     90 |       } else {
 | 
| marci@280 |     91 | 	visitor.at_previously_reached(e);
 | 
| marci@280 |     92 |       }
 | 
| marci@280 |     93 |     }
 | 
| marci@280 |     94 |     bfs_iterator(graph_type& _G, std::queue<out_edge_iterator>& _bfs_queue, reached_type& _reached, visitor_type& _visitor) : G(_G), bfs_queue(_bfs_queue), reached(_reached), visitor(_visitor) { 
 | 
| marci@280 |     95 |       //while ( !bfs_queue.empty() && !bfs_queue.front().valid() ) { bfs_queue.pop(); } 
 | 
| marci@280 |     96 |       valid();
 | 
| marci@280 |     97 |     }
 | 
| marci@280 |     98 |     bfs_iterator<graph_type, reached_type, visitor_type>& operator++() { 
 | 
| marci@280 |     99 |       //while ( !bfs_queue.empty() && !bfs_queue.front().valid() ) { bfs_queue.pop(); } 
 | 
| marci@280 |    100 |       //if (bfs_queue.empty()) return *this;
 | 
| marci@280 |    101 |       if (!valid()) return *this;
 | 
| marci@280 |    102 |       ++(bfs_queue.front());
 | 
| marci@280 |    103 |       //while ( !bfs_queue.empty() && !bfs_queue.front().valid() ) { bfs_queue.pop(); } 
 | 
| marci@280 |    104 |       valid();
 | 
| marci@280 |    105 |       return *this;
 | 
| marci@280 |    106 |     }
 | 
| marci@280 |    107 |     //void next() { 
 | 
| marci@280 |    108 |     //  while ( !bfs_queue.empty() && !bfs_queue.front().valid() ) { bfs_queue.pop(); } 
 | 
| marci@280 |    109 |     //  if (bfs_queue.empty()) return;
 | 
| marci@280 |    110 |     //  ++(bfs_queue.front());
 | 
| marci@280 |    111 |     //  while ( !bfs_queue.empty() && !bfs_queue.front().valid() ) { bfs_queue.pop(); } 
 | 
| marci@280 |    112 |     //}
 | 
| marci@280 |    113 |     bool valid() { 
 | 
| marci@280 |    114 |       while ( !bfs_queue.empty() && !bfs_queue.front().valid() ) { bfs_queue.pop(); } 
 | 
| marci@280 |    115 |       if (bfs_queue.empty()) return false; else return true;
 | 
| marci@280 |    116 |     }
 | 
| marci@280 |    117 |     //bool finished() { 
 | 
| marci@280 |    118 |     //  while ( !bfs_queue.empty() && !bfs_queue.front().valid() ) { bfs_queue.pop(); } 
 | 
| marci@280 |    119 |     //  if (bfs_queue.empty()) return true; else return false;
 | 
| marci@280 |    120 |     //}
 | 
| marci@280 |    121 |     operator edge_iterator () { return bfs_queue.front(); }
 | 
| marci@280 |    122 | 
 | 
| marci@280 |    123 |   };
 | 
| marci@280 |    124 | 
 | 
| marci@280 |    125 |   template <typename graph_type, typename reached_type>
 | 
| marci@280 |    126 |   struct bfs_iterator1 {
 | 
| marci@280 |    127 |     typedef typename graph_type::node_iterator node_iterator;
 | 
| marci@280 |    128 |     typedef typename graph_type::edge_iterator edge_iterator;
 | 
| marci@280 |    129 |     typedef typename graph_type::out_edge_iterator out_edge_iterator;
 | 
| marci@280 |    130 |     graph_type& G;
 | 
| marci@280 |    131 |     std::queue<out_edge_iterator>& bfs_queue;
 | 
| marci@280 |    132 |     reached_type& reached;
 | 
| marci@280 |    133 |     bool _newly_reached;
 | 
| marci@280 |    134 |     bfs_iterator1(graph_type& _G, std::queue<out_edge_iterator>& _bfs_queue, reached_type& _reached) : G(_G), bfs_queue(_bfs_queue), reached(_reached) { 
 | 
| marci@280 |    135 |       valid();
 | 
| marci@280 |    136 |       if (!bfs_queue.empty() && bfs_queue.front().valid()) { 
 | 
| marci@280 |    137 | 	out_edge_iterator e=bfs_queue.front();
 | 
| marci@280 |    138 | 	node_iterator w=G.head(e);
 | 
| marci@280 |    139 | 	if (!reached.get(w)) {
 | 
| marci@280 |    140 | 	  bfs_queue.push(G.first_out_edge(w));
 | 
| marci@280 |    141 | 	  reached.put(w, true);
 | 
| marci@280 |    142 | 	  _newly_reached=true;
 | 
| marci@280 |    143 | 	} else {
 | 
| marci@280 |    144 | 	  _newly_reached=false;
 | 
| marci@280 |    145 | 	}
 | 
| marci@280 |    146 |       }
 | 
| marci@280 |    147 |     }
 | 
| marci@280 |    148 |     bfs_iterator1<graph_type, reached_type>& operator++() { 
 | 
| marci@280 |    149 |       if (!valid()) return *this;
 | 
| marci@280 |    150 |       ++(bfs_queue.front());
 | 
| marci@280 |    151 |       valid();
 | 
| marci@280 |    152 |       if (!bfs_queue.empty() && bfs_queue.front().valid()) { 
 | 
| marci@280 |    153 | 	out_edge_iterator e=bfs_queue.front();
 | 
| marci@280 |    154 | 	node_iterator w=G.head(e);
 | 
| marci@280 |    155 | 	if (!reached.get(w)) {
 | 
| marci@280 |    156 | 	  bfs_queue.push(G.first_out_edge(w));
 | 
| marci@280 |    157 | 	  reached.put(w, true);
 | 
| marci@280 |    158 | 	  _newly_reached=true;
 | 
| marci@280 |    159 | 	} else {
 | 
| marci@280 |    160 | 	  _newly_reached=false;
 | 
| marci@280 |    161 | 	}
 | 
| marci@280 |    162 |       }
 | 
| marci@280 |    163 |       return *this;
 | 
| marci@280 |    164 |     }
 | 
| marci@280 |    165 |     bool valid() { 
 | 
| marci@280 |    166 |       while ( !bfs_queue.empty() && !bfs_queue.front().valid() ) { bfs_queue.pop(); } 
 | 
| marci@280 |    167 |       if (bfs_queue.empty()) return false; else return true;
 | 
| marci@280 |    168 |     }
 | 
| marci@280 |    169 |     operator edge_iterator () { return bfs_queue.front(); }
 | 
| marci@280 |    170 |     bool newly_reached() { return _newly_reached; }
 | 
| marci@280 |    171 | 
 | 
| marci@280 |    172 |   };
 | 
| marci@280 |    173 | 
 | 
| marci@280 |    174 | } // namespace hugo
 | 
| marci@280 |    175 | 
 | 
| marci@280 |    176 | #endif //MARCI_BFS_HH
 |