
I have attached a draft version. I wrote it strictly following to the instructions from boost::graph documentation http://www.boost.org/doc/libs/1_35_0/libs/graph/doc/leda_conversion.html What was really exciting is that after this I was able to call graph algorithms (currently I have succided in calling Bellman Ford shortes path, strongly connected components and minimal cycle ratio) without data copying. boost::bundle_property_map<> is quite suitable for creating boost property maps from graphviz properties. In my current implementation its usage is not completly generic. I think with enough motivation it would take one day to make it 100% generic. Waiting somebody motivates me, Regards, Dmitry Max escribió:
Please give more details ... :-)
Cheers Max
Hi there,
I have a very nice BGL adaptor for AT&T graphviz graph representation. Is it worthy to add it to the boost library ?
Thanks in advance,
Sr. Dmitry
------------------------------------------------------------------------
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
#ifndef GRAPHVIZ_BGL_ADAPTOR_HPP #define GRAPHVIZ_BGL_ADAPTOR_HPP #include <stdexcept> //#include <iostream> #include <boost/config.hpp> #include <boost/iterator/iterator_facade.hpp> #include <boost/graph/graph_traits.hpp> #include <boost/graph/properties.hpp> #include <agraph.h> namespace boost { typedef Agraph_t* bgl_graphviz_t; struct graphviz_traversal_category : public virtual edge_list_graph_tag, public virtual bidirectional_graph_tag, public virtual adjacency_graph_tag, public virtual vertex_list_graph_tag { }; template <> struct graph_traits<bgl_graphviz_t> { typedef Agnode_t* vertex_descriptor; typedef Agedge_t* edge_descriptor; struct vertex_iterator : public iterator_facade<vertex_iterator, vertex_descriptor, forward_traversal_tag, const vertex_descriptor&> { explicit vertex_iterator(vertex_descriptor v = 0) : m_v(v) { } const vertex_descriptor& dereference() const { return m_v; } bool equal(const vertex_iterator& other) const { if (m_v == other.m_v) return true; if (other.m_v == 0 || m_v == 0) return false; return AGID(m_v) == AGID(other.m_v); } void increment() { m_v = agnxtnode(m_v); } private: vertex_descriptor m_v; }; struct edge_iterator : public iterator_facade<edge_iterator, edge_descriptor, forward_traversal_tag, const edge_descriptor&> { explicit edge_iterator(vertex_descriptor v = 0, edge_descriptor e = 0) : m_v(v), m_base(e) { } virtual ~edge_iterator() {} protected: virtual void increment() { if (m_base == 0) throw std::runtime_error("Out of range\n"); m_base = agnxtout(m_base); if (m_base == 0) { m_v = agnxtnode(m_v); if (m_v) m_base = agfstout(m_v); } } const edge_descriptor& dereference() const { return m_base; } bool equal(const edge_iterator& other) const { if (m_base == other.m_base) return true; if (other.m_base == 0 || m_base == 0) return false; return AGID(m_base) == AGID(other.m_base); } vertex_descriptor m_v; edge_descriptor m_base; friend class iterator_core_access; }; struct out_edge_iterator : public iterator_facade<out_edge_iterator, edge_descriptor, forward_traversal_tag, const edge_descriptor&> { explicit out_edge_iterator(vertex_descriptor v = 0, edge_descriptor e = 0) : m_v(v), m_base(e) {} protected: const edge_descriptor& dereference() const { return m_base; } void increment() { if (m_base == 0) throw std::runtime_error("Out of range\n"); m_base = agnxtout(m_base); } bool equal(const out_edge_iterator& other) const { if (m_base == other.m_base) return true; if (other.m_base == 0 || m_base == 0) return false; return AGID(m_base) == AGID(other.m_base); } vertex_descriptor m_v; edge_descriptor m_base; friend class iterator_core_access; }; struct in_edge_iterator : public edge_iterator { explicit in_edge_iterator(vertex_descriptor v = 0, edge_descriptor e = 0) : edge_iterator(v, e) { } void increment() { if (m_base == 0) throw std::runtime_error("Out of range\n"); m_base = agnxtin(m_base); } }; typedef boost::directed_tag directed_category; typedef allow_parallel_edge_tag edge_parallel_category; typedef graphviz_traversal_category traversal_category; typedef unsigned vertices_size_type; typedef int edges_size_type; typedef int degree_size_type; vertex_descriptor null_vertex() { return vertex_descriptor(0); } }; inline std::pair< graph_traits< bgl_graphviz_t >::edge_iterator, graph_traits< bgl_graphviz_t >::edge_iterator > edges(const bgl_graphviz_t& g) { typedef graph_traits< bgl_graphviz_t>::edge_iterator myIter; bgl_graphviz_t &ncg = const_cast< bgl_graphviz_t&>(g); return std::make_pair( myIter(agfstnode(ncg), agfstout(agfstnode(ncg))), myIter() ); } inline std::pair< graph_traits< bgl_graphviz_t >::vertex_iterator, graph_traits< bgl_graphviz_t >::vertex_iterator > vertices(const bgl_graphviz_t& g) { typedef graph_traits<bgl_graphviz_t >::vertex_iterator myIter; Agraph_t* ncg = const_cast<bgl_graphviz_t>(g); return std::make_pair( myIter(agfstnode(ncg)), myIter() ); } inline graph_traits<bgl_graphviz_t>::vertex_descriptor source(graph_traits<bgl_graphviz_t>::edge_descriptor e, const bgl_graphviz_t &g) { return agtail(e); } inline graph_traits<bgl_graphviz_t>::vertex_descriptor target(graph_traits<bgl_graphviz_t>::edge_descriptor e, const bgl_graphviz_t &g) { return aghead(e); } inline std::pair< graph_traits<bgl_graphviz_t>::out_edge_iterator, graph_traits<bgl_graphviz_t >::out_edge_iterator > out_edges( graph_traits< bgl_graphviz_t>::vertex_descriptor v, const bgl_graphviz_t &g) { typedef graph_traits< bgl_graphviz_t >::out_edge_iterator myIter; return std::make_pair( myIter(v, agfstout(v)), myIter(v) ); } inline graph_traits<Agraph_t*>::degree_size_type out_degree(graph_traits<Agraph_t*>::vertex_descriptor v, const bgl_graphviz_t &g) { return agdegree(v, FALSE, TRUE); } inline graph_traits< bgl_graphviz_t >::vertices_size_type num_vertices(const bgl_graphviz_t& g) { return agnnodes(const_cast<bgl_graphviz_t>(g)); } inline graph_traits<bgl_graphviz_t>::edges_size_type num_edges(const bgl_graphviz_t& g) { return agnedges(const_cast<bgl_graphviz_t>(g)); } inline graph_traits<bgl_graphviz_t>::degree_size_type in_degree(graph_traits<bgl_graphviz_t>::vertex_descriptor v, const bgl_graphviz_t& g) { return agdegree(v, TRUE, FALSE); } inline std::pair< graph_traits<bgl_graphviz_t>::in_edge_iterator, graph_traits<bgl_graphviz_t >::in_edge_iterator > in_edges( graph_traits<bgl_graphviz_t>::vertex_descriptor v, const bgl_graphviz_t& g) { typedef graph_traits<bgl_graphviz_t>::in_edge_iterator myIter; return std::make_pair( myIter(v, agfstin(v)), myIter(v) ); } template <typename OBJ> struct graphviz_id_map : public put_get_helper<int, graphviz_id_map<OBJ> > { typedef readable_property_map_tag category; typedef int value_type; typedef int reference; typedef OBJ key_type; //Node or edge graphviz_id_map() { } int operator[](const OBJ& o) const { return AGID(o); } }; /* inline graphviz_id_map get(vertex_index_t, const bgl_graphviz_t& g) { return graphviz_id_map(); }*/ template <typename OBJ> struct ltgraphviz { bool operator()(const OBJ& o1, const OBJ& o2) const { return AGID(o1) < AGID(o2); } }; } // namespace boost typedef boost::graphviz_id_map<Agnode_t*> vim1_t; typedef boost::graphviz_id_map<Agedge_t*> eim1_t; #endif //GRAPHVIZ_BGL_ADAPTOR_HPP