Boost logo

Boost Users :

Subject: Re: [Boost-users] Boost Graph Library: edge retrieval using edge descriptor between square brackets fails
From: Cedric Laczny (cedric.laczny_at_[hidden])
Date: 2011-01-12 03:36:31


Hi,

it seems to me, that you are very well adding an edge, but forgetting to
insert its properties, that you want to retrieve.

Please s. code below.

On Wednesday, 12. January 2011 05:53:33 Nicholas Mario Wardhana wrote:
> Hi all,
>
> I am wrapping the Boost Graph Library with a thin class, and I am
> having a problem in retrieving the edge. I use a mechanism similar to
> the one in here:
>
> http://stackoverflow.com/questions/3100146/adding-custom-vertices-to-a-boos
> t-graph
>
> For testing, I add two vertices (suppose pNode1 and pNode2)
> successfully, and they can be retrieved as well by passing in their
> vertex descriptors. However, this is not the case for the edges: when
> I add an edge from pNode1 to pNode2, the edge is correctly stored as
> the out_edge of pNode1, but when I retrieve the edge using its edge
> descriptor, which is the (valid) return value of the add_edge()
> function, the pointer value is NULL. Also, when I debug the code, I
> find that inside the graph, there are two variables m_edges and
> m_vertices. The m_vertices correctly contains two vertex descriptors,
> but the m_edges is empty. So, do I make a mistake here? I have been
> looking for some information in Boost's archive and other sources
> (StackOverflow, ...), but so far haven't found anything helpful.
>
> I include a snippet at the end of this e-mail. I am using Visual
> Studio 2008 SP1 on Windows Vista SP2, and Boost 1.44.0 (haven't
> upgraded yet to 1.45, but the latter doesn't seem to address this
> issue).
>
> Thank you!
>
> Best regards,
> Nicholas Mario Wardhana
>
> //--------------------------- snippet -----------------------------
>
> template <class NodeData, class EdgeData>
> class BoostGraphWrapper : public Graph<NodeData, EdgeData>
> {
> typedef boost::adjacency_list<boost::listS, boost::listS,
> boost::directedS, Node<NodeData>*, Edge<NodeData, EdgeData>*,
> boost::listS> BoostGraph;
> typedef typename boost::graph_traits<BoostGraph>::vertex_descriptor
> BoostVertexDescriptor;
> typedef typename boost::graph_traits<BoostGraph>::edge_descriptor
> BoostEdgeDescriptor;
>
> //...
>
> public:
> void AddNode(Node<NodeData>* pNode);
> Edge<NodeData, EdgeData>* AddEdge(Node<NodeData>* pNode1,
> Node<NodeData>* pNode2);
>
> //...
>
> private:
> BoostGraph m_graph;
>
> //...
> };
>
> template <class NodeData, class EdgeData>
> void BoostGraphWrapper<NodeData, EdgeData>::AddNode(Node<NodeData>* pNode)
> {
> Graph<NodeData, EdgeData>::AddNode(pNode);
>
> // 1. Get the descriptor
> BoostVertexDescriptor vertexDescriptor = boost::add_vertex(m_graph);
>
> // 2. Fill with the node
> m_graph[vertexDescriptor] = pNode;

You correctly insert the properties of the node here.

>
> // ...
> }
>
> template <class NodeData, class EdgeData>
> Edge<NodeData, EdgeData>* BoostGraphWrapper<NodeData,
> EdgeData>::AddEdge( Node<NodeData>* pNode1, Node<NodeData>* pNode2 )
> {
> Graph<NodeData, EdgeData>::AddEdge(pNode1, pNode2);
>
> // 1. Get vertex descriptors of the nodes
> BoostVertexDescriptor vertexDescriptor1 =
> GetBoostVertexDescriptor(pNode1); BoostVertexDescriptor vertexDescriptor2
> = GetBoostVertexDescriptor(pNode2); Node<NodeData>* tempNode =
> m_graph[vertexDescriptor1];
> Node<NodeData>* tempNode2 = m_graph[vertexDescriptor2];
>
> // 2. Add an empty edge
> BoostEdgeDescriptor edgeDescriptor;
> bool inGraph = false;
> boost::tie(edgeDescriptor,inGraph) =
> boost::add_edge(vertexDescriptor1, vertexDescriptor2, m_graph);

You do add an edge, but this in the same as for vertices, it is only an edge
descriptor. There is no additional information (as the properties) associated
with it, yet.

> if(!inGraph)
> {
> return NULL;
> }
> assert(BoostEdgeSize() == 1); // successful
>
> // 3. Fill the edge with the vertices
> Edge<NodeData, EdgeData>* temp = m_graph[edgeDescriptor];

This information has not yet been set! I would expect the same as in AddNode()
here:
m_graph[edgeDescriptor] = pEdge;
Retrieving this information when first adding an edge is counter-intuitive.
Of course you need to pass pEdge as an argument to AddEdge().

> assert(NULL != temp); // fails here
>
> //....
>
> return pEdge;
> }
>
> void SomeFunction()
> {
> BoostGraphWrapper<int, int> graphWrapper;
> Node<int>* pNode1 = new Node<int>();
> Node<int>* pNode2 = new Node<int>();
> Edge<int, int>* pEdge;
>
> graphWrapper.AddNode(pNode1);
> graphWrapper.AddNode(pNode2);
>
> pEdge = graphWrapper.AddEdge(pNode2, pNode1); // fails here
> }
> _______________________________________________
> Boost-users mailing list
> Boost-users_at_[hidden]
> http://lists.boost.org/mailman/listinfo.cgi/boost-users

Hope that helps.
BTW, have you already thought about using vecS for the VertexList (instead of
listS)? It has the advantage of automatically creating vertex indices which
are crucial to most BGL algorithms.

Best,

Cedric


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