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