basics.dox
author Peter Kovacs <kpeter@inf.elte.hu>
Sun, 14 Feb 2010 22:19:50 +0100
changeset 27 b453a59230c8
parent 26 a40eafb6066d
child 28 42b0128ae0a7
permissions -rw-r--r--
Rework and extend the section of basic concepts
alpar@21
     1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
alpar@21
     2
 *
alpar@21
     3
 * This file is a part of LEMON, a generic C++ optimization library.
alpar@21
     4
 *
alpar@21
     5
 * Copyright (C) 2003-2009
alpar@21
     6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
alpar@21
     7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
alpar@21
     8
 *
alpar@21
     9
 * Permission to use, modify and distribute this software is granted
alpar@21
    10
 * provided that this copyright notice appears in all copies. For
alpar@21
    11
 * precise terms see the accompanying LICENSE file.
alpar@21
    12
 *
alpar@21
    13
 * This software is provided "AS IS" with no warranty of any kind,
alpar@21
    14
 * express or implied, and with no claim as to its suitability for any
alpar@21
    15
 * purpose.
alpar@21
    16
 *
alpar@21
    17
 */
alpar@21
    18
alpar@21
    19
namespace lemon {
alpar@21
    20
/**
kpeter@26
    21
[PAGE]sec_basics[PAGE] Basic Concepts
alpar@21
    22
kpeter@27
    23
Throughout the tutorial we are working with the \ref lemon namespace.
kpeter@27
    24
To save a lot of typing, we assume that a
alpar@21
    25
alpar@21
    26
\code
alpar@21
    27
using namespace lemon;
alpar@21
    28
\endcode
alpar@21
    29
alpar@21
    30
directive is added to the code at the beginning.
alpar@21
    31
kpeter@26
    32
[SEC]sec_digraphs[SEC] Directed Graphs
alpar@21
    33
kpeter@27
    34
This section tells you how to work with a directed graph (\e digraph,
kpeter@27
    35
for short) in LEMON.
kpeter@27
    36
The library provides various digraph structures for both general and special
kpeter@27
    37
purposes. Here we use \c ListDigraph, the most versatile digraph type.
alpar@21
    38
kpeter@27
    39
The nodes and the arcs of a graph are identified by two data types called
kpeter@27
    40
\ref concepts::Digraph::Node "ListDigraph::Node" and \ref concepts::Digraph::Arc
kpeter@27
    41
"ListDigraph::Arc". You can add new items to the graph using the member
kpeter@27
    42
functions \ref ListDigraph::addNode() "addNode()" and
kpeter@27
    43
\ref ListDigraph::addArc() "addArc()", like this:
alpar@21
    44
alpar@21
    45
\code
alpar@21
    46
  ListDigraph g;
alpar@21
    47
  ListDigraph::Node a = g.addNode();
alpar@21
    48
  ListDigraph::Node b = g.addNode();
alpar@21
    49
  ListDigraph::Node c = g.addNode();
alpar@21
    50
  ListDigraph::Node d = g.addNode();
alpar@21
    51
alpar@21
    52
  g.addArc(a,b);
alpar@21
    53
  g.addArc(b,c);
alpar@21
    54
  g.addArc(c,d);
alpar@21
    55
  g.addArc(d,a);
alpar@21
    56
\endcode
alpar@21
    57
alpar@21
    58
Of course, \ref ListDigraph::addArc() "addArc()" also returns the created arc:
alpar@21
    59
alpar@21
    60
\code
kpeter@27
    61
  ListDigraph::Arc arc = g.addArc(a,c);
alpar@21
    62
\endcode
alpar@21
    63
kpeter@27
    64
\note Using ListDigraph, you can also remove nodes or arcs with the
kpeter@27
    65
\ref ListDigraph::erase() "erase()" function.
kpeter@27
    66
However, not all graph structures support the addition and deletion
kpeter@27
    67
of graph items.
alpar@21
    68
kpeter@27
    69
Two important member functions of the directed graphs are
alpar@21
    70
\ref concepts::Digraph::source() "source()"
alpar@21
    71
and \ref concepts::Digraph::target() "target()".
kpeter@27
    72
They give back the two end nodes of an arc.
alpar@21
    73
alpar@21
    74
\code
kpeter@27
    75
  if (g.source(arc) == g.target(arc))
alpar@21
    76
    std::cout << "This is a loop arc" << std::endl;
alpar@21
    77
\endcode
alpar@21
    78
kpeter@27
    79
Each graph item has a unique integer identifier, which can be obtained using
kpeter@27
    80
the \ref concepts::Digraph::id() "id()" function of the graph structure.
kpeter@27
    81
kpeter@27
    82
\code
kpeter@27
    83
  std::cout << "Arc " << g.id(arc) << " goes from node "
kpeter@27
    84
    << g.id(g.source(arc)) << " to node " << g.id(g.target(arc)) << std::endl;
kpeter@27
    85
\endcode
kpeter@27
    86
kpeter@27
    87
\note In fact, the \c Node and \c Arc types are typically simple wrapper
kpeter@27
    88
classes for a single \c int value, which is the identifier of the item.
kpeter@27
    89
kpeter@26
    90
kpeter@26
    91
[SEC]sec_digraph_it[SEC] Iterators
alpar@21
    92
kpeter@27
    93
Let us assume you want to list the elements of the graph. For this purpose,
kpeter@27
    94
the graph structures provide several iterators. For example, the following
kpeter@27
    95
code will count the number of nodes in a graph.
alpar@21
    96
alpar@21
    97
\code
alpar@21
    98
  int cnt = 0;
kpeter@27
    99
  for (ListDigraph::NodeIt n(g); n != INVALID; ++n)
alpar@21
   100
    cnt++;
alpar@21
   101
  std::cout << "Number of nodes: " << cnt << std::endl;
alpar@21
   102
\endcode
alpar@21
   103
alpar@21
   104
Here \ref concepts::Digraph::NodeIt "ListDigraph::NodeIt"
kpeter@27
   105
is an iterator class that traverses the
kpeter@27
   106
nodes. You must give the graph to the constructor and the iterator will be set
alpar@21
   107
to the first node. The next node is obtained by the prefix ++
kpeter@27
   108
operator. If there are no more nodes in the graph, the iterator will
alpar@21
   109
be set to \ref INVALID.
alpar@21
   110
kpeter@27
   111
\note \ref INVALID is a global constant, which converts to
kpeter@27
   112
and compares with each and every iterator in LEMON.
alpar@21
   113
kpeter@27
   114
The iterators convert to the corresponding item types. For example,
alpar@21
   115
to following code will add a full graph to the existing nodes.
alpar@21
   116
alpar@21
   117
\code
kpeter@27
   118
  for (ListDigraph::NodeIt u(g); u != INVALID; ++u)
kpeter@27
   119
    for (ListDigraph::NodeIt v(g); v != INVALID; ++v)
kpeter@27
   120
      if (u != v) g.addArc(u, v);
alpar@21
   121
\endcode
alpar@21
   122
kpeter@27
   123
\note Contrary to the iterators in the C++ Standard Template Library (STL),
kpeter@27
   124
LEMON iterators are convertible to the corresponding
kpeter@27
   125
item types without having to use \c %operator*(). This is not confusing, since the
kpeter@27
   126
program context always indicates whether we refer to the iterator or to the graph
kpeter@27
   127
item (they do not have conflicting functionalities).
kpeter@27
   128
kpeter@27
   129
The graph items are also ordered by the 'less than' operator (with respect to
kpeter@27
   130
their integer identifiers). For example, this code will add only one of the
kpeter@27
   131
opposite arcs.
alpar@21
   132
alpar@21
   133
\code
kpeter@27
   134
  for (ListDigraph::NodeIt u(g); u != INVALID; ++u)
kpeter@27
   135
    for (ListDigraph::NodeIt v(g); v != INVALID; ++v)
kpeter@27
   136
      if (u < v) g.addArc(u, v);
alpar@21
   137
\endcode
alpar@21
   138
kpeter@27
   139
\warning The order in which the iterators visit the items is
alpar@21
   140
undefined. The only thing you may assume that they will list the items
alpar@21
   141
in the same order until the graph is not changed.
alpar@21
   142
alpar@21
   143
Similarly, \ref concepts::Digraph::ArcIt "ListDigraph::ArcIt"
alpar@21
   144
lists the arcs. Its usage is the same as of
alpar@21
   145
\ref concepts::Digraph::NodeIt "ListDigraph::NodeIt".
alpar@21
   146
alpar@21
   147
\code
alpar@21
   148
  int cnt = 0;
kpeter@27
   149
  for (ListDigraph::ArcIt a(g); a != INVALID; ++a)
alpar@21
   150
    cnt++;
alpar@21
   151
  std::cout << "Number of arcs: " << cnt << std::endl;
alpar@21
   152
\endcode
alpar@21
   153
alpar@21
   154
Finally, you can also list the arcs starting from or arriving at a
alpar@21
   155
certain node with 
alpar@21
   156
\ref concepts::Digraph::OutArcIt "ListDigraph::OutArcIt"
alpar@21
   157
and
alpar@21
   158
\ref concepts::Digraph::InArcIt "ListDigraph::InArcIt".
kpeter@27
   159
Their usage is the same, but you must also give the node to the constructor.
alpar@21
   160
alpar@21
   161
\code
alpar@21
   162
  int cnt = 0;
kpeter@27
   163
  for (ListDigraph::OutArcIt a(g, start); a != INVALID; ++a)
alpar@21
   164
    cnt++;
alpar@21
   165
  std::cout << "Number of arcs leaving the node 'start': " << cnt << std::endl;
alpar@21
   166
\endcode
alpar@21
   167
kpeter@26
   168
kpeter@26
   169
[SEC]sec_digraph_maps[SEC] Maps
alpar@21
   170
kpeter@27
   171
The concept of "maps" is another fundamental part of LEMON. They allow assigning
kpeter@27
   172
values of any type to the nodes or arcs of a graph. The standard maps
alpar@21
   173
provided by the graph structures have a couple of nice properties.
alpar@21
   174
kpeter@27
   175
- \e Fast. Accessing (reading/writing) the values is as fast as a
kpeter@27
   176
  simple vector reading/writing.
alpar@21
   177
- \e Dynamic. Whenever you need, you
alpar@21
   178
  can allocate new maps in your code, just as a local variable. So when you
alpar@21
   179
  leave its scope, it will be de-allocated automatically.
alpar@21
   180
- \e Automatic. If you add new nodes or arcs to the graph, the storage of the
alpar@21
   181
  existing maps will automatically expanded and the new slots will be
alpar@21
   182
  initialized. On the removal of an item, the corresponding values in the maps
alpar@21
   183
  are properly destructed.
alpar@21
   184
kpeter@27
   185
\note These maps must not be confused with \c std::map, since they provide
kpeter@27
   186
O(1) time acces to the elements instead of O(log n).
kpeter@27
   187
alpar@21
   188
So, if you want to assign \c int values to each node, you have to allocate a
kpeter@27
   189
\ref concepts::Digraph::NodeMap "NodeMap<int>".
alpar@21
   190
alpar@21
   191
\code
alpar@21
   192
  ListDigraph::NodeMap<int> map(g);
alpar@21
   193
\endcode
alpar@21
   194
alpar@21
   195
As you see, the graph you want to assign a map is given to the
alpar@21
   196
constructor. Then you can access its element as if it were a vector.
alpar@21
   197
alpar@21
   198
\code
kpeter@27
   199
  map[a] = 2;
kpeter@27
   200
  map[b] = 3;
kpeter@27
   201
  map[c] = map[a] + map[b];
alpar@21
   202
\endcode
alpar@21
   203
kpeter@27
   204
Any kind of data can be assigned to the graph items.
kpeter@27
   205
kpeter@27
   206
\code
kpeter@27
   207
  ListDigraph::NodeMap<std::string> label(g);
kpeter@27
   208
  label[a] = "Node A";
kpeter@27
   209
  label[b] = "Node B";
kpeter@27
   210
\endcode
kpeter@27
   211
kpeter@27
   212
For a more complex example, let us create a map that assigns a unique
alpar@21
   213
integer number to each node.
alpar@21
   214
alpar@21
   215
\code
alpar@21
   216
  ListDigraph::NodeMap<int> id(g);
kpeter@27
   217
  int cnt = 0;
kpeter@27
   218
  for (ListDigraph::NodeIt n(g); n != INVALID; ++n)
kpeter@27
   219
    id[n] = cnt++;
alpar@21
   220
\endcode
alpar@21
   221
kpeter@27
   222
When you create a map, you can also give an initial value of the elements
kpeter@27
   223
as a second parameter. For example, the following code puts the number
kpeter@27
   224
of outgoing arcs for each node in a map.
alpar@21
   225
alpar@21
   226
\code
kpeter@27
   227
  ListDigraph::NodeMap<int> out_deg(g, 0);
alpar@21
   228
kpeter@27
   229
  for (ListDigraph::ArcIt a(g); a != INVALID; ++a)
alpar@21
   230
    out_deg[g.source(a)]++;
alpar@21
   231
\endcode
alpar@21
   232
kpeter@27
   233
\warning The initial value will apply to the currently existing items only. If
alpar@21
   234
you add new nodes/arcs to the graph, then the corresponding values in the
alpar@21
   235
map will be initialized with the default constructor of the
alpar@21
   236
type.
alpar@21
   237
alpar@21
   238
[TRAILER]
alpar@21
   239
*/
alpar@21
   240
}