doc/graphs.dox
author deba
Wed, 08 Sep 2004 12:06:45 +0000
changeset 822 88226d9fe821
parent 756 c54cf1e83039
child 873 f3a30fda2e49
permissions -rw-r--r--
The MapFactories have been removed from the code because
if we use macros then they increases only the complexity.

The pair iterators of the maps are separeted from the maps.

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