Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

min_cost_flow.h

Go to the documentation of this file.
00001 /* -*- C++ -*-
00002  * lemon/min_cost_flow.h - Part of LEMON, a generic C++ optimization library
00003  *
00004  * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
00005  * (Egervary Research Group on Combinatorial Optimization, EGRES).
00006  *
00007  * Permission to use, modify and distribute this software is granted
00008  * provided that this copyright notice appears in all copies. For
00009  * precise terms see the accompanying LICENSE file.
00010  *
00011  * This software is provided "AS IS" with no warranty of any kind,
00012  * express or implied, and with no claim as to its suitability for any
00013  * purpose.
00014  *
00015  */
00016 
00017 #ifndef LEMON_MIN_COST_FLOW_H
00018 #define LEMON_MIN_COST_FLOW_H
00019 
00023 
00024 
00025 #include <lemon/dijkstra.h>
00026 #include <lemon/graph_adaptor.h>
00027 #include <lemon/maps.h>
00028 #include <vector>
00029 
00030 namespace lemon {
00031 
00034 
00057   template <typename Graph, typename LengthMap, typename CapacityMap>
00058   class MinCostFlow {
00059 
00060     typedef typename LengthMap::Value Length;
00061 
00062     //Warning: this should be integer type
00063     typedef typename CapacityMap::Value Capacity;
00064     
00065     typedef typename Graph::Node Node;
00066     typedef typename Graph::NodeIt NodeIt;
00067     typedef typename Graph::Edge Edge;
00068     typedef typename Graph::OutEdgeIt OutEdgeIt;
00069     typedef typename Graph::template EdgeMap<int> EdgeIntMap;
00070 
00071     typedef ResGraphAdaptor<const Graph,int,CapacityMap,EdgeIntMap> ResGW;
00072     typedef typename ResGW::Edge ResGraphEdge;
00073 
00074   protected:
00075 
00076     const Graph& g;
00077     const LengthMap& length;
00078     const CapacityMap& capacity;
00079 
00080     EdgeIntMap flow; 
00081     typedef typename Graph::template NodeMap<Length> PotentialMap;
00082     PotentialMap potential;
00083 
00084     Node s;
00085     Node t;
00086     
00087     Length total_length;
00088 
00089     class ModLengthMap {   
00090       typedef typename Graph::template NodeMap<Length> NodeMap;
00091       const ResGW& g;
00092       const LengthMap &length;
00093       const NodeMap &pot;
00094     public :
00095       typedef typename LengthMap::Key Key;
00096       typedef typename LengthMap::Value Value;
00097 
00098       ModLengthMap(const ResGW& _g, 
00099                    const LengthMap &_length, const NodeMap &_pot) : 
00100         g(_g), /*rev(_rev),*/ length(_length), pot(_pot) { }
00101         
00102       Value operator[](typename ResGW::Edge e) const {     
00103         if (g.forward(e))
00104           return  length[e]-(pot[g.target(e)]-pot[g.source(e)]);   
00105         else
00106           return -length[e]-(pot[g.target(e)]-pot[g.source(e)]);   
00107       }     
00108         
00109     }; //ModLengthMap
00110 
00111     ResGW res_graph;
00112     ModLengthMap mod_length;
00113     Dijkstra<ResGW, ModLengthMap> dijkstra;
00114 
00115   public :
00116 
00125     MinCostFlow(Graph& _g, LengthMap& _length, CapacityMap& _cap, 
00126                 Node _s, Node _t) : 
00127       g(_g), length(_length), capacity(_cap), flow(_g), potential(_g), 
00128       s(_s), t(_t), 
00129       res_graph(g, capacity, flow), 
00130       mod_length(res_graph, length, potential),
00131       dijkstra(res_graph, mod_length) { 
00132       reset();
00133       }
00134 
00138     bool augment() {
00139       dijkstra.run(s);
00140       if (!dijkstra.reached(t)) {
00141 
00142         //Unsuccessful augmentation.
00143         return false;
00144       } else {
00145 
00146         //We have to change the potential
00147         for(typename ResGW::NodeIt n(res_graph); n!=INVALID; ++n)
00148           potential.set(n, potential[n]+dijkstra.distMap()[n]);
00149         
00150         //Augmenting on the shortest path
00151         Node n=t;
00152         ResGraphEdge e;
00153         while (n!=s){
00154           e = dijkstra.pred(n);
00155           n = dijkstra.predNode(n);
00156           res_graph.augment(e,1);
00157           //Let's update the total length
00158           if (res_graph.forward(e))
00159             total_length += length[e];
00160           else 
00161             total_length -= length[e];      
00162         }
00163 
00164         return true;
00165       }
00166     }
00167     
00182     int run(int k) {
00183       if (flowValue()>k) reset();
00184       while (flowValue()<k && augment()) { }
00185       return flowValue();
00186     }
00187 
00191     void reset() {
00192       total_length=0;
00193       for (typename Graph::EdgeIt e(g); e!=INVALID; ++e) flow.set(e, 0);
00194       for (typename Graph::NodeIt n(g); n!=INVALID; ++n) potential.set(n, 0);  
00195     }
00196 
00199     int flowValue() const {
00200       int i=0;
00201       for (typename Graph::OutEdgeIt e(g, s); e!=INVALID; ++e) i+=flow[e];
00202       for (typename Graph::InEdgeIt e(g, s); e!=INVALID; ++e) i-=flow[e];
00203       return i;
00204     }
00205 
00207 
00209     Length totalLength(){
00210       return total_length;
00211     }
00212 
00214 
00216     const EdgeIntMap &getFlow() const { return flow;}
00217 
00222     const PotentialMap &getPotential() const { return potential;}
00223 
00231     bool checkComplementarySlackness(){
00232       Length mod_pot;
00233       Length fl_e;
00234         for(typename Graph::EdgeIt e(g); e!=INVALID; ++e) {
00235         //C^{\Pi}_{i,j}
00236         mod_pot = length[e]-potential[g.target(e)]+potential[g.source(e)];
00237         fl_e = flow[e];
00238         if (0<fl_e && fl_e<capacity[e]) {
00241           if (mod_pot != 0)
00242             return false;
00243         } 
00244         else {
00245           if (mod_pot > 0 && fl_e != 0)
00246             return false;
00247           if (mod_pot < 0 && fl_e != capacity[e])
00248             return false;
00249         }
00250       }
00251       return true;
00252     }
00253     
00254   }; //class MinCostFlow
00255 
00257 
00258 } //namespace lemon
00259 
00260 #endif //LEMON_MIN_COST_FLOW_H

Generated on Sat Aug 27 14:14:54 2005 for LEMON by  doxygen 1.4.4