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