1 // ==========================================================================
2 // SeqAn - The Library for Sequence Analysis
3 // ==========================================================================
4 // Copyright (c) 2006-2015, Knut Reinert, FU Berlin
5 // All rights reserved.
6 //
7 // Redistribution and use in source and binary forms, with or without
8 // modification, are permitted provided that the following conditions are met:
9 //
10 // * Redistributions of source code must retain the above copyright
11 // notice, this list of conditions and the following disclaimer.
12 // * Redistributions in binary form must reproduce the above copyright
13 // notice, this list of conditions and the following disclaimer in the
14 // documentation and/or other materials provided with the distribution.
15 // * Neither the name of Knut Reinert or the FU Berlin nor the names of
16 // its contributors may be used to endorse or promote products derived
17 // from this software without specific prior written permission.
18 //
19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 // ARE DISCLAIMED. IN NO EVENT SHALL KNUT REINERT OR THE FU BERLIN BE LIABLE
23 // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25 // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26 // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 // LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 // OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
29 // DAMAGE.
30 //
31 // ==========================================================================
32 // Author: Tobias Raussch <rausch@embl.de>
33 // ==========================================================================
34 // Implementation of the Ford-Fulkerson algorithm.
35 // ==========================================================================
36
37 #ifndef INCLUDE_SEQAN_GRAPH_ALGORITHMS_FORD_FULKERSON_H_
38 #define INCLUDE_SEQAN_GRAPH_ALGORITHMS_FORD_FULKERSON_H_
39
40 namespace seqan {
41
42 // ============================================================================
43 // Forwards
44 // ============================================================================
45
46 // ============================================================================
47 // Tags, Classes, Enums
48 // ============================================================================
49
50 // ============================================================================
51 // Metafunctions
52 // ============================================================================
53
54 // ============================================================================
55 // Functions
56 // ============================================================================
57
58 // ----------------------------------------------------------------------------
59 // Function fordFulkersonAlgorithm()
60 // ----------------------------------------------------------------------------
61
62 template <typename TSpec, typename TCapMap, typename TFlowMap, typename TResidualGraph>
63 void
_buildResidualGraph(Graph<TSpec> const & g,TCapMap const & capacity,TFlowMap const & flow,TResidualGraph & rG)64 _buildResidualGraph(Graph<TSpec> const& g,
65 TCapMap const& capacity,
66 TFlowMap const& flow,
67 TResidualGraph& rG)
68 {
69 typedef Graph<TSpec> TGraph;
70 typedef typename Iterator<TGraph, VertexIterator>::Type TVertexIterator;
71 typedef typename Iterator<TGraph, EdgeIterator>::Type TEdgeIterator;
72 typedef typename Value<TFlowMap>::Type TFlow;
73 typedef typename Value<TCapMap>::Type TCap;
74
75 clear(rG);
76 TVertexIterator itV(g);
77 for(;!atEnd(itV);goNext(itV)) {
78 _createVertices(rG, getValue(itV));
79 }
80
81 TEdgeIterator itE(g);
82 for(;!atEnd(itE);goNext(itE)) {
83 typedef typename EdgeDescriptor<TResidualGraph>::Type TEdgeDescriptor;
84 TFlow f = getProperty(flow, getValue(itE));
85 TCap cap = getProperty(capacity, getValue(itE));
86 if (f > 0) {
87 TEdgeDescriptor e_rG = findEdge(rG, targetVertex(itE), sourceVertex(itE));
88 if (e_rG == 0) addEdge(rG, targetVertex(itE), sourceVertex(itE), f);
89 else cargo(e_rG) += f;
90 }
91 if (f < cap) {
92 TEdgeDescriptor e_rG = findEdge(rG, sourceVertex(itE), targetVertex(itE));
93 if (e_rG == 0) addEdge(rG, sourceVertex(itE), targetVertex(itE), cap - f);
94 else cargo(e_rG) += cap - f;
95 }
96 }
97 }
98
99 template <typename TSpec, typename TPredecessorMap, typename TVertexDescriptor>
100 inline typename Size<Graph<TSpec> >::Type
_getMinimumAug(Graph<TSpec> const & rG,TPredecessorMap & predecessor,TVertexDescriptor const source,TVertexDescriptor sink)101 _getMinimumAug(Graph<TSpec> const & rG,
102 TPredecessorMap & predecessor,
103 TVertexDescriptor const source,
104 TVertexDescriptor sink)
105 {
106 typedef Graph<TSpec> TGraph;
107 typedef typename Size<TGraph>::Type TSize;
108 typedef TSize TFlow;
109 typedef typename Iterator<String<TVertexDescriptor>, Rooted>::Type TIterator;
110
111 // Build secondary predecessor map just containing the path
112 TVertexDescriptor nilPred = getNil<typename VertexDescriptor<TGraph>::Type>();
113 String<TVertexDescriptor> predMap;
114 resizeVertexMap(predMap, rG);
115 TIterator it = begin(predMap);
116 for(;!atEnd(it);goNext(it)) {
117 *it = nilPred;
118 }
119
120 // Find minimum flow
121 TVertexDescriptor pred = getProperty(predecessor, sink);
122 TFlow f = getCargo(findEdge(rG, pred,sink));
123 assignProperty(predMap, sink, pred);
124 while(pred != source) {
125 sink = pred;
126 pred = getProperty(predecessor, sink);
127 TFlow f2 = getCargo(findEdge(rG, pred,sink));
128 assignProperty(predMap, sink, pred);
129 if (f2 < f) f = f2;
130 }
131
132 // Just return the augmenting path
133 predecessor = predMap;
134 return f;
135 }
136
137 /*!
138 * @fn fordFulkersonAlgorithm
139 *
140 * @headerfile <seqan/graph_algorithms.h>
141 *
142 * @brief Computes a maximum flow in a directed graph.
143 *
144 * @signature TValue fordFulkeronAlgorithm(flow, g, source, sink, capacity);
145 *
146 * @param[out] flow A property map with the flow of each edge.
147 * @param[in] g A directed graph. Types: Directed Graph
148 * @param[in] source A source vertex. Types: VertexDescriptor
149 * @param[in] sink A sink vertex. Types: VertexDescriptor
150 * @param[in] capacity A property map of edge capacities.
151 *
152 * @return TValue The value of the flow. TValue is the Value tpye of the type of flow.
153 *
154 * @section Example
155 *
156 * @include demos/graph_algorithms/ford_fulkerson_algorithm.cpp
157 *
158 * @include demos/graph_algorithms/ford_fulkerson_algorithm.cpp.stdout
159 */
160 template <typename TSpec, typename TVertexDescriptor, typename TCapMap, typename TFlowMap>
161 typename Value<TFlowMap>::Type
fordFulkersonAlgorithm(TFlowMap & flow,Graph<TSpec> const & g,TVertexDescriptor const source,TVertexDescriptor const sink,TCapMap const & capacity)162 fordFulkersonAlgorithm(TFlowMap & flow,
163 Graph<TSpec> const & g,
164 TVertexDescriptor const source,
165 TVertexDescriptor const sink,
166 TCapMap const & capacity)
167 {
168 typedef Graph<TSpec> TGraph;
169 typedef typename EdgeDescriptor<TGraph>::Type TEdgeDescriptor;
170 typedef typename Iterator<TGraph, EdgeIterator>::Type TEdgeIterator;
171 typedef typename Iterator<TGraph, OutEdgeIterator>::Type TOutEdgeIterator;
172 typedef typename Value<TFlowMap>::Type TFlow;
173
174 // Initialization
175 TVertexDescriptor nilPred = getNil<typename VertexDescriptor<TGraph>::Type>();
176 resizeEdgeMap(flow, g);
177 TEdgeIterator itE(g);
178 for(;!atEnd(itE);goNext(itE)) {
179 assignProperty(flow, getValue(itE), 0);
180 }
181
182 // Build the residual graph
183 Graph<Directed<TFlow> > rG;
184 _buildResidualGraph(g,capacity, flow, rG);
185
186
187 // Determine whether the sink is reachable
188 String<TVertexDescriptor> predMap;
189 String<TVertexDescriptor> distMap;
190 breadthFirstSearch(predMap, distMap, rG, source);
191
192 while (getProperty(predMap, sink) != nilPred) {
193 TFlow inc = _getMinimumAug(rG, predMap, source, sink);
194 TEdgeIterator itEdge(g);
195 for(;!atEnd(itEdge);goNext(itEdge)) {
196 TVertexDescriptor u = sourceVertex(itEdge);
197 TVertexDescriptor v = targetVertex(itEdge);
198 TEdgeDescriptor e = getValue(itEdge);
199 if (getProperty(predMap, v) == u) assignProperty(flow, e, getProperty(flow, e) + inc);
200 if (getProperty(predMap, u) == v) assignProperty(flow, e, getProperty(flow, e) - inc);
201 }
202 // Build the residual graph
203 _buildResidualGraph(g, capacity, flow, rG);
204 // Determine whether the sink is reachable
205 clear(predMap);
206 clear(distMap);
207 breadthFirstSearch(predMap, distMap, rG, source);
208 }
209
210 TFlow valF = 0;
211 TOutEdgeIterator itOutEdge(g, source);
212 for(;!atEnd(itOutEdge);goNext(itOutEdge)) {
213 valF += getProperty(flow, getValue(itOutEdge));
214 }
215 return valF;
216 }
217
218 } // namespace seqan
219
220 #endif // #ifndef INCLUDE_SEQAN_GRAPH_ALGORITHMS_FORD_FULKERSON_H_
221