annotate DEPENDENCIES/generic/include/boost/graph/neighbor_bfs.hpp @ 125:34e428693f5d vext

Vext -> Repoint
author Chris Cannam
date Thu, 14 Jun 2018 11:15:39 +0100
parents 2665513ce2d3
children
rev   line source
Chris@16 1 //
Chris@16 2 //=======================================================================
Chris@16 3 // Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
Chris@16 4 // Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
Chris@16 5 //
Chris@16 6 // Distributed under the Boost Software License, Version 1.0. (See
Chris@16 7 // accompanying file LICENSE_1_0.txt or copy at
Chris@16 8 // http://www.boost.org/LICENSE_1_0.txt)
Chris@16 9 //=======================================================================
Chris@16 10 //
Chris@16 11 #ifndef BOOST_GRAPH_NEIGHBOR_BREADTH_FIRST_SEARCH_HPP
Chris@16 12 #define BOOST_GRAPH_NEIGHBOR_BREADTH_FIRST_SEARCH_HPP
Chris@16 13
Chris@16 14 /*
Chris@16 15 Neighbor Breadth First Search
Chris@16 16 Like BFS, but traverses in-edges as well as out-edges.
Chris@16 17 (for directed graphs only. use normal BFS for undirected graphs)
Chris@16 18 */
Chris@16 19 #include <boost/config.hpp>
Chris@16 20 #include <boost/ref.hpp>
Chris@16 21 #include <vector>
Chris@16 22 #include <boost/pending/queue.hpp>
Chris@16 23 #include <boost/graph/graph_traits.hpp>
Chris@16 24 #include <boost/graph/graph_concepts.hpp>
Chris@16 25 #include <boost/graph/visitors.hpp>
Chris@16 26 #include <boost/graph/named_function_params.hpp>
Chris@16 27 #include <boost/concept/assert.hpp>
Chris@16 28
Chris@16 29 namespace boost {
Chris@16 30
Chris@16 31 template <class Visitor, class Graph>
Chris@16 32 struct NeighborBFSVisitorConcept {
Chris@16 33 void constraints() {
Chris@16 34 BOOST_CONCEPT_ASSERT(( CopyConstructibleConcept<Visitor> ));
Chris@16 35 vis.initialize_vertex(u, g);
Chris@16 36 vis.discover_vertex(u, g);
Chris@16 37 vis.examine_vertex(u, g);
Chris@16 38 vis.examine_out_edge(e, g);
Chris@16 39 vis.examine_in_edge(e, g);
Chris@16 40 vis.tree_out_edge(e, g);
Chris@16 41 vis.tree_in_edge(e, g);
Chris@16 42 vis.non_tree_out_edge(e, g);
Chris@16 43 vis.non_tree_in_edge(e, g);
Chris@16 44 vis.gray_target(e, g);
Chris@16 45 vis.black_target(e, g);
Chris@16 46 vis.gray_source(e, g);
Chris@16 47 vis.black_source(e, g);
Chris@16 48 vis.finish_vertex(u, g);
Chris@16 49 }
Chris@16 50 Visitor vis;
Chris@16 51 Graph g;
Chris@16 52 typename graph_traits<Graph>::vertex_descriptor u;
Chris@16 53 typename graph_traits<Graph>::edge_descriptor e;
Chris@16 54 };
Chris@16 55
Chris@16 56 template <class Visitors = null_visitor>
Chris@16 57 class neighbor_bfs_visitor {
Chris@16 58 public:
Chris@16 59 neighbor_bfs_visitor(Visitors vis = Visitors()) : m_vis(vis) { }
Chris@16 60
Chris@16 61 template <class Vertex, class Graph>
Chris@16 62 void initialize_vertex(Vertex u, Graph& g) {
Chris@16 63 invoke_visitors(m_vis, u, g, on_initialize_vertex());
Chris@16 64 }
Chris@16 65 template <class Vertex, class Graph>
Chris@16 66 void discover_vertex(Vertex u, Graph& g) {
Chris@16 67 invoke_visitors(m_vis, u, g, on_discover_vertex());
Chris@16 68 }
Chris@16 69 template <class Vertex, class Graph>
Chris@16 70 void examine_vertex(Vertex u, Graph& g) {
Chris@16 71 invoke_visitors(m_vis, u, g, on_examine_vertex());
Chris@16 72 }
Chris@16 73 template <class Edge, class Graph>
Chris@16 74 void examine_out_edge(Edge e, Graph& g) {
Chris@16 75 invoke_visitors(m_vis, e, g, on_examine_edge());
Chris@16 76 }
Chris@16 77 template <class Edge, class Graph>
Chris@16 78 void tree_out_edge(Edge e, Graph& g) {
Chris@16 79 invoke_visitors(m_vis, e, g, on_tree_edge());
Chris@16 80 }
Chris@16 81 template <class Edge, class Graph>
Chris@16 82 void non_tree_out_edge(Edge e, Graph& g) {
Chris@16 83 invoke_visitors(m_vis, e, g, on_non_tree_edge());
Chris@16 84 }
Chris@16 85 template <class Edge, class Graph>
Chris@16 86 void gray_target(Edge e, Graph& g) {
Chris@16 87 invoke_visitors(m_vis, e, g, on_gray_target());
Chris@16 88 }
Chris@16 89 template <class Edge, class Graph>
Chris@16 90 void black_target(Edge e, Graph& g) {
Chris@16 91 invoke_visitors(m_vis, e, g, on_black_target());
Chris@16 92 }
Chris@16 93 template <class Edge, class Graph>
Chris@16 94 void examine_in_edge(Edge e, Graph& g) {
Chris@16 95 invoke_visitors(m_vis, e, g, on_examine_edge());
Chris@16 96 }
Chris@16 97 template <class Edge, class Graph>
Chris@16 98 void tree_in_edge(Edge e, Graph& g) {
Chris@16 99 invoke_visitors(m_vis, e, g, on_tree_edge());
Chris@16 100 }
Chris@16 101 template <class Edge, class Graph>
Chris@16 102 void non_tree_in_edge(Edge e, Graph& g) {
Chris@16 103 invoke_visitors(m_vis, e, g, on_non_tree_edge());
Chris@16 104 }
Chris@16 105 template <class Edge, class Graph>
Chris@16 106 void gray_source(Edge e, Graph& g) {
Chris@16 107 invoke_visitors(m_vis, e, g, on_gray_target());
Chris@16 108 }
Chris@16 109 template <class Edge, class Graph>
Chris@16 110 void black_source(Edge e, Graph& g) {
Chris@16 111 invoke_visitors(m_vis, e, g, on_black_target());
Chris@16 112 }
Chris@16 113 template <class Vertex, class Graph>
Chris@16 114 void finish_vertex(Vertex u, Graph& g) {
Chris@16 115 invoke_visitors(m_vis, u, g, on_finish_vertex());
Chris@16 116 }
Chris@16 117 protected:
Chris@16 118 Visitors m_vis;
Chris@16 119 };
Chris@16 120
Chris@16 121 template <class Visitors>
Chris@16 122 neighbor_bfs_visitor<Visitors>
Chris@16 123 make_neighbor_bfs_visitor(Visitors vis) {
Chris@16 124 return neighbor_bfs_visitor<Visitors>(vis);
Chris@16 125 }
Chris@16 126
Chris@16 127 namespace detail {
Chris@16 128
Chris@16 129 template <class BidirectionalGraph, class Buffer, class BFSVisitor,
Chris@16 130 class ColorMap>
Chris@16 131 void neighbor_bfs_impl
Chris@16 132 (const BidirectionalGraph& g,
Chris@16 133 typename graph_traits<BidirectionalGraph>::vertex_descriptor s,
Chris@16 134 Buffer& Q, BFSVisitor vis, ColorMap color)
Chris@16 135
Chris@16 136 {
Chris@16 137 BOOST_CONCEPT_ASSERT(( BidirectionalGraphConcept<BidirectionalGraph> ));
Chris@16 138 typedef graph_traits<BidirectionalGraph> GTraits;
Chris@16 139 typedef typename GTraits::vertex_descriptor Vertex;
Chris@16 140 typedef typename GTraits::edge_descriptor Edge;
Chris@16 141 BOOST_CONCEPT_ASSERT((
Chris@16 142 NeighborBFSVisitorConcept<BFSVisitor, BidirectionalGraph> ));
Chris@16 143 BOOST_CONCEPT_ASSERT(( ReadWritePropertyMapConcept<ColorMap, Vertex> ));
Chris@16 144 typedef typename property_traits<ColorMap>::value_type ColorValue;
Chris@16 145 typedef color_traits<ColorValue> Color;
Chris@16 146
Chris@16 147 put(color, s, Color::gray());
Chris@16 148 vis.discover_vertex(s, g);
Chris@16 149 Q.push(s);
Chris@16 150 while (! Q.empty()) {
Chris@16 151 Vertex u = Q.top();
Chris@16 152 Q.pop(); // pop before push to avoid problem if Q is priority_queue.
Chris@16 153 vis.examine_vertex(u, g);
Chris@16 154
Chris@16 155 typename GTraits::out_edge_iterator ei, ei_end;
Chris@16 156 for (boost::tie(ei, ei_end) = out_edges(u, g); ei != ei_end; ++ei) {
Chris@16 157 Edge e = *ei;
Chris@16 158 vis.examine_out_edge(e, g);
Chris@16 159 Vertex v = target(e, g);
Chris@16 160 ColorValue v_color = get(color, v);
Chris@16 161 if (v_color == Color::white()) {
Chris@16 162 vis.tree_out_edge(e, g);
Chris@16 163 put(color, v, Color::gray());
Chris@16 164 vis.discover_vertex(v, g);
Chris@16 165 Q.push(v);
Chris@16 166 } else {
Chris@16 167 vis.non_tree_out_edge(e, g);
Chris@16 168 if (v_color == Color::gray())
Chris@16 169 vis.gray_target(e, g);
Chris@16 170 else
Chris@16 171 vis.black_target(e, g);
Chris@16 172 }
Chris@16 173 } // for out-edges
Chris@16 174
Chris@16 175 typename GTraits::in_edge_iterator in_ei, in_ei_end;
Chris@16 176 for (boost::tie(in_ei, in_ei_end) = in_edges(u, g);
Chris@16 177 in_ei != in_ei_end; ++in_ei) {
Chris@16 178 Edge e = *in_ei;
Chris@16 179 vis.examine_in_edge(e, g);
Chris@16 180 Vertex v = source(e, g);
Chris@16 181 ColorValue v_color = get(color, v);
Chris@16 182 if (v_color == Color::white()) {
Chris@16 183 vis.tree_in_edge(e, g);
Chris@16 184 put(color, v, Color::gray());
Chris@16 185 vis.discover_vertex(v, g);
Chris@16 186 Q.push(v);
Chris@16 187 } else {
Chris@16 188 vis.non_tree_in_edge(e, g);
Chris@16 189 if (v_color == Color::gray())
Chris@16 190 vis.gray_source(e, g);
Chris@16 191 else
Chris@16 192 vis.black_source(e, g);
Chris@16 193 }
Chris@16 194 } // for in-edges
Chris@16 195
Chris@16 196 put(color, u, Color::black());
Chris@16 197 vis.finish_vertex(u, g);
Chris@16 198 } // while
Chris@16 199 }
Chris@16 200
Chris@16 201
Chris@16 202 template <class VertexListGraph, class ColorMap, class BFSVisitor,
Chris@16 203 class P, class T, class R>
Chris@16 204 void neighbor_bfs_helper
Chris@16 205 (VertexListGraph& g,
Chris@16 206 typename graph_traits<VertexListGraph>::vertex_descriptor s,
Chris@16 207 ColorMap color,
Chris@16 208 BFSVisitor vis,
Chris@16 209 const bgl_named_params<P, T, R>& params)
Chris@16 210 {
Chris@16 211 typedef graph_traits<VertexListGraph> Traits;
Chris@16 212 // Buffer default
Chris@16 213 typedef typename Traits::vertex_descriptor Vertex;
Chris@16 214 typedef boost::queue<Vertex> queue_t;
Chris@16 215 queue_t Q;
Chris@16 216 // Initialization
Chris@16 217 typedef typename property_traits<ColorMap>::value_type ColorValue;
Chris@16 218 typedef color_traits<ColorValue> Color;
Chris@16 219 typename boost::graph_traits<VertexListGraph>::vertex_iterator i, i_end;
Chris@16 220 for (boost::tie(i, i_end) = vertices(g); i != i_end; ++i) {
Chris@16 221 put(color, *i, Color::white());
Chris@16 222 vis.initialize_vertex(*i, g);
Chris@16 223 }
Chris@16 224 neighbor_bfs_impl
Chris@16 225 (g, s,
Chris@16 226 choose_param(get_param(params, buffer_param_t()), boost::ref(Q)).get(),
Chris@16 227 vis, color);
Chris@16 228 }
Chris@16 229
Chris@16 230 //-------------------------------------------------------------------------
Chris@16 231 // Choose between default color and color parameters. Using
Chris@16 232 // function dispatching so that we don't require vertex index if
Chris@16 233 // the color default is not being used.
Chris@16 234
Chris@16 235 template <class ColorMap>
Chris@16 236 struct neighbor_bfs_dispatch {
Chris@16 237 template <class VertexListGraph, class P, class T, class R>
Chris@16 238 static void apply
Chris@16 239 (VertexListGraph& g,
Chris@16 240 typename graph_traits<VertexListGraph>::vertex_descriptor s,
Chris@16 241 const bgl_named_params<P, T, R>& params,
Chris@16 242 ColorMap color)
Chris@16 243 {
Chris@16 244 neighbor_bfs_helper
Chris@16 245 (g, s, color,
Chris@16 246 choose_param(get_param(params, graph_visitor),
Chris@16 247 make_neighbor_bfs_visitor(null_visitor())),
Chris@16 248 params);
Chris@16 249 }
Chris@16 250 };
Chris@16 251
Chris@16 252 template <>
Chris@16 253 struct neighbor_bfs_dispatch<param_not_found> {
Chris@16 254 template <class VertexListGraph, class P, class T, class R>
Chris@16 255 static void apply
Chris@16 256 (VertexListGraph& g,
Chris@16 257 typename graph_traits<VertexListGraph>::vertex_descriptor s,
Chris@16 258 const bgl_named_params<P, T, R>& params,
Chris@16 259 param_not_found)
Chris@16 260 {
Chris@16 261 std::vector<default_color_type> color_vec(num_vertices(g));
Chris@16 262 null_visitor null_vis;
Chris@16 263
Chris@16 264 neighbor_bfs_helper
Chris@16 265 (g, s,
Chris@16 266 make_iterator_property_map
Chris@16 267 (color_vec.begin(),
Chris@16 268 choose_const_pmap(get_param(params, vertex_index),
Chris@16 269 g, vertex_index), color_vec[0]),
Chris@16 270 choose_param(get_param(params, graph_visitor),
Chris@16 271 make_neighbor_bfs_visitor(null_vis)),
Chris@16 272 params);
Chris@16 273 }
Chris@16 274 };
Chris@16 275
Chris@16 276 } // namespace detail
Chris@16 277
Chris@16 278
Chris@16 279 // Named Parameter Variant
Chris@16 280 template <class VertexListGraph, class P, class T, class R>
Chris@16 281 void neighbor_breadth_first_search
Chris@16 282 (const VertexListGraph& g,
Chris@16 283 typename graph_traits<VertexListGraph>::vertex_descriptor s,
Chris@16 284 const bgl_named_params<P, T, R>& params)
Chris@16 285 {
Chris@16 286 // The graph is passed by *const* reference so that graph adaptors
Chris@16 287 // (temporaries) can be passed into this function. However, the
Chris@16 288 // graph is not really const since we may write to property maps
Chris@16 289 // of the graph.
Chris@16 290 VertexListGraph& ng = const_cast<VertexListGraph&>(g);
Chris@16 291 typedef typename get_param_type< vertex_color_t, bgl_named_params<P,T,R> >::type C;
Chris@16 292 detail::neighbor_bfs_dispatch<C>::apply(ng, s, params,
Chris@16 293 get_param(params, vertex_color));
Chris@16 294 }
Chris@16 295
Chris@16 296
Chris@16 297 // This version does not initialize colors, user has to.
Chris@16 298
Chris@16 299 template <class IncidenceGraph, class P, class T, class R>
Chris@16 300 void neighbor_breadth_first_visit
Chris@16 301 (IncidenceGraph& g,
Chris@16 302 typename graph_traits<IncidenceGraph>::vertex_descriptor s,
Chris@16 303 const bgl_named_params<P, T, R>& params)
Chris@16 304 {
Chris@16 305 typedef graph_traits<IncidenceGraph> Traits;
Chris@16 306 // Buffer default
Chris@16 307 typedef boost::queue<typename Traits::vertex_descriptor> queue_t;
Chris@16 308 queue_t Q;
Chris@16 309
Chris@16 310 detail::neighbor_bfs_impl
Chris@16 311 (g, s,
Chris@16 312 choose_param(get_param(params, buffer_param_t()), boost::ref(Q)).get(),
Chris@16 313 choose_param(get_param(params, graph_visitor),
Chris@16 314 make_neighbor_bfs_visitor(null_visitor())),
Chris@16 315 choose_pmap(get_param(params, vertex_color), g, vertex_color)
Chris@16 316 );
Chris@16 317 }
Chris@16 318
Chris@16 319 } // namespace boost
Chris@16 320
Chris@16 321 #endif // BOOST_GRAPH_NEIGHBOR_BREADTH_FIRST_SEARCH_HPP
Chris@16 322