2 #ifndef HUGO_MINCOSTFLOW_H
3 #define HUGO_MINCOSTFLOW_H
7 ///\brief An algorithm for finding the minimum cost flow of given value in an uncapacitated network
9 #include <hugo/dijkstra.h>
10 #include <hugo/graph_wrapper.h>
11 #include <hugo/maps.h>
14 #include <for_each_macros.h>
15 #include <hugo/union_find.h>
22 ///\brief Implementation of an algorithm for finding the minimum cost flow
23 /// of given value in an uncapacitated network
26 /// The class \ref hugo::MinCostFlow "MinCostFlow" implements
27 /// an algorithm for solving the following general minimum cost flow problem>
31 /// \warning It is assumed here that the problem has a feasible solution
33 /// The range of the length (weight) function is nonnegative reals but
34 /// the range of capacity function is the set of nonnegative integers.
35 /// It is not a polinomial time algorithm for counting the minimum cost
36 /// maximal flow, since it counts the minimum cost flow for every value 0..M
37 /// where \c M is the value of the maximal flow.
39 ///\author Attila Bernath
40 template <typename Graph, typename LengthMap, typename SupplyDemandMap>
43 typedef typename LengthMap::ValueType Length;
46 typedef typename SupplyDemandMap::ValueType SupplyDemand;
48 typedef typename Graph::Node Node;
49 typedef typename Graph::NodeIt NodeIt;
50 typedef typename Graph::Edge Edge;
51 typedef typename Graph::OutEdgeIt OutEdgeIt;
52 typedef typename Graph::template EdgeMap<int> EdgeIntMap;
54 // typedef ConstMap<Edge,int> ConstMap;
56 typedef ResGraphWrapper<const Graph,int,CapacityMap,EdgeIntMap> ResGraphType;
57 typedef typename ResGraphType::Edge ResGraphEdge;
60 //typedef typename ResGraphType::template NodeMap<Length> NodeMap;
61 typedef typename Graph::template NodeMap<Length> NodeMap;
62 const ResGraphType& G;
63 // const EdgeIntMap& rev;
67 typedef typename LengthMap::KeyType KeyType;
68 typedef typename LengthMap::ValueType ValueType;
70 ValueType operator[](typename ResGraphType::Edge e) const {
72 return ol[e]-(pot[G.head(e)]-pot[G.tail(e)]);
74 return -ol[e]-(pot[G.head(e)]-pot[G.tail(e)]);
77 ModLengthMap(const ResGraphType& _G,
78 const LengthMap &o, const NodeMap &p) :
79 G(_G), /*rev(_rev),*/ ol(o), pot(p){};
87 const LengthMap& length;
88 const SupplyDemandMap& supply_demand;//supply or demand of nodes
95 //To store the potentila (dual variables)
96 typename Graph::template NodeMap<Length> potential;
97 //To store excess-deficit values
98 SupplyDemandMap excess_deficit;
107 MinCostFlow(Graph& _G, LengthMap& _length, SupplyDemandMap& _supply_demand) : G(_G),
108 length(_length), supply_demand(_supply_demand), flow(_G), potential(_G){ }
111 ///Runs the algorithm.
113 ///Runs the algorithm.
115 ///\todo May be it does make sense to be able to start with a nonzero
116 /// feasible primal-dual solution pair as well.
119 //Resetting variables from previous runs
122 typedef typename Graph::template NodeMap<int> HeapMap;
123 typedef Heap< Node, SupplyDemand, typename Graph::template NodeMap<int>,
124 std::greater<SupplyDemand> > HeapType;
126 //A heap for the excess nodes
127 HeapMap excess_nodes_map(G,-1);
128 HeapType excess_nodes(excess_nodes_map);
130 //A heap for the deficit nodes
131 HeapMap deficit_nodes_map(G,-1);
132 HeapType deficit_nodes(deficit_nodes_map);
134 //A container to store nonabundant arcs
135 list<Edge> nonabundant_arcs;
137 FOR_EACH_LOC(typename Graph::EdgeIt, e, G){
139 nonabundant_arcs.push_back(e);
142 //Initial value for delta
143 SupplyDemand delta = 0;
145 typedef UnionFindEnum<Node, Graph::template NodeMap> UFE;
147 //A union-find structure to store the abundant components
148 UFE::MapType abund_comp_map(G);
149 UFE abundant_components(abund_comp_map);
153 FOR_EACH_LOC(typename Graph::NodeIt, n, G){
154 excess_deficit.set(n,supply_demand[n]);
156 if (excess_deficit[n] > 0){
157 excess_nodes.push(n,excess_deficit[n]);
160 if (excess_deficit[n] < 0){
161 deficit_nodes.push(n, - excess_deficit[n]);
163 //Finding out starting value of delta
164 if (delta < abs(excess_deficit[n])){
165 delta = abs(excess_deficit[n]);
167 //Initialize the copy of the Dijkstra potential to zero
169 //Every single point is an abundant component initially
170 abundant_components.insert(n);
173 //It'll be allright as an initial value, though this value
174 //can be the maximum deficit here
175 SupplyDemand max_excess = delta;
177 //We need a residual graph which is uncapacitated
178 ResGraphType res_graph(G, flow);
182 ModLengthMap mod_length(res_graph, length, potential);
184 Dijkstra<ResGraphType, ModLengthMap> dijkstra(res_graph, mod_length);
187 while (max_excess > 0){
189 //Reset delta if still too big
190 if (8*number_of_nodes*max_excess <= delta){
196 * Beginning of the delta scaling phase
200 SupplyDemand buf=8*number_of_nodes*delta;
201 list<Edge>::iterator i = nonabundant_arcs.begin();
202 while ( i != nonabundant_arcs.end() ){
204 Node a = abundant_components.find(res_graph.head(i));
205 Node b = abundant_components.find(res_graph.tail(i));
208 //Find path and augment
210 //Find path and augment
211 abundant_components.join(a,b);
214 nonabundant_arcs.erase(i);
222 Node s = excess_nodes.top();
223 SupplyDemand max_excess = excess_nodes[s];
224 Node t = deficit_nodes.top();
225 if (max_excess < dificit_nodes[t]){
226 max_excess = dificit_nodes[t];
230 while(max_excess > 0){
238 /*We know from theory that t can be reached
239 if (!dijkstra.reached(t)){
240 //There are no k paths from s to t
245 //We have to change the potential
246 FOR_EACH_LOC(typename ResGraphType::NodeIt, n, res_graph){
247 potential[n] += dijkstra.distMap()[n];
251 //Augmenting on the sortest path
255 e = dijkstra.pred(n);
256 n = dijkstra.predNode(n);
257 res_graph.augment(e,delta);
259 //Let's update the total length
260 if (res_graph.forward(e))
261 total_length += length[e];
263 total_length -= length[e];
267 //Update the excess_nodes heap
268 if (delta >= excess_nodes[s]){
269 if (delta > excess_nodes[s])
270 deficit_nodes.push(s,delta - excess_nodes[s]);
275 excess_nodes[s] -= delta;
277 //Update the deficit_nodes heap
278 if (delta >= deficit_nodes[t]){
279 if (delta > deficit_nodes[t])
280 excess_nodes.push(t,delta - deficit_nodes[t]);
285 deficit_nodes[t] -= delta;
287 //Dijkstra part ends here
291 * End of the delta scaling phase
294 //Whatever this means
297 /*This is not necessary here
298 //Update the max_excess
300 FOR_EACH_LOC(typename Graph::NodeIt, n, G){
301 if (max_excess < excess_deficit[n]){
302 max_excess = excess_deficit[n];
308 }//while(max_excess > 0)
317 ///This function gives back the total length of the found paths.
318 ///Assumes that \c run() has been run and nothing changed since then.
319 Length totalLength(){
323 ///Returns a const reference to the EdgeMap \c flow. \pre \ref run() must
324 ///be called before using this function.
325 const EdgeIntMap &getFlow() const { return flow;}
327 ///Returns a const reference to the NodeMap \c potential (the dual solution).
328 /// \pre \ref run() must be called before using this function.
329 const EdgeIntMap &getPotential() const { return potential;}
331 ///This function checks, whether the given solution is optimal
332 ///Running after a \c run() should return with true
333 ///In this "state of the art" this only check optimality, doesn't bother with feasibility
335 ///\todo Is this OK here?
336 bool checkComplementarySlackness(){
339 FOR_EACH_LOC(typename Graph::EdgeIt, e, G){
341 mod_pot = length[e]-potential[G.head(e)]+potential[G.tail(e)];
343 // std::cout << fl_e << std::endl;
344 if (0<fl_e && fl_e<capacity[e]){
349 if (mod_pot > 0 && fl_e != 0)
351 if (mod_pot < 0 && fl_e != capacity[e])
359 }; //class MinCostFlow
365 #endif //HUGO_MINCOSTFLOW_H