# source:lemon-0.x/doc/graphs.dox@873:f3a30fda2e49

Last change on this file since 873:f3a30fda2e49 was 873:f3a30fda2e49, checked in by Alpar Juttner, 17 years ago
File size: 6.9 KB
Line
1/*!
2
3\page graphs How to use graphs
4
5The primary data structures of HugoLib are the graph classes. They all
6provide a node list - edge list interface, i.e. they have
7functionalities to list the nodes and the edges of the graph as well
8as in incoming and outgoing edges of a given node.
9
10
11Each graph should meet the
12\ref hugo::skeleton::StaticGraphSkeleton "StaticGraph" concept.
13This concept does not
14makes it possible to change the graph (i.e. it is not possible to add
15or delete edges or nodes). Most of the graph algorithms will run on
16these graphs.
17
18The graphs meeting the
19\ref hugo::skeleton::ExtendableGraphSkeleton "ExtendableGraph"
20concept allow node and
21edge addition. You can also "clear" (i.e. erase all edges and nodes)
22such a graph.
23
24In case of graphs meeting the full feature
25\ref hugo::skeleton::ErasableGraphSkeleton "ErasableGraph"
26concept
27you can also erase individual edges and node in arbitrary order.
28
29The implemented graph structures are the following.
30\li \ref hugo::ListGraph "ListGraph" is the most versatile graph class. It meets
31the hugo::skeleton::ErasableGraphSkeleton "ErasableGraph" concept
32and it also have some convenience features.
33\li \ref hugo::SmartGraph "SmartGraph" is a more memory
34efficient version of \ref hugo::ListGraph "ListGraph". The
35price of it is that it only meets the
36\ref hugo::skeleton::ExtendableGraphSkeleton "ExtendableGraph" concept,
37so 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".
41The difference is that whenever you add a
42new edge to the graph, it actually adds a pair of oppositely directed edges.
43They are linked together so it is possible to access the counterpart of an
44edge. An even more important feature is that using these classes you can also
45attach data to the edges in such a way that the stored data
46are shared by the edge pairs.
47\li \ref hugo::FullGraph "FullGraph"
48implements a full graph. It is a \ref ConstGraph, so you cannot
49change the number of nodes once it is constructed. It is extremely memory
50efficient: it uses constant amount of memory independently from the number of
51the 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.
53
54\li \ref hugo::NodeSet "NodeSet" implements a graph with no edges. This class
55can 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
57the node set of another graph. The base graph can be an arbitrary graph and it
58is possible to attach several \ref hugo::EdgeSet "EdgeSet"'s to a base graph.
59
60\todo Don't we need SmartNodeSet and SmartEdgeSet?
61\todo Some cross-refs are wrong.
62
63\bug This file must be updated accordig to the new style iterators.
64
65The graph structures itself can not store data attached
66to the edges and nodes. However they all provide
67\ref maps "map classes"
68to dynamically attach data the to graph components.
69
70The following program demonstrates the basic features of HugoLib's graph
71structures.
72
73\code
74#include <iostream>
75#include <hugo/list_graph.h>
76
77using namespace hugo;
78
79int main()
80{
81  typedef ListGraph Graph;
82\endcode
83
84ListGraph is one of HugoLib's graph classes. It is based on linked lists,
85therefore iterating throuh its edges and nodes is fast.
86
87\code
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;
94
95  Graph g;
96
97  for (int i = 0; i < 3; i++)
99
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);
103\endcode
104
105After some convenience typedefs we create a graph and add three nodes to it.
106Then we add edges to it to form a full graph.
107
108\code
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;
113\endcode
114
115Here we iterate through all nodes of the graph. We use a constructor of the
116node iterator to initialize it to the first node. The next member function is
117used to step to the next node, and valid is used to check if we have passed the
118last one.
119
120\code
121  std::cout << "Nodes:";
122  NodeIt n;
123  for (g.first(n); n != INVALID; g.next(n))
124    std::cout << " " << g.id(n);
125  std::cout << std::endl;
126\endcode
127
128Here you can see an alternative way to iterate through all nodes. Here we use a
129member function of the graph to initialize the node iterator to the first node
130of the graph. Using next on the iterator pointing to the last node invalidates
131the iterator i.e. sets its value to INVALID. Checking for this value is
132equivalent to using the valid member function.
133
134Both of the previous code fragments print out the same:
135
136\code
137Nodes: 2 1 0
138\endcode
139
140\code
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;
145\endcode
146
147\code
148Edges: (0,2) (1,2) (0,1) (2,1) (1,0) (2,0)
149\endcode
150
151We can also iterate through all edges of the graph very similarly. The head and
152tail member functions can be used to access the endpoints of an edge.
153
154\code
155  NodeIt first_node(g);
156
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;
161
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;
166\endcode
167
168\code
169Out-edges of node 2: (2,0) (2,1)
170In-edges of node 2: (0,2) (1,2)
171\endcode
172
173We can also iterate through the in and out-edges of a node. In the above
174example we print out the in and out-edges of the first node of the graph.
175
176\code
177  Graph::EdgeMap<int> m(g);
178
179  for (EdgeIt e(g); g.valid(e); g.next(e))
180    m.set(e, 10 - g.id(e));
181
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;
186\endcode
187
188\code
189Id Edge  Value
1904  (0,2) 6
1912  (1,2) 8
1925  (0,1) 5
1930  (2,1) 10
1943  (1,0) 7
1951  (2,0) 9
196\endcode
197
198As we mentioned above, graphs are not containers rather
199incidence structures which are iterable in many ways. HugoLib introduces
200concepts that allow us to attach containers to graphs. These containers are
201called maps.
202
203In the example above we create an EdgeMap which assigns an int value to all
204edges of the graph. We use the set member function of the map to write values
205into the map and the operator[] to retrieve them.
206
207Here we used the maps provided by the ListGraph class, but you can also write