[BGL]: Iterating through internal properties of specific value
I have a BGL graph (adjacency_list). I use it to represent a tree, and so I have an internal vertex property of type enum representing the node type, ie ROOT, LEAF, INNER. Now, I would like a way to access only the leaves of a tree, preferrably through iterators. I can't think of any good way to accomplish this, except possibly by writing new iterator classes which would internally keep track of a property map and thus hide traversal of the non-leaf nodes from the code using the iterators. This seems like a cumbersome approach though, and I'm hoping there is a simpler way? Björn
Hi Björn,
Several ideas that may or may not be appropriate to the specifics of your
situation:
First an observation: your internal property ROOT,LEAF,INNER is actually
redundant information. Given a vertex descriptor, this information can be
deduced by examining the number of in and out edges. If ((some in edges) AND
(some out edges)) then INNER, if ((some in edges) AND (no out edges)) then
LEAF, if ((no in edges)) then ROOT. I've found that it's most convenient to
use bidirectionalS so that I can easily get at both in and out edge degrees
given a vertex desc.
You could iterate over all the vertices, examine the in and out degrees and
build an external multimap
I have a BGL graph (adjacency_list). I use it to represent a tree, and so I have an internal vertex property of type enum representing the node type, ie ROOT, LEAF, INNER.
Now, I would like a way to access only the leaves of a tree, preferrably through iterators. I can't think of any good way to accomplish this, except possibly by writing new iterator classes which would internally keep track of a property map and thus hide traversal of the non-leaf nodes from the code using the iterators. This seems like a cumbersome approach though, and I'm hoping there is a simpler way?
Björn
Another quick thought. If you know the role of a node in your tree a-priori,
that is you know that it's a root,inner,or leaf at the time you're actually
inserting the vertices/edges into the BGL graph, then I would go with the
external multimap solution and build that in parallel with building the
graph. Then as soon as the graph was built, you could directly get an
iterator on the multimap (using a simple predicate that returned an
multimap::iterator by type) where vertex_desc = (*iter).second. This saves
you three graph filter operations (maybe significant, maybe not?). Plusses:
higher performance, simple. Minuses: need to know roll of tree node
a-priori, changing the graphs vertex or edge sets invalidates external
multimap forcing you to rebuild it (requires at least one traversal of the
graph). I have something similar I need to figure out soon so any comments
on my proposed solutions would be instructive and appreciated.
- Chris
"Chris Russell"
Hi Björn, Several ideas that may or may not be appropriate to the specifics of your situation:
First an observation: your internal property ROOT,LEAF,INNER is actually redundant information. Given a vertex descriptor, this information can be deduced by examining the number of in and out edges. If ((some in edges) AND (some out edges)) then INNER, if ((some in edges) AND (no out edges)) then LEAF, if ((no in edges)) then ROOT. I've found that it's most convenient to use bidirectionalS so that I can easily get at both in and out edge degrees given a vertex desc.
You could iterate over all the vertices, examine the in and out degrees and build an external multimap
, and then iterate over the multimap by type predicate. OR, write three little predicates and use them to filter the graph? You could filter the graph by, for example PredicateLeafNode, and then get a vertex iterator on the filtered graph. I think this would do what you want with the existing BGL infrastructure. But maybe I'm missing something important here. - Chris
"Björn Lindberg"
wrote in message news:3D9059C8.AFD80D45@nada.kth.se... I have a BGL graph (adjacency_list). I use it to represent a tree, and so I have an internal vertex property of type enum representing the node type, ie ROOT, LEAF, INNER.
Now, I would like a way to access only the leaves of a tree, preferrably through iterators. I can't think of any good way to accomplish this, except possibly by writing new iterator classes which would internally keep track of a property map and thus hide traversal of the non-leaf nodes from the code using the iterators. This seems like a cumbersome approach though, and I'm hoping there is a simpler way?
Björn
Chris Russell wrote:
Hi Björn, Several ideas that may or may not be appropriate to the specifics of your situation:
First an observation: your internal property ROOT,LEAF,INNER is actually redundant information. Given a vertex descriptor, this information can be deduced by examining the number of in and out edges. If ((some in edges) AND (some out edges)) then INNER, if ((some in edges) AND (no out edges)) then LEAF, if ((no in edges)) then ROOT.
Yes, you're right. The node type property was an early design decision, and I didn't think of this at the time. Your approach is much better I think. Right now, I have to keep track of labeling the vertices correctly when I construct the graph. I don't think it is cheaper in terms of time either, since checking for in and out edges for all practical purposes (it is a binary tree) takes constant time. I think I'll write a predicate function for the vertex type based on edge counting, and then use that function in a functor for use in the filtered_graph adaptor Jeremy mentioned. Björn
If I understand you correctly, there's an adaptor called filtered_graph that does this. You create a predicate functor that returns true for a leaf (the functor will need to contain a handle to the property map) and then the filtered_graph adaptor will give you all the various graph iterators. You'll probably just want to use the vertex_iterator of the filtered_graph. On Tue, 24 Sep 2002, [iso-8859-1] Bj�rn Lindberg wrote: yg-boo> I have a BGL graph (adjacency_list). I use it to represent a tree, yg-boo> and so I have an internal vertex property of type enum yg-boo> representing the node type, ie ROOT, LEAF, INNER. yg-boo> yg-boo> Now, I would like a way to access only the leaves of a tree, yg-boo> preferrably through iterators. I can't think of any good way to yg-boo> accomplish this, except possibly by writing new iterator classes yg-boo> which would internally keep track of a property map and thus hide yg-boo> traversal of the non-leaf nodes from the code using the iterators. yg-boo> This seems like a cumbersome approach though, and I'm hoping there yg-boo> is a simpler way? yg-boo> yg-boo> yg-boo> Bj�rn ---------------------------------------------------------------------- Jeremy Siek http://php.indiana.edu/~jsiek/ Ph.D. Student, Indiana Univ. B'ton email: jsiek@osl.iu.edu C++ Booster (http://www.boost.org) office phone: (812) 855-3608 ----------------------------------------------------------------------
Jeremy Siek wrote:
If I understand you correctly, there's an adaptor called filtered_graph that does this. You create a predicate functor that returns true for a leaf (the functor will need to contain a handle to the property map) and then the filtered_graph adaptor will give you all the various graph iterators. You'll probably just want to use the vertex_iterator of the filtered_graph.
Ah yes, this sounds exactly like what I need. Thanks. Björn
participants (3)
-
Björn Lindberg
-
Chris Russell
-
Jeremy Siek