epoc32/include/stdapis/boost/graph/breadth_first_search.hpp
author William Roberts <williamr@symbian.org>
Tue, 16 Mar 2010 16:12:26 +0000
branchSymbian2
changeset 2 2fe1408b6811
permissions -rw-r--r--
Final list of Symbian^2 public API header files
     1 //
     2 //=======================================================================
     3 // Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
     4 // Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
     5 //
     6 // Distributed under the Boost Software License, Version 1.0. (See
     7 // accompanying file LICENSE_1_0.txt or copy at
     8 // http://www.boost.org/LICENSE_1_0.txt)
     9 //=======================================================================
    10 //
    11 #ifndef BOOST_GRAPH_BREADTH_FIRST_SEARCH_HPP
    12 #define BOOST_GRAPH_BREADTH_FIRST_SEARCH_HPP
    13 
    14 /*
    15   Breadth First Search Algorithm (Cormen, Leiserson, and Rivest p. 470)
    16 */
    17 #include <boost/config.hpp>
    18 #include <vector>
    19 #include <boost/pending/queue.hpp>
    20 #include <boost/graph/graph_traits.hpp>
    21 #include <boost/graph/graph_concepts.hpp>
    22 #include <boost/graph/visitors.hpp>
    23 #include <boost/graph/named_function_params.hpp>
    24 
    25 namespace boost {
    26 
    27   template <class Visitor, class Graph>
    28   struct BFSVisitorConcept {
    29     void constraints() {
    30       function_requires< CopyConstructibleConcept<Visitor> >();
    31       vis.initialize_vertex(u, g);
    32       vis.discover_vertex(u, g);
    33       vis.examine_vertex(u, g);
    34       vis.examine_edge(e, g);
    35       vis.tree_edge(e, g);
    36       vis.non_tree_edge(e, g);
    37       vis.gray_target(e, g);
    38       vis.black_target(e, g);
    39       vis.finish_vertex(u, g);
    40     }
    41     Visitor vis;
    42     Graph g;
    43     typename graph_traits<Graph>::vertex_descriptor u;
    44     typename graph_traits<Graph>::edge_descriptor e;
    45   };
    46 
    47 
    48   template <class IncidenceGraph, class Buffer, class BFSVisitor,
    49             class ColorMap>
    50   void breadth_first_visit
    51     (const IncidenceGraph& g,
    52      typename graph_traits<IncidenceGraph>::vertex_descriptor s,
    53      Buffer& Q, BFSVisitor vis, ColorMap color)
    54   {
    55     function_requires< IncidenceGraphConcept<IncidenceGraph> >();
    56     typedef graph_traits<IncidenceGraph> GTraits;
    57     typedef typename GTraits::vertex_descriptor Vertex;
    58     typedef typename GTraits::edge_descriptor Edge;
    59     function_requires< BFSVisitorConcept<BFSVisitor, IncidenceGraph> >();
    60     function_requires< ReadWritePropertyMapConcept<ColorMap, Vertex> >();
    61     typedef typename property_traits<ColorMap>::value_type ColorValue;
    62     typedef color_traits<ColorValue> Color;
    63     typename GTraits::out_edge_iterator ei, ei_end;
    64 
    65     put(color, s, Color::gray());             vis.discover_vertex(s, g);
    66     Q.push(s);
    67     while (! Q.empty()) {
    68       Vertex u = Q.top(); Q.pop();            vis.examine_vertex(u, g);
    69       for (tie(ei, ei_end) = out_edges(u, g); ei != ei_end; ++ei) {
    70         Vertex v = target(*ei, g);            vis.examine_edge(*ei, g);
    71         ColorValue v_color = get(color, v);
    72         if (v_color == Color::white()) {      vis.tree_edge(*ei, g);
    73           put(color, v, Color::gray());       vis.discover_vertex(v, g);
    74           Q.push(v);
    75         } else {                              vis.non_tree_edge(*ei, g);
    76           if (v_color == Color::gray())       vis.gray_target(*ei, g);
    77           else                                vis.black_target(*ei, g);
    78         }
    79       } // end for
    80       put(color, u, Color::black());          vis.finish_vertex(u, g);
    81     } // end while
    82   } // breadth_first_visit
    83 
    84 
    85   template <class VertexListGraph, class Buffer, class BFSVisitor,
    86             class ColorMap>
    87   void breadth_first_search
    88     (const VertexListGraph& g,
    89      typename graph_traits<VertexListGraph>::vertex_descriptor s,
    90      Buffer& Q, BFSVisitor vis, ColorMap color)
    91   {
    92     // Initialization
    93     typedef typename property_traits<ColorMap>::value_type ColorValue;
    94     typedef color_traits<ColorValue> Color;
    95     typename boost::graph_traits<VertexListGraph>::vertex_iterator i, i_end;
    96     for (tie(i, i_end) = vertices(g); i != i_end; ++i) {
    97       vis.initialize_vertex(*i, g);
    98       put(color, *i, Color::white());
    99     }
   100     breadth_first_visit(g, s, Q, vis, color);
   101   }
   102 
   103 
   104   template <class Visitors = null_visitor>
   105   class bfs_visitor {
   106   public:
   107     bfs_visitor() { }
   108     bfs_visitor(Visitors vis) : m_vis(vis) { }
   109 
   110     template <class Vertex, class Graph>
   111     void initialize_vertex(Vertex u, Graph& g) {
   112       invoke_visitors(m_vis, u, g, ::boost::on_initialize_vertex());
   113     }
   114     template <class Vertex, class Graph>
   115     void discover_vertex(Vertex u, Graph& g) {
   116       invoke_visitors(m_vis, u, g, ::boost::on_discover_vertex());
   117     }
   118     template <class Vertex, class Graph>
   119     void examine_vertex(Vertex u, Graph& g) {
   120       invoke_visitors(m_vis, u, g, ::boost::on_examine_vertex());
   121     }
   122     template <class Edge, class Graph>
   123     void examine_edge(Edge e, Graph& g) {
   124       invoke_visitors(m_vis, e, g, ::boost::on_examine_edge());
   125     }
   126     template <class Edge, class Graph>
   127     void tree_edge(Edge e, Graph& g) {
   128       invoke_visitors(m_vis, e, g, ::boost::on_tree_edge());
   129     }
   130     template <class Edge, class Graph>
   131     void non_tree_edge(Edge e, Graph& g) {
   132       invoke_visitors(m_vis, e, g, ::boost::on_non_tree_edge());
   133     }
   134     template <class Edge, class Graph>
   135     void gray_target(Edge e, Graph& g) {
   136       invoke_visitors(m_vis, e, g, ::boost::on_gray_target());
   137     }
   138     template <class Edge, class Graph>
   139     void black_target(Edge e, Graph& g) {
   140       invoke_visitors(m_vis, e, g, ::boost::on_black_target());
   141     }
   142     template <class Vertex, class Graph>
   143     void finish_vertex(Vertex u, Graph& g) {
   144       invoke_visitors(m_vis, u, g, ::boost::on_finish_vertex());
   145     }
   146 
   147     BOOST_GRAPH_EVENT_STUB(on_initialize_vertex,bfs)
   148     BOOST_GRAPH_EVENT_STUB(on_discover_vertex,bfs)
   149     BOOST_GRAPH_EVENT_STUB(on_examine_vertex,bfs)
   150     BOOST_GRAPH_EVENT_STUB(on_examine_edge,bfs)
   151     BOOST_GRAPH_EVENT_STUB(on_tree_edge,bfs)
   152     BOOST_GRAPH_EVENT_STUB(on_non_tree_edge,bfs)
   153     BOOST_GRAPH_EVENT_STUB(on_gray_target,bfs)
   154     BOOST_GRAPH_EVENT_STUB(on_black_target,bfs)
   155     BOOST_GRAPH_EVENT_STUB(on_finish_vertex,bfs)
   156 
   157   protected:
   158     Visitors m_vis;
   159   };
   160   template <class Visitors>
   161   bfs_visitor<Visitors>
   162   make_bfs_visitor(Visitors vis) {
   163     return bfs_visitor<Visitors>(vis);
   164   }
   165   typedef bfs_visitor<> default_bfs_visitor;
   166 
   167 
   168   namespace detail {
   169 
   170     template <class VertexListGraph, class ColorMap, class BFSVisitor,
   171       class P, class T, class R>
   172     void bfs_helper
   173       (VertexListGraph& g,
   174        typename graph_traits<VertexListGraph>::vertex_descriptor s,
   175        ColorMap color,
   176        BFSVisitor vis,
   177        const bgl_named_params<P, T, R>& params)
   178     {
   179       typedef graph_traits<VertexListGraph> Traits;
   180       // Buffer default
   181       typedef typename Traits::vertex_descriptor Vertex;
   182       typedef boost::queue<Vertex> queue_t;
   183       queue_t Q;
   184       detail::wrap_ref<queue_t> Qref(Q);
   185       breadth_first_search
   186         (g, s,
   187          choose_param(get_param(params, buffer_param_t()), Qref).ref,
   188          vis, color);
   189     }
   190 
   191     //-------------------------------------------------------------------------
   192     // Choose between default color and color parameters. Using
   193     // function dispatching so that we don't require vertex index if
   194     // the color default is not being used.
   195 
   196     template <class ColorMap>
   197     struct bfs_dispatch {
   198       template <class VertexListGraph, class P, class T, class R>
   199       static void apply
   200       (VertexListGraph& g,
   201        typename graph_traits<VertexListGraph>::vertex_descriptor s,
   202        const bgl_named_params<P, T, R>& params,
   203        ColorMap color)
   204       {
   205         bfs_helper
   206           (g, s, color,
   207            choose_param(get_param(params, graph_visitor),
   208                         make_bfs_visitor(null_visitor())),
   209            params);
   210       }
   211     };
   212 
   213     template <>
   214     struct bfs_dispatch<detail::error_property_not_found> {
   215       template <class VertexListGraph, class P, class T, class R>
   216       static void apply
   217       (VertexListGraph& g,
   218        typename graph_traits<VertexListGraph>::vertex_descriptor s,
   219        const bgl_named_params<P, T, R>& params,
   220        detail::error_property_not_found)
   221       {
   222         std::vector<default_color_type> color_vec(num_vertices(g));
   223         default_color_type c = white_color;
   224         null_visitor null_vis;
   225 
   226         bfs_helper
   227           (g, s,
   228            make_iterator_property_map
   229            (color_vec.begin(),
   230             choose_const_pmap(get_param(params, vertex_index),
   231                               g, vertex_index), c),
   232            choose_param(get_param(params, graph_visitor),
   233                         make_bfs_visitor(null_vis)),
   234            params);
   235       }
   236     };
   237 
   238   } // namespace detail
   239 
   240 
   241   // Named Parameter Variant
   242   template <class VertexListGraph, class P, class T, class R>
   243   void breadth_first_search
   244     (const VertexListGraph& g,
   245      typename graph_traits<VertexListGraph>::vertex_descriptor s,
   246      const bgl_named_params<P, T, R>& params)
   247   {
   248     // The graph is passed by *const* reference so that graph adaptors
   249     // (temporaries) can be passed into this function. However, the
   250     // graph is not really const since we may write to property maps
   251     // of the graph.
   252     VertexListGraph& ng = const_cast<VertexListGraph&>(g);
   253     typedef typename property_value< bgl_named_params<P,T,R>,
   254       vertex_color_t>::type C;
   255     detail::bfs_dispatch<C>::apply(ng, s, params,
   256                                    get_param(params, vertex_color));
   257   }
   258 
   259 
   260   // This version does not initialize colors, user has to.
   261 
   262   template <class IncidenceGraph, class P, class T, class R>
   263   void breadth_first_visit
   264     (const IncidenceGraph& g,
   265      typename graph_traits<IncidenceGraph>::vertex_descriptor s,
   266      const bgl_named_params<P, T, R>& params)
   267   {
   268     // The graph is passed by *const* reference so that graph adaptors
   269     // (temporaries) can be passed into this function. However, the
   270     // graph is not really const since we may write to property maps
   271     // of the graph.
   272     IncidenceGraph& ng = const_cast<IncidenceGraph&>(g);
   273 
   274     typedef graph_traits<IncidenceGraph> Traits;
   275     // Buffer default
   276     typedef typename Traits::vertex_descriptor vertex_descriptor;
   277     typedef boost::queue<vertex_descriptor> queue_t;
   278     queue_t Q;
   279     detail::wrap_ref<queue_t> Qref(Q);
   280 
   281     breadth_first_visit
   282       (ng, s,
   283        choose_param(get_param(params, buffer_param_t()), Qref).ref,
   284        choose_param(get_param(params, graph_visitor),
   285                     make_bfs_visitor(null_visitor())),
   286        choose_pmap(get_param(params, vertex_color), ng, vertex_color)
   287        );
   288   }
   289 
   290 } // namespace boost
   291 
   292 #endif // BOOST_GRAPH_BREADTH_FIRST_SEARCH_HPP
   293