3 \page graphs How to use graphs
5 The primary data structures of HugoLib are the graph classes. They all
6 provide a node list - edge list interface, i.e. they have
7 functionalities to list the nodes and the edges of the graph as well
8 as in incoming and outgoing edges of a given node.
11 Each graph should meet the
12 \ref hugo::skeleton::StaticGraphSkeleton "StaticGraph" concept.
14 makes it possible to change the graph (i.e. it is not possible to add
15 or delete edges or nodes). Most of the graph algorithms will run on
18 The graphs meeting the
19 \ref hugo::skeleton::ExtendableGraphSkeleton "ExtendableGraph"
20 concept allow node and
21 edge addition. You can also "clear" (i.e. erase all edges and nodes)
24 In case of graphs meeting the full feature
25 \ref hugo::skeleton::ErasableGraphSkeleton "ErasableGraph"
27 you can also erase individual edges and node in arbitrary order.
29 The implemented graph structures are the following.
30 \li \ref hugo::ListGraph "ListGraph" is the most versatile graph class. It meets
31 the hugo::skeleton::ErasableGraphSkeleton "ErasableGraph" concept
32 and it also have some convenience features.
33 \li \ref hugo::SmartGraph "SmartGraph" is a more memory
34 efficient version of \ref hugo::ListGraph "ListGraph". The
35 price of it is that it only meets the
36 \ref hugo::skeleton::ExtendableGraphSkeleton "ExtendableGraph" concept,
37 so you cannot delete individual edges or nodes.
38 \li \ref hugo::SymListGraph "SymListGraph" and
39 \ref hugo::SymSmartGraph "SymSmartGraph" classes are very similar to
40 \ref hugo::ListGraph "ListGraph" and \ref hugo::SmartGraph "SmartGraph".
41 The difference is that whenever you add a
42 new edge to the graph, it actually adds a pair of oppositely directed edges.
43 They are linked together so it is possible to access the counterpart of an
44 edge. An even more important feature is that using these classes you can also
45 attach data to the edges in such a way that the stored data
46 are shared by the edge pairs.
47 \li \ref hugo::FullGraph "FullGraph"
48 implements a full graph. It is a \ref ConstGraph, so you cannot
49 change the number of nodes once it is constructed. It is extremely memory
50 efficient: it uses constant amount of memory independently from the number of
51 the nodes of the graph. Of course, the size of the \ref maps "NodeMap"'s and
52 \ref maps "EdgeMap"'s will depend on the number of nodes.
54 \li \ref hugo::NodeSet "NodeSet" implements a graph with no edges. This class
55 can be used as a base class of \ref hugo::EdgeSet "EdgeSet".
56 \li \ref hugo::EdgeSet "EdgeSet" can be used to create a new graph on
57 the node set of another graph. The base graph can be an arbitrary graph and it
58 is possible to attach several \ref hugo::EdgeSet "EdgeSet"'s to a base graph.
60 \todo Don't we need SmartNodeSet and SmartEdgeSet?
61 \todo Some cross-refs are wrong.
63 \bug This file must be updated accordig to the new style iterators.
65 The graph structures itself can not store data attached
66 to the edges and nodes. However they all provide
67 \ref maps "map classes"
68 to dynamically attach data the to graph components.
70 The following program demonstrates the basic features of HugoLib's graph
75 #include <hugo/list_graph.h>
81 typedef ListGraph Graph;
84 ListGraph is one of HugoLib's graph classes. It is based on linked lists,
85 therefore iterating throuh its edges and nodes is fast.
88 typedef Graph::Edge Edge;
89 typedef Graph::InEdgeIt InEdgeIt;
90 typedef Graph::OutEdgeIt OutEdgeIt;
91 typedef Graph::EdgeIt EdgeIt;
92 typedef Graph::Node Node;
93 typedef Graph::NodeIt NodeIt;
97 for (int i = 0; i < 3; i++)
100 for (NodeIt i(g); g.valid(i); g.next(i))
101 for (NodeIt j(g); g.valid(j); g.next(j))
102 if (i != j) g.addEdge(i, j);
105 After some convenience typedefs we create a graph and add three nodes to it.
106 Then we add edges to it to form a full graph.
109 std::cout << "Nodes:";
110 for (NodeIt i(g); g.valid(i); g.next(i))
111 std::cout << " " << g.id(i);
112 std::cout << std::endl;
115 Here we iterate through all nodes of the graph. We use a constructor of the
116 node iterator to initialize it to the first node. The next member function is
117 used to step to the next node, and valid is used to check if we have passed the
121 std::cout << "Nodes:";
123 for (g.first(n); n != INVALID; g.next(n))
124 std::cout << " " << g.id(n);
125 std::cout << std::endl;
128 Here you can see an alternative way to iterate through all nodes. Here we use a
129 member function of the graph to initialize the node iterator to the first node
130 of the graph. Using next on the iterator pointing to the last node invalidates
131 the iterator i.e. sets its value to INVALID. Checking for this value is
132 equivalent to using the valid member function.
134 Both of the previous code fragments print out the same:
141 std::cout << "Edges:";
142 for (EdgeIt i(g); g.valid(i); g.next(i))
143 std::cout << " (" << g.id(g.tail(i)) << "," << g.id(g.head(i)) << ")";
144 std::cout << std::endl;
148 Edges: (0,2) (1,2) (0,1) (2,1) (1,0) (2,0)
151 We can also iterate through all edges of the graph very similarly. The head and
152 tail member functions can be used to access the endpoints of an edge.
155 NodeIt first_node(g);
157 std::cout << "Out-edges of node " << g.id(first_node) << ":";
158 for (OutEdgeIt i(g, first_node); g.valid(i); g.next(i))
159 std::cout << " (" << g.id(g.tail(i)) << "," << g.id(g.head(i)) << ")";
160 std::cout << std::endl;
162 std::cout << "In-edges of node " << g.id(first_node) << ":";
163 for (InEdgeIt i(g, first_node); g.valid(i); g.next(i))
164 std::cout << " (" << g.id(g.tail(i)) << "," << g.id(g.head(i)) << ")";
165 std::cout << std::endl;
169 Out-edges of node 2: (2,0) (2,1)
170 In-edges of node 2: (0,2) (1,2)
173 We can also iterate through the in and out-edges of a node. In the above
174 example we print out the in and out-edges of the first node of the graph.
177 Graph::EdgeMap<int> m(g);
179 for (EdgeIt e(g); g.valid(e); g.next(e))
180 m.set(e, 10 - g.id(e));
182 std::cout << "Id Edge Value" << std::endl;
183 for (EdgeIt e(g); g.valid(e); g.next(e))
184 std::cout << g.id(e) << " (" << g.id(g.tail(e)) << "," << g.id(g.head(e))
185 << ") " << m[e] << std::endl;
198 As we mentioned above, graphs are not containers rather
199 incidence structures which are iterable in many ways. HugoLib introduces
200 concepts that allow us to attach containers to graphs. These containers are
203 In the example above we create an EdgeMap which assigns an int value to all
204 edges of the graph. We use the set member function of the map to write values
205 into the map and the operator[] to retrieve them.
207 Here we used the maps provided by the ListGraph class, but you can also write
208 your own maps. You can read more about using maps \ref maps "here".