Boost logo

Boost Users :

From: Gordon Smith (schmoo2k_at_[hidden])
Date: 2005-02-09 08:00:33


ok - just to clarify - I am not having any issues with vertex or edge
properties, I am having an issue with graph properties, (hence the specific
example).

Gordon.

"Jeffrey Holle" <jeff.holle_at_[hidden]> wrote in message
news:42094DDB.9090802_at_verizon.net...
> Excuse me, I don't use graph properties, though I suspect they behave the
same
> as edge and vertex properties as far as subgraphs go.
>
> What I can provide is the class that I used to wrap subgraphs.
> The inner VertexData and EdgeData classes provide operator[] and iterator
> interfaces. Look at the implementation of these methods to see the
boost::get
> usage.
>
> This was developed for boost 1.31.1. I know that things have improved
somewhat
> in this area, but believe the subgraph/property things remain the same.
>
> Gordon Smith wrote:
> > I am not sure I follow - I am specifically talking about "graph_name_t"
type
> > properties (not vertex or edge properties) - can show a code snippet of
how
> > you get a reference to one for a specific subgraph?
> >
> > TIA,
> >
> > Gordon.
> >
> > "Jeffrey Holle" <jeff.holle_at_[hidden]> wrote in message
> > news:cubfff$8mt$1_at_sea.gmane.org...
> >
> >>The answer is no.
> >>The way I had to employ internal properties with subgraph is to use the
> >
> > root.
> >
> >>method of the subgraph class to access the properties of the root graph.
> >>Note that the local to global vertex/edge index methods must also be
used.
> >>
> >>The subgraph does have properties, just not the same as the roots.
> >>
> >>Gordon Smith wrote:
> >>
> >>>The following example produces the following (unexpected results):
> >>>name: graph
> >>>name: subgraph 1
> >>>name sg2: subgraph 2
> >>>name sg: subgraph 2
> >>>
> >>>Do subgraphs share the same property_map?
> >>>
> >>>Gordon.
> >>>
> >>>// SubGraphPropertyTest.cpp : Defines the entry point for the console
> >>>application.
> >>>//
> >>>#include "stdafx.h"
> >>>#include <string>
> >>>#include <iostream>
> >>>#include <boost/cstdlib.hpp>
> >>>#include <boost/graph/adjacency_list.hpp>
> >>>#include <boost/graph/subgraph.hpp>
> >>>int
> >>>main()
> >>>{
> >>>using namespace boost;
> >>>using std::string;
> >>>typedef adjacency_list<vecS, vecS, directedS,no_property,
> >>>property<edge_index_t, int>,
> >>>property<graph_name_t, string> > graph_t;
> >>>graph_t g;
> >>>get_property(g, graph_name) = "graph";
> >>>std::cout << "name: " << get_property(g, graph_name) << std::endl;
> >>>typedef subgraph<graph_t> subgraph_t;
> >>>subgraph_t sg;
> >>>get_property(sg, graph_name) = "subgraph 1";
> >>>std::cout << "name: " << get_property(sg, graph_name) << std::endl;
> >>>subgraph_t sg2 = sg.create_subgraph();
> >>>get_property(sg2, graph_name) = "subgraph 2";
> >>>std::cout << "name sg2: " << get_property(sg2, graph_name) <<
std::endl;
> >>>std::cout << "name sg: " << get_property(sg, graph_name) << std::endl;
> >>>return exit_success;
> >>>}
>

----------------------------------------------------------------------------

----
> /*
>  * This is a directional graph that inherits from the boost::graph
subgraph adjacent list template.
>  * Properties are internal, though public accessors are provided here that
can be used within any subgraph
>  * derived from this class via create_subgraph to access the base graph
properties.
>  * All graph mutators which affect these properties, are implemented as
methods.
>  */
> #include "dataGraph.h"
> #include <assert.h>
> #include <iostream>
> #include <utility>
> #include <algorithm>
> #include <iterator>
> #include <set>
> #include "pseudoClasses.h"
> #include "dfsVisitor.h"
>
> using namespace std;
> using boost::tie;
>
> DataGraph::DataGraph(DataGraphT& dataGraph)
>   : dataGraph_(dataGraph)
> {}
>
> DataGraph::DataGraph(DataGraphT& dataGraph,const DataVertices&
dataVertices)
>   : dataGraph_(dataGraph)
> {
>   for (DataVertices::const_iterator
iter=dataVertices.begin();iter!=dataVertices.end();++iter)
>     boost::add_vertex(*iter,dataGraph_);
> }
>
> DataGraph::VertexData::VertexData(DataGraphT& dataGraph)
>   : dataGraph_(dataGraph)
> {
> }
>
> DataGraph::EdgeData::EdgeData(DataGraphT& dataGraph)
>   : dataGraph_(dataGraph)
> {
> }
>
> Vertex_Datum&
> DataGraph::VertexData::operator[] (const DataVertex& index)
> {
>   return boost::get(boost::get(vertex_Datum,
dataGraph_.root()),dataGraph_.local_to_global(index));
> }
>
> Edge_Datum&
> DataGraph::EdgeData::operator[] (const DataEdge& index)
> {
>   return boost::get(boost::get(edge_Datum,
dataGraph_.root()),dataGraph_.local_to_global(index));
> }
>
> DataEdge
> DataGraph::add_edge(LayoutEdge* pLayoutEdge,DataVertex source,DataVertex
target)
> {
>   typedef pair<DataEdge,bool> Result;
>   Result result = boost::add_edge(source,target,dataGraph_);
>   assert(result.second == true);
>
boost::put(boost::get(edge_Datum,dataGraph_.root()),dataGraph_.local_to_glob
al(result.first),Edge_Datum(pLayoutEdge));
>   return result.first;
> }
>
> DataEdge
> DataGraph::add_edge(PseudoEdge* pPseudoEdge,DataVertex source,DataVertex
target)
> {
>   typedef pair<DataEdge,bool> Result;
>   Result result = boost::add_edge(source,target,dataGraph_);
>   assert(result.second == true);
>
boost::put(boost::get(edge_Datum,dataGraph_.root()),dataGraph_.local_to_glob
al(result.first),Edge_Datum(pPseudoEdge));
>   return result.first;
> }
>
> DataEdge
> DataGraph::add_edge(const Edge_Datum& edgeDatum,DataVertex
source,DataVertex target)
> {
>   typedef pair<DataEdge,bool> Result;
>   Result result = boost::add_edge(source,target,dataGraph_);
>   assert(result.second == true);
>
boost::put(boost::get(edge_Datum,dataGraph_.root()),dataGraph_.local_to_glob
al(result.first),edgeDatum);
>   return result.first;
> }
>
> DataVertex
> DataGraph::add_vertex(LayoutVertex *pLayoutVertex)
> {
>   assert(pLayoutVertex > (LayoutVertex*)100);
>   DataVertex vertex = boost::add_vertex(dataGraph_);
>
boost::put(boost::get(vertex_Datum,dataGraph_.root()),dataGraph_.local_to_gl
obal(vertex),Vertex_Datum(pLayoutVertex));
>   return vertex;
> }
>
> DataVertex
> DataGraph::add_vertex(PseudoVertex *pPseudoVertex)
> {
>   assert(pPseudoVertex > (PseudoVertex*)100);
>   DataVertex vertex = boost::add_vertex(dataGraph_);
>
boost::put(boost::get(vertex_Datum,dataGraph_.root()),dataGraph_.local_to_gl
obal(vertex),Vertex_Datum(pPseudoVertex));
>   return vertex;
> }
>
> void
> DataGraph::remove_edge(DataEdge edge)
> {
>   boost::remove_edge(edge,dataGraph_);
> }
>
> void
> DataGraph::remove_vertex(DataVertex vertex)
> {
>   boost::remove_vertex(vertex,dataGraph_);
> }
> struct ltSubgraph : public std::binary_function<DataEdge,DataEdge,bool>
> {
>   bool operator() (const DataEdge& s1, const DataEdge& s2) const
>   {
>         return s1.m_source < s2.m_source || (!(s2.m_source < s1.m_source)
&& s1.m_target < s2.m_target);
>   }
> };
>
> typedef set<DataEdge,ltSubgraph> SetEdges;
>
> struct insert : public unary_function<SetEdges::value_type,void>
> {
>   insert(const DataGraphT& subGraph,SetEdges& container) :
subGraph_(subGraph),container_(container) {}
>   void operator() (const SetEdges::value_type& x)
>   {
>     container_.insert(subGraph_.local_to_global(x));
>   }
> public:
>   const DataGraphT& subGraph_;
>   SetEdges& container_;
> };
>
> struct InternalEdgeCantidate : public unary_function<DataEdge,bool>
> {
>   enum Edge_Type { in, out};
>   InternalEdgeCantidate(Edge_Type edge_type, DataGraphT& subGraph) :
edge_type_(edge_type),subGraph_(subGraph) {}
>   bool operator()(const DataEdge& x) const
>   {
>     return (edge_type_==in)  ?
!subGraph_.parent().find_vertex(x.m_source).second :
!subGraph_.parent().find_vertex(x.m_target).second;
>   }
> private:
>   Edge_Type edge_type_;
>   DataGraphT&  subGraph_;
> };
>
> /* Return the external Edges (using global descriptors) */
> void
> DataGraph::handleExternalEdges(DataGraph::Edges&
in_external_edges,DataGraph::Edges& out_external_edges)
> {
>   DataVertexIterator vi,vi_end;
>   {
>     SetEdges local_edges,global_edges;
>     for (tie(vi,vi_end)=boost::vertices(dataGraph_);vi!=vi_end;++vi) {
>       boost::graph_traits<DataGraphT>::in_edge_iterator ei, ei_end;
>           tie(ei,ei_end)=boost::in_edges(*vi,dataGraph_);
>       for_each(ei,ei_end,insert(dataGraph_,local_edges));
>
tie(ei,ei_end)=boost::in_edges(dataGraph_.local_to_global(*vi),dataGraph_.ro
ot());
>       for_each(ei,ei_end,insert(dataGraph_.root(),global_edges));
>     }
>
set_difference(global_edges.begin(),global_edges.end(),local_edges.begin(),l
ocal_edges.end(),insert_iterator<DataGraph::Edges>(in_external_edges,in_exte
rnal_edges.end()),ltSubgraph());
>
in_external_edges.erase(remove_if(in_external_edges.begin(),in_external_edge
s.end(),InternalEdgeCantidate(InternalEdgeCantidate::in,dataGraph_)),in_exte
rnal_edges.end());
>   }
>   {
>     SetEdges local_edges,global_edges;
>     for (tie(vi,vi_end)=boost::vertices(dataGraph_);vi!=vi_end;++vi) {
>       boost::graph_traits<DataGraphT>::out_edge_iterator ei, ei_end;
>           tie(ei,ei_end)=boost::out_edges(*vi,dataGraph_);
>       for_each(ei,ei_end,insert(dataGraph_,local_edges));
>
tie(ei,ei_end)=boost::out_edges(dataGraph_.local_to_global(*vi),dataGraph_.r
oot());
>       for_each(ei,ei_end,insert(dataGraph_.root(),global_edges));
>     }
>
set_difference(global_edges.begin(),global_edges.end(),local_edges.begin(),l
ocal_edges.end(),insert_iterator<DataGraph::Edges>(out_external_edges,out_ex
ternal_edges.end()),ltSubgraph());
>
out_external_edges.erase(remove_if(out_external_edges.begin(),out_external_e
dges.end(),InternalEdgeCantidate(InternalEdgeCantidate::out,dataGraph_)),out
_external_edges.end());
>   }
> }
>
> void
> DataGraph::handleParallelEdges(void)
> {
>   typedef multiset<DataEdge,ltSubgraph> Edges;
>   Edges edges;
>   boost::graph_traits<DataGraphT>::edge_iterator ei,ei_end;
>   for (tie(ei,ei_end)=boost::edges(dataGraph_);ei!=ei_end;++ei)
>     edges.insert(*ei);
>   for (Edges::const_iterator iter1 = edges.begin(); iter1 != edges.end();
advance(iter1,edges.count(*iter1)))
>     if (edges.count(*iter1)>1) {
>       Edge_Datum edgeDatum(new ParallelEdge());
>       for (Edges::const_iterator
iter2=edges.lower_bound(*iter1);iter2!=edges.upper_bound(*iter1);++iter2) {
>         Edge_Datum& existing_datum = getEdgeData()[*iter2];
>         existing_datum.setDeleted(true);
>
edgeDatum.setOmega(edgeDatum.getOmega()+existing_datum.getOmega());
>       }
>       add_edge(edgeDatum,iter1->m_source,iter1->m_target);
>     }
> }
>
> class back_edge_recorder : public boost::default_dfs_visitor
> {
> public:
>   back_edge_recorder(DataGraph& dataGraph)
>     : dataGraph_(dataGraph) {}
>   void back_edge(DataEdge e, const DataGraphT &)
>   {
>     dataGraph_.getEdgeData()[e].setReversed(true);
>   }
> private:
>   DataGraph& dataGraph_;
> };
>
> void
> DataGraph::markBackEdges(void)
> {
>   dfsVisitor(dataGraph_,back_edge_recorder(*this));
> }
>
> string
> DataGraph::label(DataVertex v)
> {
>   const LayoutVertex *pInterface;
>   if (!getVertexData()[v].isPseudo()) {
>     pInterface = getVertexData()[v].getLayoutInterface();
>     assert(pInterface  != NULL);
>         return pInterface->getLabel();
>   } else
>     return string();
> }
>
>
----------------------------------------------------------------------------
----
> #ifndef dataGraph_H
> #define dataGraph_H
> #include <set>
> #include <vector>
> #include <boost/graph/property_iter_range.hpp>
> #include "graphtype.h"
>
> class DataGraph
> {
> public:
>   typedef std::vector<DataEdge> Edges;
>   enum DescriptorType {local,global};
>   DataGraph(DataGraphT& dataGraph);
>   DataGraph(DataGraphT& dataGraph, const DataVertices& dataVertices);
>   // Graph Data accessor methods
>   struct VertexData
>   {
>     typedef boost::graph_property_iter_range
<DataGraphT,vertex_Datum_t>::iterator iterator;
>     typedef boost::graph_property_iter_range
<DataGraphT,vertex_Datum_t>::const_iterator const_iterator;
>     typedef Vertex_Datum value_type;
>
>     VertexData(DataGraphT& dataGraph);
>     iterator begin(void) {return
boost::get_property_iter_range(dataGraph_,vertex_Datum).first;}
>     const_iterator begin(void) const {return
boost::get_property_iter_range(const_cast<const
DataGraphT&>(dataGraph_),vertex_Datum).first;}
>     iterator end(void) {return
boost::get_property_iter_range(dataGraph_,vertex_Datum).second;}
>     const_iterator end(void) const {return
boost::get_property_iter_range(const_cast<const
DataGraphT&>(dataGraph_),vertex_Datum).second;}
>     Vertex_Datum& operator[] (const DataVertex& index);
>   private:
>     DataGraphT& dataGraph_;
>   };
>   struct EdgeData
>   {
>     typedef boost::graph_property_iter_range
<DataGraphT,edge_Datum_t>::iterator iterator;
>     typedef boost::graph_property_iter_range
<DataGraphT,edge_Datum_t>::const_iterator const_iterator;
>     typedef Edge_Datum value_type;
>     EdgeData(DataGraphT& subgraph);
>     iterator begin(void) {return
boost::get_property_iter_range(dataGraph_,edge_Datum).first;}
>     const_iterator begin(void) const {return
boost::get_property_iter_range(const_cast<const
DataGraphT&>(dataGraph_),edge_Datum).first;}
>     iterator end(void) {return
boost::get_property_iter_range(dataGraph_,edge_Datum).second;}
>     const_iterator end(void) const {return
boost::get_property_iter_range( const_cast<const
DataGraphT&>(dataGraph_),edge_Datum).second;}
>     Edge_Datum& operator[] (const DataEdge& index);
>   private:
>     DataGraphT& dataGraph_;
>   };
>   VertexData getVertexData(DescriptorType type = local) {return (type ==
local) ? VertexData(dataGraph_) : VertexData(dataGraph_.root());}
>   EdgeData getEdgeData(DescriptorType type = local) {return (type ==
local) ? EdgeData(dataGraph_) : EdgeData(dataGraph_.root());}
>   // access to held subgraph
>   DataGraphT& getGraph(void) {return dataGraph_;}
>
>   // Max/Min Rank Set manipulator methods.
>   typedef std::set<DataVertex> SameRank;
>   const SameRank& getMinRanks(void) const {return minRanks_;}
>   SameRank& getMinRanks(void) {return minRanks_;}
>   const SameRank& getMaxRanks(void) const {return maxRanks_;}
>   SameRank& getMaxRanks(void) {return maxRanks_;}
>
>   // graph mutator methods
>   DataEdge add_edge(LayoutEdge* pLayoutEdge,DataVertex source,DataVertex
target);
>   DataEdge add_edge(PseudoEdge* pPseudoEdge,DataVertex source,DataVertex
target);
>   DataEdge add_edge(const Edge_Datum& edgeDatum,DataVertex
source,DataVertex target);
>   DataVertex add_vertex(LayoutVertex *pLayoutVertex);
>   DataVertex add_vertex(PseudoVertex *pPseudoVertex);
>   void remove_edge(DataEdge edge);
>   void remove_vertex(DataVertex vertex);
>   void handleExternalEdges(DataGraph::Edges&
in_external_edges,DataGraph::Edges& out_external_edges);
>   void handleParallelEdges(void);
>   void markBackEdges(void);
>
> private:
>   std::string label(DataVertex v);
>   DataGraphT& dataGraph_;
>   SameRank  minRanks_;
>   SameRank  maxRanks_;
> };
>
> /*
>  * This should be a template that has overloaded operator() methods.
>  */
> struct FindViaInterface : std::unary_function<DataVertex,bool>
> {
>   FindViaInterface(DataGraph& dataGraph, const void *pPointer) :
dataGraph_(dataGraph),pPointer_(pPointer) {}
>   bool operator() (const DataVertex& x) const
>   {
>     if (dataGraph_.getVertexData(DataGraph::global)[x].isPseudo()) {
>       return
dataGraph_.getVertexData(DataGraph::global)[x].getPseudoInterface() ==
pPointer_;
>     } else
>       return
dataGraph_.getVertexData(DataGraph::global)[x].getLayoutInterface() ==
pPointer_;
> }
> private:
>   DataGraph& dataGraph_;
>   const void *pPointer_;
> };
>
> template< typename T1>
> struct IsPseudo : std::unary_function<typename T1::value_type,bool>
> {
>   bool operator()(typename T1::value_type& x) const
>   {
>     return x.isPseudo();
>   }
> };
>
> template< typename T1>
> struct IsDeleted : std::unary_function<typename T1::value_type,bool>
> {
>   bool operator()(typename T1::value_type& x) const
>   {
>     return x.isDeleted();
>   }
> };
>
> struct IsReversed :
std::unary_function<DataGraph::EdgeData::value_type,bool>
> {
>   bool operator()(DataGraph::EdgeData::value_type& x) const
>   {
>     return x.isReversed();
>   }
> };
>
> template< typename T1, typename T2>
> struct IsType : public std::unary_function<typename T1::value_type,bool>
> {
>   IsType(typename T2::type type) : type_(type) {}
>   bool operator() (typename T1::value_type x) const;
> private:
>   typename T2::type type_;
> };
>
> template<> inline bool
IsType<DataGraph::VertexData,PseudoVertex>::operator()(DataGraph::VertexData
::value_type x) const
> {
>   if (x.isPseudo())
>     return type_ == x.getPseudoInterface()->getType();
>   else
>     return false;
> }
>
> template<> inline bool
IsType<DataGraph::VertexData,LayoutVertex>::operator()(DataGraph::VertexData
::value_type x) const
> {
>   if (!x.isPseudo())
>     return type_ == x.getLayoutInterface()->getType();
>   else
>     return false;
> }
>
> template<> inline bool
IsType<DataGraph::EdgeData,PseudoEdge>::operator()(DataGraph::EdgeData::valu
e_type x) const
> {
>   if (x.isPseudo())
>     return type_ == x.getPseudoInterface()->getType();
>   else
>     return false;
> }
>
> template<> inline bool
IsType<DataGraph::EdgeData,LayoutEdge>::operator()(DataGraph::EdgeData::valu
e_type x) const
> {
>   if (!x.isPseudo())
>     return type_ == x.getLayoutInterface()->getType();
>   else
>     return false;
> }
>
> #endif
>
----------------------------------------------------------------------------
----
> _______________________________________________
> Boost-users mailing list
> Boost-users_at_[hidden]
> http://lists.boost.org/mailman/listinfo.cgi/boost-users

Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net