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>
15 #include <hugo/for_each_macros.h>
16 #include <hugo/unionfind.h>
17 #include <hugo/bin_heap.h>
25 ///\brief Implementation of an algorithm for solving the minimum cost general
26 /// flow problem in an uncapacitated network
29 /// The class \ref hugo::MinCostFlow "MinCostFlow" implements
30 /// an algorithm for solving the following general minimum cost flow problem>
34 /// \warning It is assumed here that the problem has a feasible solution
36 /// The range of the cost (weight) function is nonnegative reals but
37 /// the range of capacity function is the set of nonnegative integers.
38 /// It is not a polinomial time algorithm for counting the minimum cost
39 /// maximal flow, since it counts the minimum cost flow for every value 0..M
40 /// where \c M is the value of the maximal flow.
42 ///\author Attila Bernath
43 template <typename Graph, typename CostMap, typename SupplyDemandMap>
46 typedef typename CostMap::ValueType Cost;
49 typedef typename SupplyDemandMap::ValueType SupplyDemand;
51 typedef typename Graph::Node Node;
52 typedef typename Graph::NodeIt NodeIt;
53 typedef typename Graph::Edge Edge;
54 typedef typename Graph::OutEdgeIt OutEdgeIt;
55 typedef typename Graph::template EdgeMap<SupplyDemand> FlowMap;
56 typedef ConstMap<Edge,SupplyDemand> ConstEdgeMap;
58 // typedef ConstMap<Edge,int> ConstMap;
60 typedef ResGraphWrapper<const Graph,int,ConstEdgeMap,FlowMap> ResGraph;
61 typedef typename ResGraph::Edge ResGraphEdge;
64 //typedef typename ResGraph::template NodeMap<Cost> NodeMap;
65 typedef typename Graph::template NodeMap<Cost> NodeMap;
66 const ResGraph& res_graph;
67 // const EdgeIntMap& rev;
71 typedef typename CostMap::KeyType KeyType;
72 typedef typename CostMap::ValueType ValueType;
74 ValueType operator[](typename ResGraph::Edge e) const {
75 if (res_graph.forward(e))
76 return ol[e]-(pot[res_graph.head(e)]-pot[res_graph.tail(e)]);
78 return -ol[e]-(pot[res_graph.head(e)]-pot[res_graph.tail(e)]);
81 ModCostMap(const ResGraph& _res_graph,
82 const CostMap &o, const NodeMap &p) :
83 res_graph(_res_graph), /*rev(_rev),*/ ol(o), pot(p){};
92 const SupplyDemandMap& supply_demand;//supply or demand of nodes
99 //To store the potential (dual variables)
100 typedef typename Graph::template NodeMap<Cost> PotentialMap;
101 PotentialMap potential;
102 //To store excess-deficit values
103 SupplyDemandMap excess_deficit;
112 MinCostFlow(Graph& _graph, CostMap& _cost, SupplyDemandMap& _supply_demand):
115 supply_demand(_supply_demand),
118 excess_deficit(_graph){ }
121 ///Runs the algorithm.
123 ///Runs the algorithm.
125 ///\todo May be it does make sense to be able to start with a nonzero
126 /// feasible primal-dual solution pair as well.
129 //Resetting variables from previous runs
132 typedef typename Graph::template NodeMap<int> HeapMap;
133 typedef BinHeap< Node, SupplyDemand, typename Graph::template NodeMap<int>,
134 std::greater<SupplyDemand> > HeapType;
136 //A heap for the excess nodes
137 HeapMap excess_nodes_map(graph,-1);
138 HeapType excess_nodes(excess_nodes_map);
140 //A heap for the deficit nodes
141 HeapMap deficit_nodes_map(graph,-1);
142 HeapType deficit_nodes(deficit_nodes_map);
144 //A container to store nonabundant arcs
145 std::list<Edge> nonabundant_arcs;
148 FOR_EACH_LOC(typename Graph::EdgeIt, e, graph){
150 nonabundant_arcs.push_back(e);
153 //Initial value for delta
154 SupplyDemand delta = 0;
156 typedef UnionFindEnum<Node, Graph::template NodeMap> UFE;
158 //A union-find structure to store the abundant components
159 typename UFE::MapType abund_comp_map(graph);
160 UFE abundant_components(abund_comp_map);
164 FOR_EACH_LOC(typename Graph::NodeIt, n, graph){
165 excess_deficit.set(n,supply_demand[n]);
167 if (excess_deficit[n] > 0){
168 excess_nodes.push(n,excess_deficit[n]);
171 if (excess_deficit[n] < 0){
172 deficit_nodes.push(n, - excess_deficit[n]);
174 //Finding out starting value of delta
175 if (delta < abs(excess_deficit[n])){
176 delta = abs(excess_deficit[n]);
178 //Initialize the copy of the Dijkstra potential to zero
180 //Every single point is an abundant component initially
181 abundant_components.insert(n);
184 //It'll be allright as an initial value, though this value
185 //can be the maximum deficit here
186 SupplyDemand max_excess = delta;
188 ///\bug This is a serious cheat here, before we have an uncapacitated ResGraph
189 ConstEdgeMap const_inf_map(MAXINT);
191 //We need a residual graph which is uncapacitated
192 ResGraph res_graph(graph, const_inf_map, flow);
194 //An EdgeMap to tell which arcs are abundant
195 typename Graph::template EdgeMap<bool> abundant_arcs(graph);
197 //Let's construct the sugraph consisting only of the abundant edges
198 typedef ConstMap< typename Graph::Node, bool > ConstNodeMap;
199 ConstNodeMap const_true_map(true);
200 typedef SubGraphWrapper< const Graph, ConstNodeMap,
201 typename Graph::template EdgeMap<bool> >
203 AbundantGraph abundant_graph(graph, const_true_map, abundant_arcs );
205 //Let's construct the residual graph for the abundant graph
206 typedef ResGraphWrapper<const AbundantGraph,int,ConstEdgeMap,FlowMap>
208 //Again uncapacitated
209 ResAbGraph res_ab_graph(abundant_graph, const_inf_map, flow);
211 //We need things for the bfs
212 typename ResAbGraph::template NodeMap<bool> bfs_reached(res_ab_graph);
213 typename ResAbGraph::template NodeMap<typename ResAbGraph::Edge>
214 bfs_pred(res_ab_graph);
215 NullMap<typename ResAbGraph::Node, int> bfs_dist_dummy;
216 //We want to run bfs-es (more) on this graph 'res_ab_graph'
218 typename ResAbGraph::template NodeMap<bool>,
219 typename ResAbGraph::template NodeMap<typename ResAbGraph::Edge>,
220 NullMap<typename ResAbGraph::Node, int> >
221 bfs(res_ab_graph, bfs_reached, bfs_pred, bfs_dist_dummy);
222 /*This is what Marci wants for a bfs
223 template <typename Graph,
224 typename ReachedMap=typename Graph::template NodeMap<bool>,
226 =typename Graph::template NodeMap<typename Graph::Edge>,
227 typename DistMap=typename Graph::template NodeMap<int> >
228 class Bfs : public BfsIterator<Graph, ReachedMap> {
232 ModCostMap mod_cost(res_graph, cost, potential);
234 Dijkstra<ResGraph, ModCostMap> dijkstra(res_graph, mod_cost);
237 while (max_excess > 0){
239 //Reset delta if still too big
240 if (8*number_of_nodes*max_excess <= delta){
246 * Beginning of the delta scaling phase
250 SupplyDemand buf=8*number_of_nodes*delta;
251 typename std::list<Edge>::iterator i = nonabundant_arcs.begin();
252 while ( i != nonabundant_arcs.end() ){
254 Node a = abundant_components.find(res_graph.head(i));
255 Node b = abundant_components.find(res_graph.tail(i));
258 abundant_components.join(a,b);
259 //We want to push the smaller
260 //Which has greater absolut value excess/deficit
261 Node root=(abs(excess_deficit[a])>abs(excess_deficit[b]))?a:b;
263 Node non_root = ( a == root ) ? b : a ;
264 abundant_components.makeRep(root);
265 SupplyDemand qty_to_augment = abs(excess_deficit[non_root]);
266 //Push the positive value
267 if (excess_deficit[non_root] < 0)
268 swap(root, non_root);
269 //If the non_root node has excess/deficit at all
270 if (qty_to_augment>0){
271 //Find path and augment
273 //root should be reached
275 //Augmenting on the found path
280 n = res_graph.tail(e);
281 res_graph.augment(e,qty_to_augment);
284 //We know that non_root had positive excess
285 excess_nodes[non_root] -= qty_to_augment;
286 //But what about root node
287 //It might have been positive and so became larger
288 if (excess_deficit[root]>0){
289 excess_nodes[root] += qty_to_augment;
292 //Or negative but not turned into positive
293 deficit_nodes[root] -= qty_to_augment;
296 //Update the excess_deficit map
297 excess_deficit[non_root] -= qty_to_augment;
298 excess_deficit[root] += qty_to_augment;
304 //Marci and Zsolt says I shouldn't do such things
305 nonabundant_arcs.erase(i++);
306 abundant_arcs[i] = true;
314 Node s = excess_nodes.top();
315 SupplyDemand max_excess = excess_nodes[s];
316 Node t = deficit_nodes.top();
317 if (max_excess < deficit_nodes[t]){
318 max_excess = deficit_nodes[t];
322 while(max_excess > (number_of_nodes-1)*delta/number_of_nodes){
330 /*We know from theory that t can be reached
331 if (!dijkstra.reached(t)){
332 //There are no k paths from s to t
337 //We have to change the potential
338 FOR_EACH_LOC(typename ResGraph::NodeIt, n, res_graph){
339 potential[n] += dijkstra.distMap()[n];
343 //Augmenting on the sortest path
347 e = dijkstra.pred(n);
348 n = dijkstra.predNode(n);
349 res_graph.augment(e,delta);
351 //Let's update the total cost
352 if (res_graph.forward(e))
353 total_cost += cost[e];
355 total_cost -= cost[e];
359 //Update the excess_deficit map
360 excess_deficit[s] -= delta;
361 excess_deficit[t] += delta;
364 //Update the excess_nodes heap
365 if (delta >= excess_nodes[s]){
366 if (delta > excess_nodes[s])
367 deficit_nodes.push(s,delta - excess_nodes[s]);
372 excess_nodes[s] -= delta;
374 //Update the deficit_nodes heap
375 if (delta >= deficit_nodes[t]){
376 if (delta > deficit_nodes[t])
377 excess_nodes.push(t,delta - deficit_nodes[t]);
382 deficit_nodes[t] -= delta;
384 //Dijkstra part ends here
386 //Choose s and t again
387 s = excess_nodes.top();
388 max_excess = excess_nodes[s];
389 t = deficit_nodes.top();
390 if (max_excess < deficit_nodes[t]){
391 max_excess = deficit_nodes[t];
397 * End of the delta scaling phase
400 //Whatever this means
403 /*This is not necessary here
404 //Update the max_excess
406 FOR_EACH_LOC(typename Graph::NodeIt, n, graph){
407 if (max_excess < excess_deficit[n]){
408 max_excess = excess_deficit[n];
414 }//while(max_excess > 0)
423 ///This function gives back the total cost of the found paths.
424 ///Assumes that \c run() has been run and nothing changed since then.
429 ///Returns a const reference to the EdgeMap \c flow. \pre \ref run() must
430 ///be called before using this function.
431 const FlowMap &getFlow() const { return flow;}
433 ///Returns a const reference to the NodeMap \c potential (the dual solution).
434 /// \pre \ref run() must be called before using this function.
435 const PotentialMap &getPotential() const { return potential;}
437 ///This function checks, whether the given solution is optimal
438 ///Running after a \c run() should return with true
439 ///In this "state of the art" this only check optimality, doesn't bother with feasibility
441 ///\todo Is this OK here?
442 bool checkComplementarySlackness(){
445 FOR_EACH_LOC(typename Graph::EdgeIt, e, graph){
447 mod_pot = cost[e]-potential[graph.head(e)]+potential[graph.tail(e)];
449 // std::cout << fl_e << std::endl;
450 if (0<fl_e && fl_e<capacity[e]){
455 if (mod_pot > 0 && fl_e != 0)
457 if (mod_pot < 0 && fl_e != capacity[e])
465 }; //class MinCostFlow
471 #endif //HUGO_MINCOSTFLOW_H