I\'m trying to decide between going with a pre-made graph/node network library or to roll my own.
I\'m implementing some graph search algorithms which might require
Before deciding to build your own graph library, I would have a good look at igraph (http://igraph.sourceforge.net/). It is written in C and is extremely fast and offers a wider range of basic and advanced graph algorithms (including visualization). In addition, it has a python wrapper for fast coding so I think this solution combines speed of coding and speed of execution.
You may also take a try with LEMON graph library.
I could use it to perform Dijsktra shortest path search after reading the graph from a configuration file.
A new version has just come out.
“require some significant customization to the class structure of the node and/or edges.”
Have you looked at the “bundled properties” feature of the BGL?
http://www.boost.org/doc/libs/1_40_0/libs/graph/doc/bundles.html
This is both powerful and not the least bit acrcane.
You define a classes for your edges and your vertices
class cMyVertex
{
…
};
class cMyEdge
{
…
};
Now you define a graph type which will use your classes
typedef boost::adjacency_list<
boost::listS, boost::vecS, boost::bidirectionalS,
cMyVertex, cMyEdge > graph_t;
Now you can create graphs of this type that will use your classes, whatever they are, for the vertices and edges.
You can access the attributes and methods of your classes in a perfectly natural way
Graph_t g(10) // create a graph with 10 vertices
g[1].setA1( “alpha” ); // invoke an accessor on node #1
I use the BGL very much, but what disturbs me with BGL is the lack of basic algorithms like edge and vertex connectivity, min cost flow and, general maximum weight perfect matching, just to name those which I miss the most.
LEMON offers all of that and also has a simpler syntax, what bugs me with LEMON is the installation and compilation problems on WINDOWS platforms, but I will probably switch to LEMON despite those problems.
I think if you can leverage the graph traversal algorithms, it is worth using the Boost Graph. Creating and using custom vertices is pretty easy. The examples included with BGL were useful for learning how to use it.
I agree with Clifford, I've used GraphViz to help visualize the graph during development and found it very useful.
I can perhaps provide a little guidance on the BGL.
The library is very flexible. The cost of this is that the syntax can be very baroque, in order to accommodate all the possibilities. However, it is sufficiently flexible that simple things can be done simply.
Unfortunately the boost documentation goes at things full tilt, providing a description only of the full complexity, without a hint of how simple things can be.
( "Any sufficiently advanced technology is indistinguishable from magic" - Arthur C. Clarke. What he should have said is "Any advanced technology, sufficiently badly documented, is indistinguishable from magic )
Consider:
typedef property_map<Graph, vertex_index_t>::type IndexMap;
IndexMap index = get(vertex_index, g);
typedef graph_traits<Graph>::vertex_iterator vertex_iter;
std::pair<vertex_iter, vertex_iter> vp;
for (vp = vertices(g); vp.first != vp.second; ++vp.first) {
std::cout << index[*vp.first] << " ";
}
This is how the "quick tour" suggests we print out a list of the graph vertices. However, a little study shows that a vertex is no more than an integer index, and the code can be greatly simplified to
for (int v = *vertices(g).first; v != *vertices(g).second; ++v)
std::cout << v << " ";
Perhaps there are some magical things that cannot be achieved with this simplified code, but for every day use it reasonable to drastically prune the syntax that encrust BGL so you can see what your are coding.
Sometimes the elaborate syntax cannot be removed. ( Or perhaps I have just not noticed the underlying truth ). Then I usually use a little utility function to encapsulate the complexity abd keep it away from the algorithm I am working on.
For example, I often need to loop over the children of a vertex
vector<int> getVertexChildren( int v )
{
vector<int> vc;
typedef std::pair<graph_traits<graph_t>::out_edge_iterator, graph_traits<graph_t>::out_edge_iterator> out_edge_iter_pair_t;
for( out_edge_iter_pair_t ep = out_edges(v,m_tree);
ep.first != ep.second; ++(ep.first))
{
vc.push_back( target( *ep.first, m_tree ) );
}
return vc;
}
#define FOR_ALL_CHILDREN( v ) vector<int> vc=getVertexChildren(v); BOOST_FOR_EACH( int child, vc )
The bottom line is: go ahead and use BGL. It can be simplified to do simple things, but once you have learned to use it, all the immense flexibility will be available whenever you do need it.