Search code examples
c++boostboost-graph

Boost Graph Library: How to use depth_first_visit, issue with ColorMap


Initial question: Boost Graph Library: Prevent DFS from visiting unconnected nodes

I am trying to use boost::depth_first_visit, but don't know how to supply the ColorMap property. I tried the method given in the example here: http://www.boost.org/doc/libs/1_58_0/libs/graph/example/loops_dfs.cpp

My (relevant) code:

    /// Define vertex properties.
    struct NodeProperty
    {
        unsigned     id;              /// Id.
        unsigned     kind;            /// Kind.
        unsigned     depth;           /// Depth.
        unsigned     layer_color;     /// Layer color.
        unsigned     signal_color;    /// Signal color.
        unsigned     sch_color;       /// Sch color.
        CBoundingBox bounds;          /// Bounds.

        NodeProperty()
           : id(0), kind(0), depth(0), layer_color(0), signal_color(0), sch_color(0), bounds(0,0,0,0)
        {
           ;
        }
   };

   /// Define net topology graph.
   typedef boost::adjacency_list<boost::vecS, boost::vecS, boost::bidirectionalS, NodeProperty> Graph;
   /// Define Vertex + iterator.
   typedef boost::graph_traits<Graph>::vertex_descriptor Vertex;
   typedef boost::graph_traits<Graph>::vertex_iterator VertexItr;
   /// Define Edge + iterator.
   typedef boost::graph_traits<Graph>::edge_descriptor Edge;
   typedef boost::graph_traits<Graph>::edge_iterator EdgeItr;

   class receiver_visitor : public boost::default_dfs_visitor
   {
   public:
       receiver_visitor(std::vector<Vertex>& r)
           : recv(r)
       {
            ;
       }

       void discover_vertex(Vertex v, Graph const& g) const
       {
            std::cout << "Visit: " << v << std::endl;
            if (g[v].sch_color) {
                recv.push_back(g[v].sch_color);
            }
       }

       std::vector<Vertex>& recv;
   };

   std::vector<std::size_t>
   NetTopology::getReceivers(std::size_t src) const
   {
       std::vector<Vertex> recv;
       receiver_visitor vis(recv);

       std::vector<boost::default_color_type> color_map(boost::num_vertices(data_->g));

      //boost::depth_first_search(data_->g, boost::visitor(vis).root_vertex(src));
      boost::depth_first_visit(data_->g,
                               src,
                               boost::visitor(vis),
                        boost::make_iterator_property_map(color_map.begin(), boost::get(boost::vertex_index, data_->g), color_map[0]));

      return recv;
    }

I get the compile error below which I don't know how to fix. Any ideas?

/p/dt/cad/em64t_SLES11/boost/1.58.0_gcc472_64/include/boost/graph/depth_first_search.hpp: In instantiation of 'void boost::depth_first_visit(const IncidenceGraph&, typen
        ame boost::graph_traits<Graph>::vertex_descriptor, DFSVisitor, ColorMap) [with IncidenceGraph = boost::adjacency_list<boost::vecS, boost::vecS, boost::bidirectionalS, tr
        on::les::NodeProperty>; DFSVisitor = boost::bgl_named_params<tron::les::receiver_visitor, boost::graph_visitor_t, boost::no_property>; ColorMap = boost::iterator_propert
        y_map<__gnu_cxx::__normal_iterator<boost::default_color_type*, std::vector<boost::default_color_type> >, boost::vec_adj_list_vertex_id_map<tron::les::NodeProperty, long 
        unsigned int>, boost::default_color_type, boost::default_color_type&>; typename boost::graph_traits<Graph>::vertex_descriptor = long unsigned int]':
        NetTopology.cpp:353:139:   required from here
        /p/dt/cad/em64t_SLES11/boost/1.58.0_gcc472_64/include/boost/graph/depth_first_search.hpp:341:5: error: 'struct boost::bgl_named_params<tron::les::receiver_visitor, boost
        ::graph_visitor_t, boost::no_property>' has no member named 'start_vertex'
             vis.start_vertex(u, g);

Solution

  • The overload of depth_first_search you were originally using was:

    template <class Graph, class class P, class T, class R>
    void depth_first_search(Graph& G,
      const bgl_named_params<P, T, R>& params);
    

    and the one you want to use for depth_first_visit is:

    template <class IncidenceGraph, class DFSVisitor, class ColorMap>
    void depth_first_visit(IncidenceGraph& g,
      typename graph_traits<IncidenceGraph>::vertex_descriptor s, 
      DFSVisitor& vis, ColorMap color);
    

    The first one used Named Parameters and so you needed to use boost::visitor(vis).root_vertex(src) (or boost::root_vertex(src).visitor(vis) or just boost::visitor(vis) if you wanted to use the default start vertex). Since the depth_first_visit does not use them you need to remove the call to boost::visitor(...) and pass vis directly:

    boost::depth_first_visit(data_->g,
                                   src,
                                   vis,
                            boost::make_iterator_property_map(color_map.begin(), boost::get(boost::vertex_index, data_->g), color_map[0]));