src/lemon/min_cost_flow.h
changeset 953 d9c115e2eeaf
parent 921 818510fa3d99
child 986 e997802b855c
equal deleted inserted replaced
0:6333d04a5530 1:4453aea55e06
    68     typedef typename Graph::NodeIt NodeIt;
    68     typedef typename Graph::NodeIt NodeIt;
    69     typedef typename Graph::Edge Edge;
    69     typedef typename Graph::Edge Edge;
    70     typedef typename Graph::OutEdgeIt OutEdgeIt;
    70     typedef typename Graph::OutEdgeIt OutEdgeIt;
    71     typedef typename Graph::template EdgeMap<int> EdgeIntMap;
    71     typedef typename Graph::template EdgeMap<int> EdgeIntMap;
    72 
    72 
    73 
       
    74     typedef ResGraphWrapper<const Graph,int,CapacityMap,EdgeIntMap> ResGW;
    73     typedef ResGraphWrapper<const Graph,int,CapacityMap,EdgeIntMap> ResGW;
    75     typedef typename ResGW::Edge ResGraphEdge;
    74     typedef typename ResGW::Edge ResGraphEdge;
    76 
    75 
       
    76   protected:
       
    77 
       
    78     const Graph& g;
       
    79     const LengthMap& length;
       
    80     const CapacityMap& capacity;
       
    81 
       
    82     EdgeIntMap flow; 
       
    83     typedef typename Graph::template NodeMap<Length> PotentialMap;
       
    84     PotentialMap potential;
       
    85 
       
    86     Node s;
       
    87     Node t;
       
    88     
       
    89     Length total_length;
       
    90 
    77     class ModLengthMap {   
    91     class ModLengthMap {   
    78       typedef typename Graph::template NodeMap<Length> NodeMap;
    92       typedef typename Graph::template NodeMap<Length> NodeMap;
    79       const ResGW& G;
    93       const ResGW& g;
    80       const LengthMap &ol;
    94       const LengthMap &length;
    81       const NodeMap &pot;
    95       const NodeMap &pot;
    82     public :
    96     public :
    83       typedef typename LengthMap::KeyType KeyType;
    97       typedef typename LengthMap::KeyType KeyType;
    84       typedef typename LengthMap::ValueType ValueType;
    98       typedef typename LengthMap::ValueType ValueType;
       
    99 
       
   100       ModLengthMap(const ResGW& _g, 
       
   101 		   const LengthMap &_length, const NodeMap &_pot) : 
       
   102 	g(_g), /*rev(_rev),*/ length(_length), pot(_pot) { }
    85 	
   103 	
    86       ValueType operator[](typename ResGW::Edge e) const {     
   104       ValueType operator[](typename ResGW::Edge e) const {     
    87 	if (G.forward(e))
   105 	if (g.forward(e))
    88 	  return  ol[e]-(pot[G.head(e)]-pot[G.tail(e)]);   
   106 	  return  length[e]-(pot[g.head(e)]-pot[g.tail(e)]);   
    89 	else
   107 	else
    90 	  return -ol[e]-(pot[G.head(e)]-pot[G.tail(e)]);   
   108 	  return -length[e]-(pot[g.head(e)]-pot[g.tail(e)]);   
    91       }     
   109       }     
    92 	
   110 	
    93       ModLengthMap(const ResGW& _G,
   111     }; //ModLengthMap
    94 		   const LengthMap &o,  const NodeMap &p) : 
   112 
    95 	G(_G), /*rev(_rev),*/ ol(o), pot(p){}; 
   113     ResGW res_graph;
    96     };//ModLengthMap
   114     ModLengthMap mod_length;
    97 
   115     Dijkstra<ResGW, ModLengthMap> dijkstra;
    98 
       
    99   protected:
       
   100     
       
   101     //Input
       
   102     const Graph& G;
       
   103     const LengthMap& length;
       
   104     const CapacityMap& capacity;
       
   105 
       
   106 
       
   107     //auxiliary variables
       
   108 
       
   109     //To store the flow
       
   110     EdgeIntMap flow; 
       
   111     //To store the potential (dual variables)
       
   112     typedef typename Graph::template NodeMap<Length> PotentialMap;
       
   113     PotentialMap potential;
       
   114     
       
   115 
       
   116     Length total_length;
       
   117 
       
   118 
   116 
   119   public :
   117   public :
   120 
   118 
   121     /// The constructor of the class.
   119     /*! \brief The constructor of the class.
   122     
   120     
   123     ///\param _G The directed graph the algorithm runs on. 
   121     \param _g The directed graph the algorithm runs on. 
   124     ///\param _length The length (weight or cost) of the edges. 
   122     \param _length The length (weight or cost) of the edges. 
   125     ///\param _cap The capacity of the edges. 
   123     \param _cap The capacity of the edges. 
   126     MinCostFlow(Graph& _G, LengthMap& _length, CapacityMap& _cap) : G(_G), 
   124     \param _s Source node.
   127       length(_length), capacity(_cap), flow(_G), potential(_G){ }
   125     \param _t Target node.
   128 
   126     */
   129     
   127     MinCostFlow(Graph& _g, LengthMap& _length, CapacityMap& _cap, 
   130     ///Runs the algorithm.
   128 		Node _s, Node _t) : 
   131     
   129       g(_g), length(_length), capacity(_cap), flow(_g), potential(_g), 
   132     ///Runs the algorithm.
   130       s(_s), t(_t), 
   133     ///Returns k if there is a flow of value at least k edge-disjoint 
   131       res_graph(g, capacity, flow), 
   134     ///from s to t.
   132       mod_length(res_graph, length, potential),
   135     ///Otherwise it returns the maximum value of a flow from s to t.
   133       dijkstra(res_graph, mod_length) { 
   136     ///
   134       reset();
   137     ///\param s The source node.
   135       }
   138     ///\param t The target node.
   136 
   139     ///\param k The value of the flow we are looking for.
   137     /*! Tries to augment the flow between s and t by 1.
   140     ///
   138       The return value shows if the augmentation is successful.
   141     ///\todo May be it does make sense to be able to start with a nonzero 
   139      */
   142     /// feasible primal-dual solution pair as well.
   140     bool augment() {
   143     int run(Node s, Node t, int k) {
   141       dijkstra.run(s);
   144 
   142       if (!dijkstra.reached(t)) {
   145       //Resetting variables from previous runs
   143 
   146       total_length = 0;
   144 	//Unsuccessful augmentation.
   147       
   145 	return false;
   148       for (typename Graph::EdgeIt e(G); e!=INVALID; ++e) flow.set(e, 0);
   146       } else {
   149 
   147 
   150       //Initialize the potential to zero
   148 	//We have to change the potential
   151       for (typename Graph::NodeIt n(G); n!=INVALID; ++n) potential.set(n, 0);
   149 	for(typename ResGW::NodeIt n(res_graph); n!=INVALID; ++n)
   152       
   150 	  potential[n] += dijkstra.distMap()[n];
   153       
       
   154       //We need a residual graph
       
   155       ResGW res_graph(G, capacity, flow);
       
   156 
       
   157 
       
   158       ModLengthMap mod_length(res_graph, length, potential);
       
   159 
       
   160       Dijkstra<ResGW, ModLengthMap> dijkstra(res_graph, mod_length);
       
   161 
       
   162       int i;
       
   163       for (i=0; i<k; ++i){
       
   164 	dijkstra.run(s);
       
   165 	if (!dijkstra.reached(t)){
       
   166 	  //There are no flow of value k from s to t
       
   167 	  break;
       
   168 	};
       
   169 	
   151 	
   170 	//We have to change the potential
       
   171         for(typename ResGW::NodeIt n(res_graph); n!=INVALID; ++n)
       
   172 	  potential[n] += dijkstra.distMap()[n];
       
   173 
       
   174 
       
   175 	//Augmenting on the sortest path
   152 	//Augmenting on the sortest path
   176 	Node n=t;
   153 	Node n=t;
   177 	ResGraphEdge e;
   154 	ResGraphEdge e;
   178 	while (n!=s){
   155 	while (n!=s){
   179 	  e = dijkstra.pred(n);
   156 	  e = dijkstra.pred(n);
   184 	    total_length += length[e];
   161 	    total_length += length[e];
   185 	  else 
   162 	  else 
   186 	    total_length -= length[e];	    
   163 	    total_length -= length[e];	    
   187 	}
   164 	}
   188 
   165 
   189 	  
   166 	return true;
   190       }
   167       }
   191       
   168     }
   192 
   169     
       
   170     /*! \brief Runs the algorithm.
       
   171     
       
   172     Runs the algorithm.
       
   173     Returns k if there is a flow of value at least k from s to t.
       
   174     Otherwise it returns the maximum value of a flow from s to t.
       
   175     
       
   176     \param k The value of the flow we are looking for.
       
   177     
       
   178     \todo May be it does make sense to be able to start with a nonzero 
       
   179     feasible primal-dual solution pair as well.
       
   180     
       
   181     \todo If the actual flow value is bigger than k, then everything is 
       
   182     cleared and the algorithm starts from zero flow. Is it a good approach?
       
   183     */
       
   184     int run(int k) {
       
   185       if (flowValue()>k) reset();
       
   186       while (flowValue()<k && augment()) { }
       
   187       return flowValue();
       
   188     }
       
   189 
       
   190     /*! \brief The class is reset to zero flow and potential.
       
   191       The class is reset to zero flow and potential.
       
   192      */
       
   193     void reset() {
       
   194       total_length=0;
       
   195       for (typename Graph::EdgeIt e(g); e!=INVALID; ++e) flow.set(e, 0);
       
   196       for (typename Graph::NodeIt n(g); n!=INVALID; ++n) potential.set(n, 0);  
       
   197     }
       
   198 
       
   199     /*! Returns the value of the actual flow. 
       
   200      */
       
   201     int flowValue() const {
       
   202       int i=0;
       
   203       for (typename Graph::OutEdgeIt e(g, s); e!=INVALID; ++e) i+=flow[e];
       
   204       for (typename Graph::InEdgeIt e(g, s); e!=INVALID; ++e) i-=flow[e];
   193       return i;
   205       return i;
   194     }
   206     }
   195 
   207 
   196 
   208     /// Total weight of the found flow.
   197 
   209 
   198     /// Gives back the total weight of the found flow.
   210     /// This function gives back the total weight of the found flow.
   199 
       
   200     ///This function gives back the total weight of the found flow.
       
   201     ///Assumes that \c run() has been run and nothing changed since then.
       
   202     Length totalLength(){
   211     Length totalLength(){
   203       return total_length;
   212       return total_length;
   204     }
   213     }
   205 
   214 
   206     ///Returns a const reference to the EdgeMap \c flow. 
   215     ///Returns a const reference to the EdgeMap \c flow. 
   207 
   216 
   208     ///Returns a const reference to the EdgeMap \c flow. 
   217     ///Returns a const reference to the EdgeMap \c flow. 
   209     ///\pre \ref run() must
       
   210     ///be called before using this function.
       
   211     const EdgeIntMap &getFlow() const { return flow;}
   218     const EdgeIntMap &getFlow() const { return flow;}
   212 
   219 
   213     ///Returns a const reference to the NodeMap \c potential (the dual solution).
   220     /*! \brief Returns a const reference to the NodeMap \c potential (the dual solution).
   214 
   221 
   215     ///Returns a const reference to the NodeMap \c potential (the dual solution).
   222     Returns a const reference to the NodeMap \c potential (the dual solution).
   216     /// \pre \ref run() must be called before using this function.
   223     */
   217     const PotentialMap &getPotential() const { return potential;}
   224     const PotentialMap &getPotential() const { return potential;}
   218 
   225 
   219     /// Checking the complementary slackness optimality criteria
   226     /*! \brief Checking the complementary slackness optimality criteria.
   220 
   227 
   221     ///This function checks, whether the given solution is optimal
   228     This function checks, whether the given flow and potential 
   222     ///If executed after the call of \c run() then it should return with true.
   229     satisfiy the complementary slackness cnditions (i.e. these are optimal).
   223     ///This function only checks optimality, doesn't bother with feasibility.
   230     This function only checks optimality, doesn't bother with feasibility.
   224     ///It is meant for testing purposes.
   231     For testing purpose.
   225     ///
   232     */
   226     bool checkComplementarySlackness(){
   233     bool checkComplementarySlackness(){
   227       Length mod_pot;
   234       Length mod_pot;
   228       Length fl_e;
   235       Length fl_e;
   229         for(typename Graph::EdgeIt e(G); e!=INVALID; ++e) {
   236         for(typename Graph::EdgeIt e(g); e!=INVALID; ++e) {
   230 	//C^{\Pi}_{i,j}
   237 	//C^{\Pi}_{i,j}
   231 	mod_pot = length[e]-potential[G.head(e)]+potential[G.tail(e)];
   238 	mod_pot = length[e]-potential[g.head(e)]+potential[g.tail(e)];
   232 	fl_e = flow[e];
   239 	fl_e = flow[e];
   233 	if (0<fl_e && fl_e<capacity[e]) {
   240 	if (0<fl_e && fl_e<capacity[e]) {
   234 	  /// \todo better comparison is needed for real types, moreover, 
   241 	  /// \todo better comparison is needed for real types, moreover, 
   235 	  /// this comparison here is superfluous.
   242 	  /// this comparison here is superfluous.
   236 	  if (mod_pot != 0)
   243 	  if (mod_pot != 0)
   244 	}
   251 	}
   245       }
   252       }
   246       return true;
   253       return true;
   247     }
   254     }
   248     
   255     
   249 
       
   250   }; //class MinCostFlow
   256   }; //class MinCostFlow
   251 
   257 
   252   ///@}
   258   ///@}
   253 
   259 
   254 } //namespace lemon
   260 } //namespace lemon