# HG changeset patch # User Peter Kovacs # Date 1267407000 -3600 # Node ID 10b6a5b7d4c02c92a6bd858e0873e4883fc30aae # Parent 18404ec968ca49aaa50c7608ad7f68102474b55c Improve Algorithms section (it is still under construction) diff -r 18404ec968ca -r 10b6a5b7d4c0 algorithms.dox --- a/algorithms.dox Mon Mar 01 02:28:44 2010 +0100 +++ b/algorithms.dox Mon Mar 01 02:30:00 2010 +0100 @@ -21,172 +21,164 @@ [PAGE]sec_algorithms[PAGE] Algorithms \todo This page is under construction. - -\todo The following contents are mainly ported from the LEMON 0.x tutorial, -thus they have to be thoroughly revised and reworked. - -\warning Currently, this section may contain old or faulty contents. +\todo This section should be revised and extended. In addition to the graph structures, the most important parts of LEMON are the various algorithms related to graph theory and combinatorial optimization. The library provides quite flexible and efficient implementations -for well-known fundamental algorithms, such as breadth-first -search (BFS), depth-first search (DFS), Dijkstra algorithm, Kruskal algorithm -and methods for discovering graph properties like connectivity, bipartiteness -or Euler property, as well as more complex optimization algorithms for finding -maximum flows, minimum cuts, matchings, minimum cost flows and arc-disjoint -paths. +for well-known fundamental algorithms, such as \ref Bfs +"breadth-first search (BFS)", \ref Dfs "depth-first search (DFS)", +\ref Dijkstra "Dijkstra algorithm", \ref kruskal "Kruskal algorithm" +and methods for discovering \ref graph_properties "graph properties" like +connectivity, bipartiteness or Euler property, as well as more complex +optimization algorithms for finding \ref max_flow "maximum flows", +\ref min_cut "minimum cuts", \ref matching "matchings", +\ref min_cost_flow_algs "minimum cost flows" etc. In this section, we present only some of the most fundamental algorithms. For a complete overview, see the \ref algs module of the reference manual. [SEC]sec_graph_search[SEC] Graph Search -See \ref Bfs, \ref Dfs and \ref graph_properties. +The common graph search algorithms, namely \ref Bfs "breadth-first search (BFS)" +and \ref Dfs "depth-first search (DFS)" are implemented in highly adaptable and +efficient algorithm classes \ref Bfs and \ref Dfs. In LEMON, +the algorithms are typically placed in separated files, which are named after +the algorithm itself but with lower case like all other header files. +For example, we have to include bfs.h for using \ref Bfs. -Both \ref lemon::Bfs "Bfs" and \ref lemon::Dfs "Dfs" are highly adaptable and efficient -implementations of the well known algorithms. The algorithms are placed most cases in -separated files named after the algorithm itself but lower case as all other header file names. -For example the next Bfs class is in the \c lemon/bfs.h. +\code + #include +\endcode -The algorithm is implemented in the \ref lemon::Bfs "Bfs" template class - rather than as function. -The class has two template parameters: \b GR and \b TR.
-GR is the digraph the algorithm runs on. It has \ref lemon::ListDigraph "ListDigraph" as default type. -TR is a Traits class commonly used to easy the parameterization of templates. In most cases you -wont need to modify the default type \ref lemon::BfsDefaultTraits "BfsDefaultTraits". +Basically, all algorithms are implemented in template classes. +The template parameters typically specify the used graph type (for more +information, see \ref sec_graph_structures) and the required map types. +For example, an instance of the \ref BFs class can be created like this. -To use the class, declare it! \code -Bfs bfs(gr); + ListDigraph g; + Bfs bfs(g); \endcode -Note the lack of second template argument because of the default parameter. -It provides a simple but powerful interface to control the execution. +This class provides a simple but powerful interface to control the execution +of the algorithm and to obtain all the results. +You can execute the algorithm from a given source node by calling +the \ref Bfs::run() "run()" function. + \code -int dist = bfs.run(s,t); + bfs.run(s); \endcode -It finds the shortest path from node \c s to node \c t and returns it, or zero -if there is no path from \c s to \c t.
-If you want the shortest path from a specified node to all other node, just write: + +This operation finds the shortest paths from \c s to all other nodes. +If you are looking for an s-t path for a certain target node \c t, +you can also call the \ref Bfs::run() "run()" function with two +parameters. In this case, the BFS search will terminate once it has found +the shortest path from \c s to \c t. + \code -bfs.run(s); + bfs.run(s,t); \endcode -Now the distances and path information are stored in maps which you can access with -member functions like \ref lemon::Bfs::distMap "distMap()" or \ref lemon::Bfs::predMap "predMap()".
-Or more directly with other member functions like \ref lemon::Bfs::predNode "predNode()". Once the algorithm -is finished (or to be precise reached that node) \ref lemon::Bfs::dist "dist()" or \ref lemon::Bfs::predNode -"predNode()" can be called. -For an example let's say we want to print the shortest path of those nodes which -are in a certain distance. +By default, the distances and the path information are stored in internal +maps, which you can access with member functions like \ref lemon::Bfs::distMap +"distMap()" and \ref lemon::Bfs::predMap() "predMap()" or more directly with +other member functions like \ref lemon::Bfs::dist() "dist()", +\ref lemon::Bfs::path() "path()", \ref lemon::Bfs::predNode() "predNode()", +\ref lemon::Bfs::predArc() "predArc()". Once the execution of the algorithm +is finished, these query functions can be called. + +For an example, let us say we want to print the shortest path of those nodes +that are at most in a certain distance \c max_dist. \code bfs.run(s); -for( ListGraph::NodeIt n(gr); n != INVALID; ++n ) { - if( bfs.reached(n) && bfs.dist(n) <= max_dist ) { +for (ListGraph::NodeIt n(g); n != INVALID; ++n) { + if (bfs.reached(n) && bfs.dist(n) <= max_dist) { std::cout << gr.id(n); - - Node prev = bfs.prevNode(n); - while( prev != INVALID ) { + Node prev = bfs.prevNode(n); + while (prev != INVALID) { std::cout << "<-" << gr.id(prev); prev = bfs.prevNode(n); - } - + } std::cout << std::endl; } } \endcode -In the previous code we only used \c run(). Now we introduce the way you can directly -control the execution of the algorithm. +The class interfaces of the algorithms also support a finer control on +the execution. For example, we can specify more source nodes and we can +even run the algorithm step-by-step. +If you need such control on the execution, you have to use more functions +instead of \ref Bfs::run() "run()". First, you have to call \ref Bfs::init() +"init()" to initialize the internal data structures. -First you have to initialize the variables with \ref lemon::Bfs::init "init()". \code bfs.init(); \endcode -Then you add one or more source nodes to the queue. They will be processed, as they would -be reached by the algorithm before. And yes - you can add more sources during the execution. +Then you can add one or more source nodes to the queue with +\ref Bfs::addSource() "addSource()". They will be processed, as they would +be reached by the algorithm before. And yes, you can even add more sources +during the execution. + \code - bfs.addSource(node_1); - bfs.addSource(node_2); + bfs.addSource(s1); + bfs.addSource(s2); ... \endcode -And finally you can start the process with \ref lemon::Bfs::start "start()", or -you can write your own loop to process the nodes one-by-one. +Finally, the actual path computation of the algorithm can be performed with +the \ref Bfs::start() "start()" function. +\code + bfs.start(t); +\endcode -Since Dfs is very similar to Bfs with a few tiny differences we only see a bit more complex example -to demonstrate Dfs's capabilities. +Instead of using \ref Bfs::start() "start()", you can even execute the +algorithm step-by-step, so you can write your own loop to process the +nodes one-by-one. +For example, the following code will executes the algorithm in such a way, +that it reaches all nodes in the digraph, namely the algorithm is started +for each node that is not visited before. -We will see a program, which solves the problem of topological ordering. -We need to know in which order we should put on our clothes. The program will do the following: -
    -
  1. We run the dfs algorithm to all nodes. -
  2. Put every node into a list when processed completely. -
  3. Write out the list in reverse order. -
+\code + bfs.init(); + for (NodeIt n(g); n != INVALID; ++n) { + if (!bfs.reached(n)) { + bfs.addSource(n); + bfs.start(); + } + } +\endcode -\dontinclude topological_ordering.cc -First of all we will need an own \ref lemon::Dfs::ProcessedMap "ProcessedMap". The ordering -will be done through it. -\skip MyOrdererMap -\until }; -The class meets the \ref concepts::WriteMap "WriteMap" concept. In it's \c set() method the only thing -we need to do is insert the key - that is the node whose processing just finished - into the beginning -of the list.
-Although we implemented this needed helper class ourselves it was not necessary. -The \ref lemon::FrontInserterBoolMap "FrontInserterBoolMap" class does exactly -what we needed. To be correct it's more general - and it's all in \c LEMON. But -we wanted to show you, how easy is to add additional functionality. +bfs.start() is only a shortcut of the following code. -First we declare the needed data structures: the digraph and a map to store the nodes' label. -\skip ListDigraph -\until label +\code + while (!bfs.emptyQueue()) { + bfs.processNextNode(); + } +\endcode -Now we build a digraph. But keep in mind that it must be DAG because cyclic digraphs has no topological -ordering. -\skip belt -\until trousers -We label them... -\skip label -\until trousers -Then add arcs which represent the precedences between those items. -\skip trousers, belt -\until ); +\todo Write about function-type interfaces -See how easy is to access the internal information of this algorithm trough maps. -We only need to set our own map as the class's \ref lemon::Dfs::ProcessedMap "ProcessedMap". -\skip Dfs -\until run -And now comes the third part. Write out the list in reverse order. But the list was -composed in reverse way (with \c push_front() instead of \c push_back() so we just iterate it. -\skip std -\until endl - -The program is to be found in the \ref demo directory: \ref topological_ordering.cc - -\todo Check the linking of the demo file, the code samples are missing. - -More algorithms are described in the \ref algorithms2 "second part". +Since the DFS algorithm is very similar to BFS with a few tiny differences, +the \ref Dfs class can be used similarly to \ref Bfs. [SEC]sec_shortest_paths[SEC] Shortest Paths -See \ref Dijkstra and \ref BellmanFord. +If you would like to solve some transportation problems in a network, then +you will most likely want to find shortest paths between nodes of a graph. +This is usually solved using Dijkstra's algorithm. +The following code is a simple program using the LEMON \ref Dijkstra class +through the function-type interface \ref dijkstra(). +It calculates the shortest path between node \c s and \c t in a digraph \c g. - -If you want to solve some transportation problems in a network then you -will want to find shortest paths between nodes of a graph. This is -usually solved using Dijkstra's algorithm. A utility that solves this is -the LEMON Dijkstra class. The following code is a simple program using -the LEMON Dijkstra class: it calculates the shortest path between node s -and t in a graph g. We omit the part reading the graph g and the length -map len. - -
+\code + dijkstra(g, length).distMap(dist).run(s,t); +\endcode In LEMON, the algorithms are implemented basically as classes, but for some of them, function-type interfaces are also available @@ -195,13 +187,13 @@ template class, but the \ref dijkstra() function is also defined, which can still be used quite flexibly due to named parameters. -The original sample code could also use the class interface as follows. +The above sample code could also use the class interface as follows. \code Dijkstra dijkstra(g, length); dijkstra.distMap(dist); dijsktra.init(); - dijkstra.addSource(u); + dijkstra.addSource(s); dijkstra.start(); \endcode @@ -219,11 +211,19 @@ } \endcode +LEMON provides several other algorithms for findign shortest paths in +specific or more general cases. For example, \ref BellmanFord can be used +instead of \ref Dijkstra when the graph contains an arc with negative cost. +You may check the \ref shortest_path module of the reference manual for +more details. + [SEC]sec_max_flow[SEC] Maximum Flows See \ref Preflow. +\todo Write this subsection. + [TRAILER] */ } diff -r 18404ec968ca -r 10b6a5b7d4c0 maps.dox --- a/maps.dox Mon Mar 01 02:28:44 2010 +0100 +++ b/maps.dox Mon Mar 01 02:30:00 2010 +0100 @@ -36,18 +36,6 @@ These classes also conform to the map %concepts, thus they can be used like standard LEMON maps. -Let us suppose that we have a traffic network stored in a LEMON digraph -structure with two arc maps \c length and \c speed, which -denote the physical length of each arc and the maximum (or average) -speed that can be achieved on the corresponding road-section, -respectively. If we are interested in the best traveling times, -the following code can be used. - -\code - dijkstra(g, divMap(length, speed)).distMap(dist).run(s); -\endcode - - Maps play a central role in LEMON. As their name suggests, they map a certain range of \e keys to certain \e values. Each map has two typedef's to determine the types of keys and values, like this: @@ -335,6 +323,7 @@ [SEC]sec_algs_with_maps[SEC] Using Algorithms with Special Maps + The basic functionality of the algorithms can be highly extended using special purpose map types for their internal data structures. For example, the \ref Dijkstra class stores a @@ -349,6 +338,17 @@ named template parameters. Similarly to the named function parameters, they allow specifying any subset of the parameters and in arbitrary order. +Let us suppose that we have a traffic network stored in a LEMON digraph +structure with two arc maps \c length and \c speed, which +denote the physical length of each arc and the maximum (or average) +speed that can be achieved on the corresponding road-section, +respectively. If we are interested in the best traveling times, +the following code can be used. + +\code + dijkstra(g, divMap(length, speed)).distMap(dist).run(s); +\endcode + \code typedef vector Container; typedef back_insert_iterator InsertIterator; @@ -378,6 +378,56 @@ .run(s); \endcode +Let us see a bit more complex example to demonstrate Dfs's capabilities. + +We will see a program, which solves the problem of topological ordering. +We need to know in which order we should put on our clothes. The program will do the following: +
    +
  1. We run the dfs algorithm to all nodes. +
  2. Put every node into a list when processed completely. +
  3. Write out the list in reverse order. +
+ +\dontinclude topological_ordering.cc +First of all we will need an own \ref lemon::Dfs::ProcessedMap "ProcessedMap". The ordering +will be done through it. +\skip MyOrdererMap +\until }; +The class meets the \ref concepts::WriteMap "WriteMap" concept. In it's \c set() method the only thing +we need to do is insert the key - that is the node whose processing just finished - into the beginning +of the list.
+Although we implemented this needed helper class ourselves it was not necessary. +The \ref lemon::FrontInserterBoolMap "FrontInserterBoolMap" class does exactly +what we needed. To be correct it's more general - and it's all in \c LEMON. But +we wanted to show you, how easy is to add additional functionality. + +First we declare the needed data structures: the digraph and a map to store the nodes' label. +\skip ListDigraph +\until label + +Now we build a digraph. But keep in mind that it must be DAG because cyclic digraphs has no topological +ordering. +\skip belt +\until trousers +We label them... +\skip label +\until trousers +Then add arcs which represent the precedences between those items. +\skip trousers, belt +\until ); + +See how easy is to access the internal information of this algorithm trough maps. +We only need to set our own map as the class's \ref lemon::Dfs::ProcessedMap "ProcessedMap". +\skip Dfs +\until run + +And now comes the third part. Write out the list in reverse order. But the list was +composed in reverse way (with \c push_front() instead of \c push_back() so we just iterate it. +\skip std +\until endl + +The program is to be found in the \ref demo directory: \ref topological_ordering.cc + LEMON also contains visitor based algorithm classes for BFS and DFS.