Boost logo

Boost :

Subject: Re: [boost] [BGL] To customize the graph traversing
From: Dmitry Bufistov (dmitry_at_[hidden])
Date: 2009-07-16 06:48:41


Cosimo Calabrese escribió:
>
>> Yep. I see now. Sorry.
>> What if you just "unfold" you graph to explicitly create all possible
>> paths? For example, in your example you should duplicate node D to D1
>> and D2 and remove edge (D2->G):
>>
>> _C _ F
>> o| //|\
>> o / /
>> o / /
>> A---->B------> D1/o o o >G
>> | /\
>> \ D2 \
>> \ ^ \ \
>> \ | \ \
>> _\| | _\||/
>> E | H
>> I
>>
>
>
> Yes, I've yet do it.
>
> But the graph can increases his dimension in memory too much; moreover,
> I must do the "vertex split" ( D in D1 and D2 ) offline, that is before
> I use the graph in the client application; if the edge's property (that
> explains in which edge the exploration can go) change, I must change the
> graph on-the-fly, and my "split algorithm" is complex...
>
> I search a strategy to understand in that direction to continue the
> exploration maintaining the graph unchanged. If there were a way to
> encapsulate the exploration rule, this would be a more flexible strategy.
>

You may try to specialize out_edges() function.
See attached example.

Dmitry


#include <list>
#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/graph_traits.hpp>
#include <boost/graph/graph_utility.hpp>
#include <boost/graph/properties.hpp>

struct ep_t;
struct vp_t;
typedef boost::adjacency_list<boost::listS, boost::vecS, boost::directedS,
                              vp_t, ep_t> my_graph;

typedef boost::graph_traits<my_graph>::edge_descriptor Edge;
typedef boost::graph_traits<my_graph>::vertex_descriptor Vertex;
typedef std::list<Edge> outel_t;
extern outel_t goutel;

namespace std {
  std::ostream& operator<<(std::ostream &os, const outel_t &o);
}
struct vp_t
{
  Edge pred; //Edge from which the vertex has been discovered
  Vertex pv;
};

struct ep_t
{
  outel_t outel;
  friend std::ostream& operator<<(std::ostream &os, const ep_t &o)
  {
    std::copy(o.outel.begin(), o.outel.end(), std::ostream_iterator<Edge>(os," "));
    return os << std::endl;
  }
};

class graph_wrapper
{
public:
  graph_wrapper(const my_graph &g) : m_g(g) {}
  const my_graph& get_graph() const { return m_g; }
private:
  const my_graph &m_g;
};

namespace boost {
template <>
struct graph_traits<graph_wrapper> {
    typedef my_graph::vertex_descriptor vertex_descriptor;
    typedef my_graph::edge_descriptor edge_descriptor;
    typedef my_graph::adjacency_iterator adjacency_iterator;
    typedef outel_t::const_iterator out_edge_iterator;
    typedef my_graph::in_edge_iterator in_edge_iterator;
    typedef my_graph::vertex_iterator vertex_iterator;
    typedef my_graph::edge_iterator edge_iterator;

    typedef my_graph::directed_category directed_category;
    typedef my_graph::edge_parallel_category edge_parallel_category;
    typedef my_graph::traversal_category traversal_category;

    typedef my_graph::vertices_size_type vertices_size_type;
    typedef my_graph::edges_size_type edges_size_type;
    typedef my_graph::degree_size_type degree_size_type;

    static inline vertex_descriptor null_vertex();
  };

 inline std::pair<
   boost::graph_traits< graph_wrapper >::vertex_iterator,
   boost::graph_traits< graph_wrapper >::vertex_iterator >
   vertices(const graph_wrapper &g)
  {
    return boost::vertices(g.get_graph());
  }

 inline graph_traits<graph_wrapper>::degree_size_type
  out_degree(graph_traits<graph_wrapper>::vertex_descriptor v,
  const graph_wrapper &g)
  {
    return boost::out_degree(v, g.get_graph());
  }

inline std::pair<graph_traits<graph_wrapper>::out_edge_iterator,
graph_traits<graph_wrapper>::out_edge_iterator>
out_edges(graph_traits<graph_wrapper>::vertex_descriptor v,
          const graph_wrapper &g)
{
  property_map<my_graph, outel_t ep_t::*>::const_type
    epm(get(&ep_t::outel, g.get_graph()));
  if (get(&vp_t::pv, g.get_graph(), v) != v)
  {
    return std::make_pair(get(epm, get(&vp_t::pred, g.get_graph(), v)).begin(),
      get(epm, get(&vp_t::pred, g.get_graph(), v)).end());
  }
  else
  {
    goutel.clear();
    boost::graph_traits<my_graph>::out_edge_iterator oei, oei_end;
    for (boost::tie(oei, oei_end) = boost::out_edges(v, g.get_graph());
      oei != oei_end; ++oei)
    {
      goutel.push_back(*oei);
    }
    return std::make_pair(goutel.begin(), goutel.end());
  }
}
}

inline boost::graph_traits<graph_wrapper>::vertex_descriptor
source(boost::graph_traits<graph_wrapper>::edge_descriptor e,
    const graph_wrapper &g)
 {
   boost::graph_traits<my_graph>::edge_descriptor e_ = e;
   return boost::source(e_, g.get_graph());
 }

inline boost::graph_traits<graph_wrapper>::vertex_descriptor
target(boost::graph_traits<graph_wrapper>::edge_descriptor e,
    const graph_wrapper &g)
 {
   return boost::target(e, g.get_graph());
 }



Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk