doc/algorithms.dox
author ladanyi
Sat, 13 Oct 2007 08:48:07 +0000
changeset 2495 e4f8367beb41
parent 2470 46818ce27a60
child 2553 bfced05fa852
permissions -rw-r--r--
Added the function isFinite(), and replaced the calls to finite() with it.
This was necessary because finite() is not a standard function. Neither can
we use its standard counterpart isfinite(), because it was introduced only
in C99, and therefore it is not supplied by all C++ implementations.
alpar@2391
     1
/* -*- C++ -*-
alpar@2391
     2
 *
alpar@2391
     3
 * This file is a part of LEMON, a generic C++ optimization library
alpar@2391
     4
 *
alpar@2391
     5
 * Copyright (C) 2003-2007
alpar@2391
     6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
alpar@2391
     7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
alpar@2391
     8
 *
alpar@2391
     9
 * Permission to use, modify and distribute this software is granted
alpar@2391
    10
 * provided that this copyright notice appears in all copies. For
alpar@2391
    11
 * precise terms see the accompanying LICENSE file.
alpar@2391
    12
 *
alpar@2391
    13
 * This software is provided "AS IS" with no warranty of any kind,
alpar@2391
    14
 * express or implied, and with no claim as to its suitability for any
alpar@2391
    15
 * purpose.
alpar@2391
    16
 *
alpar@2391
    17
 */
alpar@2391
    18
alpar@2216
    19
namespace lemon {
alpar@2196
    20
/**
alpar@2196
    21
\page algorithms Algorithms
alpar@2196
    22
alpar@2216
    23
\section algo_bfs_dfs Bfs/Dfs
alpar@2216
    24
Both \ref lemon::Bfs "Bfs" and \ref lemon::Dfs "Dfs" are highly adaptable and efficient
alpar@2216
    25
implementations of the well known algorithms. The algorithms are placed most cases in
alpar@2216
    26
separated files named after the algorithm itself but lower case as all other header file names.
alpar@2216
    27
For example the next Bfs class is in the \c lemon/bfs.h.
alpar@2216
    28
alpar@2216
    29
\subsection Bfs
alpar@2216
    30
The algorithm is implemented in the \ref lemon::Bfs "Bfs" template class - rather than as function.
alpar@2408
    31
The class has two template parameters: \b GR and \b TR.<br>
alpar@2216
    32
GR is the graph the algorithm runs on. It has \ref lemon::ListGraph "ListGraph" as default type.
alpar@2216
    33
TR is a Traits class commonly used to easy the parametrization of templates. In most cases you
alpar@2216
    34
wont need to modify the default type \ref lemon::BfsDefaultTraits "BfsDefaultTraits<GR>".
alpar@2216
    35
alpar@2216
    36
To use the class, declare it!
alpar@2216
    37
\code
alpar@2216
    38
Bfs<ListUGraph>  bfs(gr);
alpar@2216
    39
\endcode
alpar@2216
    40
Note the lack of second template argument because of the default parameter.
alpar@2216
    41
alpar@2216
    42
It provides a simple but powerful interface to control the execution.
alpar@2216
    43
\code
alpar@2216
    44
int dist = bfs.run(s,t);
alpar@2216
    45
\endcode
alpar@2216
    46
It finds the shortest path from node \c s to node \c t and returns it, or zero
alpar@2216
    47
if there is no path from \c s to \c t.<br>
alpar@2216
    48
If you want the shortest path from a specified node to all other node, just write:
alpar@2216
    49
\code
alpar@2216
    50
bfs.run(s);
alpar@2216
    51
\endcode
alpar@2216
    52
Now the distances and path information are stored in maps which you can access with
alpar@2216
    53
member functions like \ref lemon::Bfs::distMap "distMap()" or \ref lemon::Bfs::predMap "predMap()".<br>
alpar@2408
    54
Or more directly with other member functions like \ref lemon::Bfs::predNode "predNode()". Once the algorithm
alpar@2216
    55
is finished (or to be precise reached that node) \ref lemon::Bfs::dist "dist()" or \ref lemon::Bfs::predNode
alpar@2216
    56
"predNode()" can be called.
alpar@2216
    57
alpar@2216
    58
For an example let's say we want to print the shortest path of those nodes which
alpar@2216
    59
are in a certain distance.
alpar@2216
    60
\code
alpar@2216
    61
bfs.run(s);
alpar@2216
    62
alpar@2216
    63
for( ListUGraph::NodeIt  n(gr); n != INVALID; ++n ) {
alpar@2216
    64
  if( bfs.reached(n) && bfs.dist(n) <= max_dist ) {
alpar@2216
    65
    std::cout << gr.id(n);
alpar@2216
    66
alpar@2216
    67
    Node  prev = bfs.prevNode(n);
alpar@2216
    68
    while( prev != INVALID ) {
alpar@2216
    69
      std::cout << "<-" << gr.id(prev);
alpar@2216
    70
      prev = bfs.prevNode(n);
alpar@2216
    71
    }
alpar@2216
    72
    
alpar@2216
    73
    std::cout << std::endl;
alpar@2216
    74
  }
alpar@2216
    75
}
alpar@2216
    76
\endcode
alpar@2216
    77
alpar@2216
    78
\subsubsection bfs_adv_control Advanced control
alpar@2216
    79
In the previous code we only used \c run(). Now we introduce the way you can directly
alpar@2216
    80
control the execution of the algorithm.
alpar@2216
    81
alpar@2216
    82
First you have to initialize the variables with \ref lemon::Bfs::init "init()".
alpar@2216
    83
\code
alpar@2216
    84
  bfs.init();
alpar@2216
    85
\endcode
alpar@2216
    86
alpar@2216
    87
Then you add one or more source nodes to the queue. They will be processed, as they would
alpar@2216
    88
be reached by the algorithm before. And yes - you can add more sources during the execution.
alpar@2216
    89
\code
alpar@2216
    90
  bfs.addSource(node_1);
alpar@2216
    91
  bfs.addSource(node_2);
alpar@2216
    92
  ...
alpar@2216
    93
\endcode
alpar@2216
    94
alpar@2216
    95
And finally you can start the process with \ref lemon::Bfs::start "start()", or
alpar@2216
    96
you can write your own loop to process the nodes one-by-one.
alpar@2216
    97
kpeter@2470
    98
\todo Demo for Bfs advanced control.
alpar@2216
    99
alpar@2216
   100
\subsection Dfs
alpar@2216
   101
Since Dfs is very similar to Bfs with a few tiny differences we only see a bit more complex example
alpar@2216
   102
to demonstrate Dfs's capabilities.
alpar@2216
   103
alpar@2216
   104
We will see a program, which solves the problem of <b>topological ordering</b>.
alpar@2216
   105
We need to know in which order we should put on our clothes. The program will do the following:
alpar@2216
   106
<ol>
alpar@2216
   107
<li>We run the dfs algorithm to all nodes.
alpar@2216
   108
<li>Put every node into a list when processed completely.
alpar@2216
   109
<li>Write out the list in reverse order.
alpar@2216
   110
</ol>
alpar@2216
   111
alpar@2216
   112
\dontinclude topological_ordering.cc
alpar@2216
   113
First of all we will need an own \ref lemon::Dfs::ProcessedMap "ProcessedMap". The ordering
alpar@2216
   114
will be done through it.
mqrelly@2281
   115
\skip MyOrdererMap
alpar@2216
   116
\until };
kpeter@2476
   117
The class meets the \ref concepts::WriteMap "WriteMap" concept. In it's \c set() method the only thing
alpar@2408
   118
we need to do is insert the key - that is the node whose processing just finished - into the beginning
mqrelly@2281
   119
of the list.<br>
mqrelly@2281
   120
Although we implemented this needed helper class ourselves it was not necessary.
mqrelly@2281
   121
The \ref lemon::FrontInserterBoolMap "FrontInserterBoolMap" class does exactly
mqrelly@2281
   122
what we needed. To be correct it's more general - and it's all in \c LEMON. But
mqrelly@2281
   123
we wanted to show you, how easy is to add additional functionality.
alpar@2216
   124
alpar@2216
   125
First we declare the needed data structures: the graph and a map to store the nodes' label.
alpar@2216
   126
\skip ListGraph
alpar@2216
   127
\until label
alpar@2216
   128
alpar@2216
   129
Now we build a graph. But keep in mind that it must be DAG because cyclic graphs has no topological
alpar@2216
   130
ordering.
alpar@2216
   131
\skip belt
alpar@2216
   132
\until trousers
alpar@2216
   133
We label them...
alpar@2216
   134
\skip label
alpar@2216
   135
\until trousers
alpar@2216
   136
Then add directed edges which represent the precedences between those items.
alpar@2216
   137
\skip trousers, belt
alpar@2216
   138
\until );
alpar@2216
   139
alpar@2216
   140
See how easy is to access the internal information of this algorithm trough maps.
alpar@2216
   141
We only need to set our own map as the class's \ref lemon::Dfs::ProcessedMap "ProcessedMap".
alpar@2216
   142
\skip Dfs
alpar@2216
   143
\until run
alpar@2216
   144
alpar@2216
   145
And now comes the third part. Write out the list in reverse order. But the list was
alpar@2216
   146
composed in reverse way (with \c push_front() instead of \c push_back() so we just iterate it.
alpar@2216
   147
\skip std
alpar@2216
   148
\until endl
alpar@2216
   149
alpar@2216
   150
The program is to be found in the \ref demo directory: \ref topological_ordering.cc
mqrelly@2281
   151
kpeter@2470
   152
\todo Check the linking of the demo file, the code samples are missing.
kpeter@2470
   153
mqrelly@2281
   154
More algorithms are described in the \ref algorithms2 "second part".
alpar@2196
   155
*/
alpar@2216
   156
}