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>
13 #include <for_each_macros.h>
20 ///\brief Implementation of an algorithm for finding the minimum cost flow
21 /// of given value in an uncapacitated network
24 /// The class \ref hugo::MinCostFlow "MinCostFlow" implements
25 /// an algorithm for solving the following general minimum cost flow problem>
29 /// \warning It is assumed here that the problem has a feasible solution
31 /// The range of the length (weight) function is nonnegative reals but
32 /// the range of capacity function is the set of nonnegative integers.
33 /// It is not a polinomial time algorithm for counting the minimum cost
34 /// maximal flow, since it counts the minimum cost flow for every value 0..M
35 /// where \c M is the value of the maximal flow.
37 ///\author Attila Bernath
38 template <typename Graph, typename LengthMap, typename SupplyDemandMap>
41 typedef typename LengthMap::ValueType Length;
44 typedef typename SupplyDemandMap::ValueType SupplyDemand;
46 typedef typename Graph::Node Node;
47 typedef typename Graph::NodeIt NodeIt;
48 typedef typename Graph::Edge Edge;
49 typedef typename Graph::OutEdgeIt OutEdgeIt;
50 typedef typename Graph::template EdgeMap<int> EdgeIntMap;
52 // typedef ConstMap<Edge,int> ConstMap;
54 typedef ResGraphWrapper<const Graph,int,CapacityMap,EdgeIntMap> ResGraphType;
55 typedef typename ResGraphType::Edge ResGraphEdge;
58 //typedef typename ResGraphType::template NodeMap<Length> NodeMap;
59 typedef typename Graph::template NodeMap<Length> NodeMap;
60 const ResGraphType& G;
61 // const EdgeIntMap& rev;
65 typedef typename LengthMap::KeyType KeyType;
66 typedef typename LengthMap::ValueType ValueType;
68 ValueType operator[](typename ResGraphType::Edge e) const {
70 return ol[e]-(pot[G.head(e)]-pot[G.tail(e)]);
72 return -ol[e]-(pot[G.head(e)]-pot[G.tail(e)]);
75 ModLengthMap(const ResGraphType& _G,
76 const LengthMap &o, const NodeMap &p) :
77 G(_G), /*rev(_rev),*/ ol(o), pot(p){};
85 const LengthMap& length;
86 const SupplyDemandMap& supply_demand;//supply or demand of nodes
93 //To store the potentila (dual variables)
94 typename Graph::template NodeMap<Length> potential;
95 //To store excess-deficit values
96 SupplyDemandMap excess_deficit;
105 MinCostFlow(Graph& _G, LengthMap& _length, SupplyDemandMap& _supply_demand) : G(_G),
106 length(_length), supply_demand(_supply_demand), flow(_G), potential(_G){ }
109 ///Runs the algorithm.
111 ///Runs the algorithm.
113 ///\todo May be it does make sense to be able to start with a nonzero
114 /// feasible primal-dual solution pair as well.
117 //Resetting variables from previous runs
120 typedef typename Graph::template NodeMap<int> HeapMap;
121 typedef Heap<Node, SupplyDemand, typename Graph::template NodeMap<int>,
122 std::greater<SupplyDemand> > HeapType;
124 //A heap for the excess nodes
125 HeapMap excess_nodes_map(G,-1);
126 HeapType excess_nodes(excess_nodes_map);
128 //A heap for the deficit nodes
129 HeapMap deficit_nodes_map(G,-1);
130 HeapType deficit_nodes(deficit_nodes_map);
133 FOR_EACH_LOC(typename Graph::EdgeIt, e, G){
137 //Initial value for delta
138 SupplyDemand delta = 0;
140 FOR_EACH_LOC(typename Graph::NodeIt, n, G){
141 excess_deficit.set(n,supply_demand[n]);
143 if (excess_deficit[n] > 0){
144 excess_nodes.push(n,excess_deficit[n]);
147 if (excess_deficit[n] < 0){
148 deficit_nodes.push(n, - excess_deficit[n]);
150 //Finding out starting value of delta
151 if (delta < abs(excess_deficit[n])){
152 delta = abs(excess_deficit[n]);
154 //Initialize the copy of the Dijkstra potential to zero
158 //It'll be allright as an initial value, though this value
159 //can be the maximum deficit here
160 SupplyDemand max_excess = delta;
162 //We need a residual graph which is uncapacitated
163 ResGraphType res_graph(G, flow);
167 ModLengthMap mod_length(res_graph, length, potential);
169 Dijkstra<ResGraphType, ModLengthMap> dijkstra(res_graph, mod_length);
172 while (max_excess > 0){
175 * Beginning of the delta scaling phase
180 Node s = excess_nodes.top();
181 SupplyDemand max_excess = excess_nodes[s];
182 Node t = deficit_nodes.top();
183 if (max_excess < dificit_nodes[t]){
184 max_excess = dificit_nodes[t];
188 while(max_excess > 0){
196 /*We know from theory that t can be reached
197 if (!dijkstra.reached(t)){
198 //There are no k paths from s to t
203 //We have to change the potential
204 FOR_EACH_LOC(typename ResGraphType::NodeIt, n, res_graph){
205 potential[n] += dijkstra.distMap()[n];
209 //Augmenting on the sortest path
213 e = dijkstra.pred(n);
214 n = dijkstra.predNode(n);
215 res_graph.augment(e,delta);
217 //Let's update the total length
218 if (res_graph.forward(e))
219 total_length += length[e];
221 total_length -= length[e];
225 //Update the excess_nodes heap
226 if (delta >= excess_nodes[s]){
227 if (delta > excess_nodes[s])
228 deficit_nodes.push(s,delta - excess_nodes[s]);
233 excess_nodes[s] -= delta;
235 //Update the deficit_nodes heap
236 if (delta >= deficit_nodes[t]){
237 if (delta > deficit_nodes[t])
238 excess_nodes.push(t,delta - deficit_nodes[t]);
243 deficit_nodes[t] -= delta;
245 //Dijkstra part ends here
249 * End of the delta scaling phase
252 //Whatever this means
255 /*This is not necessary here
256 //Update the max_excess
258 FOR_EACH_LOC(typename Graph::NodeIt, n, G){
259 if (max_excess < excess_deficit[n]){
260 max_excess = excess_deficit[n];
264 //Reset delta if still too big
265 if (8*number_of_nodes*max_excess <= delta){
270 }//while(max_excess > 0)
279 ///This function gives back the total length of the found paths.
280 ///Assumes that \c run() has been run and nothing changed since then.
281 Length totalLength(){
285 ///Returns a const reference to the EdgeMap \c flow. \pre \ref run() must
286 ///be called before using this function.
287 const EdgeIntMap &getFlow() const { return flow;}
289 ///Returns a const reference to the NodeMap \c potential (the dual solution).
290 /// \pre \ref run() must be called before using this function.
291 const EdgeIntMap &getPotential() const { return potential;}
293 ///This function checks, whether the given solution is optimal
294 ///Running after a \c run() should return with true
295 ///In this "state of the art" this only check optimality, doesn't bother with feasibility
297 ///\todo Is this OK here?
298 bool checkComplementarySlackness(){
301 FOR_EACH_LOC(typename Graph::EdgeIt, e, G){
303 mod_pot = length[e]-potential[G.head(e)]+potential[G.tail(e)];
305 // std::cout << fl_e << std::endl;
306 if (0<fl_e && fl_e<capacity[e]){
311 if (mod_pot > 0 && fl_e != 0)
313 if (mod_pot < 0 && fl_e != capacity[e])
321 }; //class MinCostFlow
327 #endif //HUGO_MINCOSTFLOW_H