/*! \page graphs How to use graphs The primary data structures of HugoLib are the graph classes. They all provide a node list - edge list interface, i.e. they have functionalities to list the nodes and the edges of the graph as well as in incoming and outgoing edges of a given node. Each graph should meet the \ref ConstGraph concept. This concept does makes it possible to change the graph (i.e. it is not possible to add or delete edges or nodes). Most of the graph algorithms will run on these graphs. The graphs meeting the \ref ExtendableGraph concept allow node and edge addition. You can also "clear" (i.e. erase all edges and nodes) such a graph. In case of graphs meeting the full feature \ref ErasableGraph concept you can also erase individual edges and node in arbitrary order. The implemented graph structures are the following. \li \ref hugo::ListGraph "ListGraph" is the most versatile graph class. It meets the ErasableGraph concept and it also have some convenience features. \li \ref hugo::SmartGraph "SmartGraph" is a more memory efficient version of \ref hugo::ListGraph "ListGraph". The price of it is that it only meets the \ref ExtendableGraph concept, so you cannot delete individual edges or nodes. \li \ref hugo::SymListGraph "SymListGraph" and \ref hugo::SymSmartGraph "SymSmartGraph" classes are very similar to \ref hugo::ListGraph "ListGraph" and \ref hugo::SmartGraph "SmartGraph". The difference is that whenever you add a new edge to the graph, it actually adds a pair of oppositely directed edges. They are linked together so it is possible to access the counterpart of an edge. An even more important feature is that using these classes you can also attach data to the edges in such a way that the stored data are shared by the edge pairs. \li \ref hugo::FullGraph "FullGraph" implements a full graph. It is a \ref ConstGraph, so you cannot change the number of nodes once it is constructed. It is extremely memory efficient: it uses constant amount of memory independently from the number of the nodes of the graph. Of course, the size of the \ref maps "NodeMap"'s and \ref maps "EdgeMap"'s will depend on the number of nodes. \li \ref hugo::NodeSet "NodeSet" implements a graph with no edges. This class can be used as a base class of \ref hugo::EdgeSet "EdgeSet". \li \ref hugo::EdgeSet "EdgeSet" can be used to create a new graph on the edge set of another graph. The base graph can be an arbitrary graph and it is possible to attach several \ref hugo::EdgeSet "EdgeSet"'s to a base graph. \todo Don't we need SmartNodeSet and SmartEdgeSet? \todo Some cross-refs are wrong. \bug This file must be updated accordig to the new stile iterators. The graph structures itself can not store data attached to the edges and nodes. However they all provide \ref maps "map classes" to dynamically attach data the to graph components. The following program demonstrates the basic features of HugoLib's graph structures. \code #include #include using namespace hugo; int main() { typedef ListGraph Graph; \endcode ListGraph is one of HugoLib's graph classes. It is based on linked lists, therefore iterating throuh its edges and nodes is fast. \code typedef Graph::Edge Edge; typedef Graph::InEdgeIt InEdgeIt; typedef Graph::OutEdgeIt OutEdgeIt; typedef Graph::EdgeIt EdgeIt; typedef Graph::Node Node; typedef Graph::NodeIt NodeIt; Graph g; for (int i = 0; i < 3; i++) g.addNode(); for (NodeIt i(g); g.valid(i); g.next(i)) for (NodeIt j(g); g.valid(j); g.next(j)) if (i != j) g.addEdge(i, j); \endcode After some convenience typedefs we create a graph and add three nodes to it. Then we add edges to it to form a full graph. \code std::cout << "Nodes:"; for (NodeIt i(g); g.valid(i); g.next(i)) std::cout << " " << g.id(i); std::cout << std::endl; \endcode Here we iterate through all nodes of the graph. We use a constructor of the node iterator to initialize it to the first node. The next member function is used to step to the next node, and valid is used to check if we have passed the last one. \code std::cout << "Nodes:"; NodeIt n; for (g.first(n); n != INVALID; g.next(n)) std::cout << " " << g.id(n); std::cout << std::endl; \endcode Here you can see an alternative way to iterate through all nodes. Here we use a member function of the graph to initialize the node iterator to the first node of the graph. Using next on the iterator pointing to the last node invalidates the iterator i.e. sets its value to INVALID. Checking for this value is equivalent to using the valid member function. Both of the previous code fragments print out the same: \code Nodes: 2 1 0 \endcode \code std::cout << "Edges:"; for (EdgeIt i(g); g.valid(i); g.next(i)) std::cout << " (" << g.id(g.tail(i)) << "," << g.id(g.head(i)) << ")"; std::cout << std::endl; \endcode \code Edges: (0,2) (1,2) (0,1) (2,1) (1,0) (2,0) \endcode We can also iterate through all edges of the graph very similarly. The head and tail member functions can be used to access the endpoints of an edge. \code NodeIt first_node(g); std::cout << "Out-edges of node " << g.id(first_node) << ":"; for (OutEdgeIt i(g, first_node); g.valid(i); g.next(i)) std::cout << " (" << g.id(g.tail(i)) << "," << g.id(g.head(i)) << ")"; std::cout << std::endl; std::cout << "In-edges of node " << g.id(first_node) << ":"; for (InEdgeIt i(g, first_node); g.valid(i); g.next(i)) std::cout << " (" << g.id(g.tail(i)) << "," << g.id(g.head(i)) << ")"; std::cout << std::endl; \endcode \code Out-edges of node 2: (2,0) (2,1) In-edges of node 2: (0,2) (1,2) \endcode We can also iterate through the in and out-edges of a node. In the above example we print out the in and out-edges of the first node of the graph. \code Graph::EdgeMap m(g); for (EdgeIt e(g); g.valid(e); g.next(e)) m.set(e, 10 - g.id(e)); std::cout << "Id Edge Value" << std::endl; for (EdgeIt e(g); g.valid(e); g.next(e)) std::cout << g.id(e) << " (" << g.id(g.tail(e)) << "," << g.id(g.head(e)) << ") " << m[e] << std::endl; \endcode \code Id Edge Value 4 (0,2) 6 2 (1,2) 8 5 (0,1) 5 0 (2,1) 10 3 (1,0) 7 1 (2,0) 9 \endcode In generic graph optimization programming graphs are not containers rather incidence structures which are iterable in many ways. HugoLib introduces concepts that allow us to attach containers to graphs. These containers are called maps. In the example above we create an EdgeMap which assigns an int value to all edges of the graph. We use the set member function of the map to write values into the map and the operator[] to retrieve them. Here we used the maps provided by the ListGraph class, but you can also write your own maps. You can read more about using maps \ref maps "here". */