How to fit a custom graph to the boost graph library template? - c++

I'm rusty on C++ templates and I'm using the boost graph library (a fatal combination). I've searched the web and can't find any direct instructions on how to take a custom graph structure and fit enough of it to BGL (boost graph library) that I can use boosts graph traversing algorithms. Anyone familiar enough with the library to help me out?
EDIT: So, the main problem I've been having is where to find a source where the total requirements to map an arbitrary graph to a BGL graph. I'm really new to templates so it's hard for me to read BGL's specification/examples. Maybe I should look for a general source on templates?

My suggestion would be to abandon use of BGL entirely unless you already have a significant amount of code written on top of it. I was testing it out recently for future use on a large graph analysis project, and I found it to be almost unusable due to an overly complex and poorly designed API.
There are no simple tasks in BGL, only complex ones, and I was constantly fighting the compiler due to the excessively complicated template hierarchy that BGL has. Little to no useful documentation (at least not where it's really needed) and not enough examples only aggravate matters. That's no way to write code.
I'd recommend switching to LEMON. It's stable, written in C++, easy-to-understand and code in, offers several specialized forms of graphs to support different usage needs, and it supports both BFS and DFS search/visitor functions. It also has its own equivalent of property maps for nodes/edges, so you should be able to fit your own graph structure and other data onto it.
Try LEMON; it tastes a lot better and will cause fewer ulcers. ;-)

The approach, as I understand it, is to specialize the boost::graph_traits structure for your graph type. This configures BGL with various important properties it needs to know about your graph. You then specialize global template functions for your graph's specialized type of graph_traits to implement whatever boost graph interfaces might apply to your specific kind of graph.
An example is right there in the BGL documentation:
http://www.boost.org/doc/libs/1_43_0/libs/graph/doc/leda_conversion.html
There are links for several of the different interfaces there, which indicate which global template functions you'll need to specialize for your graph if you want to support that interface. The full list of interfaces is here:
http://www.boost.org/doc/libs/1_43_0/libs/graph/doc/graph_concepts.html

Related

Designing around bundled properties in the Boost Graph Library

I am porting some graph code out of Python (networkx) and into C++ (BGL). In my Python code, the vertices and edges of the graph are client-defined objects implementing an established interface; I go on to call a bunch of methods on them. Everything is fine.
Naively, it would seem that BGL is meant to support a similar design pattern with "bundled properties." These basically allow one to define custom types for the vertices and edges by passing certain template parameters:
adjacency_list<OutEdgeList, VertexList,
Directed, VertexProperties,
EdgeProperties, GraphProperties,
EdgeList>
The custom vertex and edge types here are given by VertexProperties and EdgeProperties.
In working on this port I've noticed a couple of things that make me think that maybe BGL's bundled properties interface is really only meant to support (more-or-less) immutable types:
Edge and vertex "descriptors"
If you put something into the graph, you get back a "descriptor" that you have to use to reference it from there on. There are descriptors for edges and vertices, and they are the "keys" -- implemented as immutables -- to the graph. So if you have a vertex and you want to find neighboring vertices, you have to (a) get the current vertex descriptor, (b) use BGL methods to find the descriptors of its neighbors, and finally (c) reference each of the neighbors via their respective descriptors.
The net result of all this bookkeeping is an apparent need for additional containers -- std::map, say -- to provide reverse-lookup from vertices and edges (again, types VertexProperty and EdgeProperty) to their descriptors.
"BGL isn't meant to store pointers."
I spotted this claim in a similar SO question but haven't been able to verify it in the Boost docs anywhere. From the ensuing discussion I am left to speculate that the constraint may actually be a bit stronger: "BGL isn't meant to directly reference the heap." This doesn't seem entirely reasonable, though, as the container types are configurable (OutEdgeList and VertexList, above) and default standard things like vectors.
I'm a BGL n00b and am having trouble understanding what's intended with bundled properties. (And, frankly, I feel a bit overwhelmed by the programming model in general -- "properties", "concepts", "traits", "descriptors", AHHHH!) Questions:
Do BGL graphs efficiently support complex and possibly heap-bound types for VertexProperty and EdgeProperty? Or are these meant to be lightweight containers for immutable data?
If the former, is there any way to get around all the descriptor bookkeeping?
If the latter, what's the "right way" to deal with large, complicated things that we might want to stick in a BGL graph?
Do BGL graphs efficiently support complex and possibly heap-bound types for VertexProperty and EdgeProperty? Or are these meant to be lightweight containers for immutable data?
Of course. You can do it anyway you want. Point in case: you could make the bundle hold an (immutable or mutable) pointer to a heap allocated "complex" type that is - of course - entirely mutable. Now,
I'd suggest using your preferred ownership adaptor (unique_ptr, scoped_ptr, shared_ptr, what not). Look at std::string: it too is "heap based", but you didn't ever worry about using it in a property bundle, did you?
If the former, is there any way to get around all the descriptor bookkeeping?
There is not strictly any "descriptor bookkeeping". There might be depending on the graph model. But in general, descriptor is really an abstraction of the underlying container iterator model (not that this could be iterators across multiple containers, e.g. the edges(EdgeListgraph) as opposed to out_edges(v, IncidenceGraph) for adjacency_list<>.
The point is to decouple the logic from assumptions about the storage model. Even with some pretty unsightly void* passing-around, the compiler should compile it down to the same code as direct iterator access. In this sense the "bookkeeping" is usually perceptual, and you are likely picking up on mental load of having the extra conceptual layer.
If the latter, what's the "right way" to deal with large, complicated things that we might want to stick in a BGL graph?
Oops. I think I accidentally addressed this under 1. The absolute simplest thing to use might be refcounted sharing. Your specific situation might allow for more efficient solutions.
CAPITA SELECTA
"BGL isn't meant to store pointers."
Well, not as bundles, perhaps. Even here, it depends solely on how you manage the ownership/lifetime of the pointees.
I think the linked answer is excellent. It resonates with what I said above.
So if you have a vertex and you want to find neighboring vertices, you have to (a) get the current vertex descriptor, (b) use BGL methods to find the descriptors of its neighbors, and finally (c) reference each of the neighbors via their respective descriptors.
Most BGL algorithms rely on the presence of vertex_index_t property (or require one to be specified as a parameter) to make sure these are low-cost operations. In fact, if you use vecS then the vertex index is the index into the vertex vector, so reverse and forward lookups are pretty simple. (You can always look at the generated assembly with optimizations enabled to see whether there are any surprises).
This answer might be inspirational: Boost Graph Library: possible to combine Bundled Properties with Interior Properties?
TL;DR / Summary
I have a feeling coming from Python you might be understandably underestimating C++ optimizing compilers in template-heavy generic library code.
What bubbles up when you sift through the layers of generic machinery in practice evaporates at compile time. Of course, the downside of this is that can be hard to see through the abstractions. But it also means that power and abstraction level aren't compromised.
BGL is one library that allows you to switch to radically different graph models, storage layout etc. with very few code changes. The goal here wasn't "ease of use" or "do what I mean" (use Java or python for that).
The goal was to make the choice for C++ /not/ remove all agility by hard-coding every single implementation detail into your entire code base. Instead, work at the level of library concepts and benefit from the freedom you retain to experiment/change your approach as requirements evolve.

C/C++ graph interface for representation of partial order

In my code I use a class which represents a directed acyclic graph. I wrote the code myself, it wasn't hard. But later I realized my app has more requirements: the graph must be transitive-reduced, i.e. unique representation of a partial ordrer. Every time the user does drag-n-drop or cut/copy/paste on the visual GUI representation of the graph, it has to be validated and adapted to this requirement. Now things become more complicated. So I did plan how to perform all graph operations safely, etc., but before I really dive into the code, I'd like to know:
Is there a known C/C++ interface for partial orders? (Preferably C++)
I found many many libraries for graphs, but I already have my simple acyclic digraph code. I couldn't find anything which deals specifically with transitively-reduced graphs (I don't need an adjacency matrix, the data comes from the user so it would be inefficient here... It's a small graph for user data, not something for mathematical use)
I'm looking for an interface which automatically detects unnecessary connections and removes them, does tests to see if a node copy/move operation would be valid partial-order-wise, i.e. preserve the properties of a partial order, etc.
I would recommend adding a partial-order validation method. When an edit is being made, make a copy of the whole graph apply the edit to one copy, then validate it. If it passes, keep the modified copy. If it doesn't pass, revert to the saved copy.
Perhaps the validator could find all bottom nodes, for each one, build a multiset of its ancestors (or descendants if you call them that) and check for duplicate entries. I would revert to recursion for the search if you expect only small graphs.
As far as I know, usually programs have their own graph classes when used for non-mathematical purposes. This happens because graphs may be much more complicated than linear containers such as the STL containers (vector, list, etc.).
Since you don't have any special needs in the field of math or algorithms (a search algorithm in your case would be a simple loop, in most cases you don't need more than that, and certainly not in the case of (premature) optimization). If you do, you have boost::graph, but I suspect it would complicate things more than help you.
So I say, write a good graph/node class, and if it's good enough and written for general-purpose, we can all benefit from that. Nobody is answering the question because there's really no existing public code which matches your needs. Write good libre code once, and it can then be used everywhere. Good luck.
P.S your own search algorithm may be much faster than ones written for general-purpose graph libraries, e.g. boost::graph, because you can take an advantage of the known restrictions and rules of you specific graph, thus making seraches much faster. For example, in a transitively-reduced graph, if A is a parent of B, then A cannot also have b as a non-child decendant (e.g. grand-child), so you can optimize your search using this knowledge. The price you pay is doing lots of tests when changing the graph, but you gain a lot back because searching/scanning can become much faster.

Performance of Graphviz

How fast is Graphiz? I want to implement a profiler which keeps track of threads state. I want to build and visualize waits-for graphs in real time (!).
Is this even possible? Would Graphviz be the appropriate match?
Otherwise, are there alternative for C++?
I would not use Graphviz because it is designed for creating graphical visualization of graph structures. Instead, might I suggest using the Boost Graph Library? While I have not used it personally, the Boost libraries are well respected, and it seems to be everywhere when I try to look for graphs in c++. I think that you will find the boost implementation will meet your needs.

Can I implement potential field/depth first method for obstacle avoidance using boost graph?

I implemented an obstacle avoidance algorithm in Matlab which assigns every node in a graph a potential and tries to descend this potential (the goal of the pathplanning is in the global minimum). Now there might appear local minima, so the (global) planning needs a way to get out of these. I used the strategy to have a list of open nodes which are reachable from the already visited nodes. I visit the open node which has the smallest potential next.
I want to implement this in C++ and I am wondering if Boost Graph has such algorithms already. If not - is there any benefit from using this library if I have to write the algorithm myself and I will also have to create my own graph class because the graph is too big to be stored as adjacency list/edge list in memory.
Any advice appreciated!
boost::graph provides a list of Shortest Paths / Cost Minimization Algorithms. You might be interested in the followings: Dijkstra Shortest path, A*.
The algorithms can be easily customized. If that doesn't exactly fit your needs, take a look at the visitor concepts. It allows you to customize your algorithm at some predefined event point.
Finally Distributed BGL handles huge graph (potentially millions of nodes). It will work for you if your graph does not fit in memory.
You can find good overview of the Boost Graph Library here.
And of course, do not hesitate to ask more specific question about BGL on stackoverflow.
To my mind, boost::graph is really awesome for implementing new algorithms, because it provides various data holders, adaptors and commonly used stuff (which can obviously be used as parts of the newly constructed algorithms).
Last ones are also customizable due to usage of visitors and other smart patterns.
Actually, boost::graph may take some time to get used to, but in my opinion it's really worth it.

Methods for implementing and using graphs of nodes in C++?

I am working on a research project that deals with social networks. I have done most of the backbone of the program in C++ and am now wanting to implement a way to create the graph of nodes and the connections as well as a way to visualize the connections between people. I have looked a little into Lemon and the Boost graph library, but was wondering which one would be easier to learn and implement or if I should just code my own.
If you use the BGL then you should also be able to make use of the Graph Toolkit for Algorithms and Drawings (GTAD). The GTAD is meant to be compatible with BGL and adds a number of graph algorithms not in BGL as well as algorithms for layouts.
For visualization the BGL allows you to read and write some common graph file types such as GraphML and Dot for use with GraphViz.
Lemon looks to be a well featured library with a good array of algorithms. You can also use gLemon to view Lemon graphs. This visualizer looks quite basic though and was last updated in 2008, unlike Lemon which is still under development.
I would suggest you first work out what you want to do with any graphs you create, ie what algorithms you require (shortest-path etc) and compare the two libraries from that respect.
Also take a look at the tutorials for both. They have very good documentation and should help you decide which you'll find easier to implement.
Unless you really want to get into the details of how certain graph structures and algorithms are implemented I would use a library.