19 namespace lemon { |
19 namespace lemon { |
20 /** |
20 /** |
21 [PAGE]sec_algorithms[PAGE] Algorithms |
21 [PAGE]sec_algorithms[PAGE] Algorithms |
22 |
22 |
23 \todo This page is under construction. |
23 \todo This page is under construction. |
24 |
24 \todo This section should be revised and extended. |
25 \todo The following contents are mainly ported from the LEMON 0.x tutorial, |
|
26 thus they have to be thoroughly revised and reworked. |
|
27 |
|
28 \warning Currently, this section may contain old or faulty contents. |
|
29 |
25 |
30 In addition to the graph structures, the most important parts of LEMON are |
26 In addition to the graph structures, the most important parts of LEMON are |
31 the various algorithms related to graph theory and combinatorial optimization. |
27 the various algorithms related to graph theory and combinatorial optimization. |
32 The library provides quite flexible and efficient implementations |
28 The library provides quite flexible and efficient implementations |
33 for well-known fundamental algorithms, such as breadth-first |
29 for well-known fundamental algorithms, such as \ref Bfs |
34 search (BFS), depth-first search (DFS), Dijkstra algorithm, Kruskal algorithm |
30 "breadth-first search (BFS)", \ref Dfs "depth-first search (DFS)", |
35 and methods for discovering graph properties like connectivity, bipartiteness |
31 \ref Dijkstra "Dijkstra algorithm", \ref kruskal "Kruskal algorithm" |
36 or Euler property, as well as more complex optimization algorithms for finding |
32 and methods for discovering \ref graph_properties "graph properties" like |
37 maximum flows, minimum cuts, matchings, minimum cost flows and arc-disjoint |
33 connectivity, bipartiteness or Euler property, as well as more complex |
38 paths. |
34 optimization algorithms for finding \ref max_flow "maximum flows", |
|
35 \ref min_cut "minimum cuts", \ref matching "matchings", |
|
36 \ref min_cost_flow_algs "minimum cost flows" etc. |
39 |
37 |
40 In this section, we present only some of the most fundamental algorithms. |
38 In this section, we present only some of the most fundamental algorithms. |
41 For a complete overview, see the \ref algs module of the reference manual. |
39 For a complete overview, see the \ref algs module of the reference manual. |
42 |
40 |
43 [SEC]sec_graph_search[SEC] Graph Search |
41 [SEC]sec_graph_search[SEC] Graph Search |
44 |
42 |
45 See \ref Bfs, \ref Dfs and \ref graph_properties. |
43 The common graph search algorithms, namely \ref Bfs "breadth-first search (BFS)" |
46 |
44 and \ref Dfs "depth-first search (DFS)" are implemented in highly adaptable and |
47 Both \ref lemon::Bfs "Bfs" and \ref lemon::Dfs "Dfs" are highly adaptable and efficient |
45 efficient algorithm classes \ref Bfs and \ref Dfs. In LEMON, |
48 implementations of the well known algorithms. The algorithms are placed most cases in |
46 the algorithms are typically placed in separated files, which are named after |
49 separated files named after the algorithm itself but lower case as all other header file names. |
47 the algorithm itself but with lower case like all other header files. |
50 For example the next Bfs class is in the \c lemon/bfs.h. |
48 For example, we have to include <tt>bfs.h</tt> for using \ref Bfs. |
51 |
49 |
52 The algorithm is implemented in the \ref lemon::Bfs "Bfs" template class - rather than as function. |
50 \code |
53 The class has two template parameters: \b GR and \b TR.<br> |
51 #include <lemon/bfs.h> |
54 GR is the digraph the algorithm runs on. It has \ref lemon::ListDigraph "ListDigraph" as default type. |
52 \endcode |
55 TR is a Traits class commonly used to easy the parameterization of templates. In most cases you |
53 |
56 wont need to modify the default type \ref lemon::BfsDefaultTraits "BfsDefaultTraits<GR>". |
54 Basically, all algorithms are implemented in template classes. |
57 |
55 The template parameters typically specify the used graph type (for more |
58 To use the class, declare it! |
56 information, see \ref sec_graph_structures) and the required map types. |
59 \code |
57 For example, an instance of the \ref BFs class can be created like this. |
60 Bfs<ListGraph> bfs(gr); |
58 |
61 \endcode |
59 \code |
62 Note the lack of second template argument because of the default parameter. |
60 ListDigraph g; |
63 |
61 Bfs<ListDigraph> bfs(g); |
64 It provides a simple but powerful interface to control the execution. |
62 \endcode |
65 \code |
63 |
66 int dist = bfs.run(s,t); |
64 This class provides a simple but powerful interface to control the execution |
67 \endcode |
65 of the algorithm and to obtain all the results. |
68 It finds the shortest path from node \c s to node \c t and returns it, or zero |
66 You can execute the algorithm from a given source node by calling |
69 if there is no path from \c s to \c t.<br> |
67 the \ref Bfs::run() "run()" function. |
70 If you want the shortest path from a specified node to all other node, just write: |
68 |
|
69 \code |
|
70 bfs.run(s); |
|
71 \endcode |
|
72 |
|
73 This operation finds the shortest paths from \c s to all other nodes. |
|
74 If you are looking for an s-t path for a certain target node \c t, |
|
75 you can also call the \ref Bfs::run() "run()" function with two |
|
76 parameters. In this case, the BFS search will terminate once it has found |
|
77 the shortest path from \c s to \c t. |
|
78 |
|
79 \code |
|
80 bfs.run(s,t); |
|
81 \endcode |
|
82 |
|
83 By default, the distances and the path information are stored in internal |
|
84 maps, which you can access with member functions like \ref lemon::Bfs::distMap |
|
85 "distMap()" and \ref lemon::Bfs::predMap() "predMap()" or more directly with |
|
86 other member functions like \ref lemon::Bfs::dist() "dist()", |
|
87 \ref lemon::Bfs::path() "path()", \ref lemon::Bfs::predNode() "predNode()", |
|
88 \ref lemon::Bfs::predArc() "predArc()". Once the execution of the algorithm |
|
89 is finished, these query functions can be called. |
|
90 |
|
91 For an example, let us say we want to print the shortest path of those nodes |
|
92 that are at most in a certain distance \c max_dist. |
71 \code |
93 \code |
72 bfs.run(s); |
94 bfs.run(s); |
73 \endcode |
95 |
74 Now the distances and path information are stored in maps which you can access with |
96 for (ListGraph::NodeIt n(g); n != INVALID; ++n) { |
75 member functions like \ref lemon::Bfs::distMap "distMap()" or \ref lemon::Bfs::predMap "predMap()".<br> |
97 if (bfs.reached(n) && bfs.dist(n) <= max_dist) { |
76 Or more directly with other member functions like \ref lemon::Bfs::predNode "predNode()". Once the algorithm |
|
77 is finished (or to be precise reached that node) \ref lemon::Bfs::dist "dist()" or \ref lemon::Bfs::predNode |
|
78 "predNode()" can be called. |
|
79 |
|
80 For an example let's say we want to print the shortest path of those nodes which |
|
81 are in a certain distance. |
|
82 \code |
|
83 bfs.run(s); |
|
84 |
|
85 for( ListGraph::NodeIt n(gr); n != INVALID; ++n ) { |
|
86 if( bfs.reached(n) && bfs.dist(n) <= max_dist ) { |
|
87 std::cout << gr.id(n); |
98 std::cout << gr.id(n); |
88 |
99 Node prev = bfs.prevNode(n); |
89 Node prev = bfs.prevNode(n); |
100 while (prev != INVALID) { |
90 while( prev != INVALID ) { |
|
91 std::cout << "<-" << gr.id(prev); |
101 std::cout << "<-" << gr.id(prev); |
92 prev = bfs.prevNode(n); |
102 prev = bfs.prevNode(n); |
|
103 } |
|
104 std::cout << std::endl; |
|
105 } |
|
106 } |
|
107 \endcode |
|
108 |
|
109 The class interfaces of the algorithms also support a finer control on |
|
110 the execution. For example, we can specify more source nodes and we can |
|
111 even run the algorithm step-by-step. |
|
112 If you need such control on the execution, you have to use more functions |
|
113 instead of \ref Bfs::run() "run()". First, you have to call \ref Bfs::init() |
|
114 "init()" to initialize the internal data structures. |
|
115 |
|
116 \code |
|
117 bfs.init(); |
|
118 \endcode |
|
119 |
|
120 Then you can add one or more source nodes to the queue with |
|
121 \ref Bfs::addSource() "addSource()". They will be processed, as they would |
|
122 be reached by the algorithm before. And yes, you can even add more sources |
|
123 during the execution. |
|
124 |
|
125 \code |
|
126 bfs.addSource(s1); |
|
127 bfs.addSource(s2); |
|
128 ... |
|
129 \endcode |
|
130 |
|
131 Finally, the actual path computation of the algorithm can be performed with |
|
132 the \ref Bfs::start() "start()" function. |
|
133 |
|
134 \code |
|
135 bfs.start(t); |
|
136 \endcode |
|
137 |
|
138 Instead of using \ref Bfs::start() "start()", you can even execute the |
|
139 algorithm step-by-step, so you can write your own loop to process the |
|
140 nodes one-by-one. |
|
141 For example, the following code will executes the algorithm in such a way, |
|
142 that it reaches all nodes in the digraph, namely the algorithm is started |
|
143 for each node that is not visited before. |
|
144 |
|
145 \code |
|
146 bfs.init(); |
|
147 for (NodeIt n(g); n != INVALID; ++n) { |
|
148 if (!bfs.reached(n)) { |
|
149 bfs.addSource(n); |
|
150 bfs.start(); |
93 } |
151 } |
94 |
152 } |
95 std::cout << std::endl; |
153 \endcode |
96 } |
154 |
97 } |
155 <tt>bfs.start()</tt> is only a shortcut of the following code. |
98 \endcode |
156 |
99 |
157 \code |
100 In the previous code we only used \c run(). Now we introduce the way you can directly |
158 while (!bfs.emptyQueue()) { |
101 control the execution of the algorithm. |
159 bfs.processNextNode(); |
102 |
160 } |
103 First you have to initialize the variables with \ref lemon::Bfs::init "init()". |
161 \endcode |
104 \code |
162 |
105 bfs.init(); |
163 \todo Write about function-type interfaces |
106 \endcode |
164 |
107 |
165 |
108 Then you add one or more source nodes to the queue. They will be processed, as they would |
166 Since the DFS algorithm is very similar to BFS with a few tiny differences, |
109 be reached by the algorithm before. And yes - you can add more sources during the execution. |
167 the \ref Dfs class can be used similarly to \ref Bfs. |
110 \code |
|
111 bfs.addSource(node_1); |
|
112 bfs.addSource(node_2); |
|
113 ... |
|
114 \endcode |
|
115 |
|
116 And finally you can start the process with \ref lemon::Bfs::start "start()", or |
|
117 you can write your own loop to process the nodes one-by-one. |
|
118 |
|
119 |
|
120 Since Dfs is very similar to Bfs with a few tiny differences we only see a bit more complex example |
|
121 to demonstrate Dfs's capabilities. |
|
122 |
|
123 We will see a program, which solves the problem of <b>topological ordering</b>. |
|
124 We need to know in which order we should put on our clothes. The program will do the following: |
|
125 <ol> |
|
126 <li>We run the dfs algorithm to all nodes. |
|
127 <li>Put every node into a list when processed completely. |
|
128 <li>Write out the list in reverse order. |
|
129 </ol> |
|
130 |
|
131 \dontinclude topological_ordering.cc |
|
132 First of all we will need an own \ref lemon::Dfs::ProcessedMap "ProcessedMap". The ordering |
|
133 will be done through it. |
|
134 \skip MyOrdererMap |
|
135 \until }; |
|
136 The class meets the \ref concepts::WriteMap "WriteMap" concept. In it's \c set() method the only thing |
|
137 we need to do is insert the key - that is the node whose processing just finished - into the beginning |
|
138 of the list.<br> |
|
139 Although we implemented this needed helper class ourselves it was not necessary. |
|
140 The \ref lemon::FrontInserterBoolMap "FrontInserterBoolMap" class does exactly |
|
141 what we needed. To be correct it's more general - and it's all in \c LEMON. But |
|
142 we wanted to show you, how easy is to add additional functionality. |
|
143 |
|
144 First we declare the needed data structures: the digraph and a map to store the nodes' label. |
|
145 \skip ListDigraph |
|
146 \until label |
|
147 |
|
148 Now we build a digraph. But keep in mind that it must be DAG because cyclic digraphs has no topological |
|
149 ordering. |
|
150 \skip belt |
|
151 \until trousers |
|
152 We label them... |
|
153 \skip label |
|
154 \until trousers |
|
155 Then add arcs which represent the precedences between those items. |
|
156 \skip trousers, belt |
|
157 \until ); |
|
158 |
|
159 See how easy is to access the internal information of this algorithm trough maps. |
|
160 We only need to set our own map as the class's \ref lemon::Dfs::ProcessedMap "ProcessedMap". |
|
161 \skip Dfs |
|
162 \until run |
|
163 |
|
164 And now comes the third part. Write out the list in reverse order. But the list was |
|
165 composed in reverse way (with \c push_front() instead of \c push_back() so we just iterate it. |
|
166 \skip std |
|
167 \until endl |
|
168 |
|
169 The program is to be found in the \ref demo directory: \ref topological_ordering.cc |
|
170 |
|
171 \todo Check the linking of the demo file, the code samples are missing. |
|
172 |
|
173 More algorithms are described in the \ref algorithms2 "second part". |
|
174 |
168 |
175 |
169 |
176 [SEC]sec_shortest_paths[SEC] Shortest Paths |
170 [SEC]sec_shortest_paths[SEC] Shortest Paths |
177 |
171 |
178 See \ref Dijkstra and \ref BellmanFord. |
172 If you would like to solve some transportation problems in a network, then |
179 |
173 you will most likely want to find shortest paths between nodes of a graph. |
180 |
174 This is usually solved using Dijkstra's algorithm. |
181 If you want to solve some transportation problems in a network then you |
175 The following code is a simple program using the LEMON \ref Dijkstra class |
182 will want to find shortest paths between nodes of a graph. This is |
176 through the function-type interface \ref dijkstra(). |
183 usually solved using Dijkstra's algorithm. A utility that solves this is |
177 It calculates the shortest path between node \c s and \c t in a digraph \c g. |
184 the LEMON Dijkstra class. The following code is a simple program using |
178 |
185 the LEMON Dijkstra class: it calculates the shortest path between node s |
179 \code |
186 and t in a graph g. We omit the part reading the graph g and the length |
180 dijkstra(g, length).distMap(dist).run(s,t); |
187 map len. |
181 \endcode |
188 |
|
189 <hr> |
|
190 |
182 |
191 In LEMON, the algorithms are implemented basically as classes, but |
183 In LEMON, the algorithms are implemented basically as classes, but |
192 for some of them, function-type interfaces are also available |
184 for some of them, function-type interfaces are also available |
193 for the sake of convenience. |
185 for the sake of convenience. |
194 For instance, the Dijkstra algorithm is implemented in the \ref Dijkstra |
186 For instance, the Dijkstra algorithm is implemented in the \ref Dijkstra |
195 template class, but the \ref dijkstra() function is also defined, |
187 template class, but the \ref dijkstra() function is also defined, |
196 which can still be used quite flexibly due to named parameters. |
188 which can still be used quite flexibly due to named parameters. |
197 |
189 |
198 The original sample code could also use the class interface as follows. |
190 The above sample code could also use the class interface as follows. |
199 |
191 |
200 \code |
192 \code |
201 Dijkstra<ListDigraph> dijkstra(g, length); |
193 Dijkstra<ListDigraph> dijkstra(g, length); |
202 dijkstra.distMap(dist); |
194 dijkstra.distMap(dist); |
203 dijsktra.init(); |
195 dijsktra.init(); |
204 dijkstra.addSource(u); |
196 dijkstra.addSource(s); |
205 dijkstra.start(); |
197 dijkstra.start(); |
206 \endcode |
198 \endcode |
207 |
199 |
208 The previous code is obviously longer than the original, but the |
200 The previous code is obviously longer than the original, but the |
209 execution can be controlled to a higher extent. While using the function-type |
201 execution can be controlled to a higher extent. While using the function-type |