min_cost_flow.h

Go to the documentation of this file.
00001 /* -*- C++ -*- 00002 * src/lemon/min_cost_flow.h - Part of LEMON, a generic C++ optimization library 00003 * 00004 * Copyright (C) 2004 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport 00005 * (Egervary Combinatorial Optimization Research Group, 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_wrapper.h> 00027 #include <lemon/maps.h> 00028 #include <vector> 00029 00030 namespace lemon { 00031 00034 00059 template <typename Graph, typename LengthMap, typename CapacityMap> 00060 class MinCostFlow { 00061 00062 typedef typename LengthMap::ValueType Length; 00063 00064 //Warning: this should be integer type 00065 typedef typename CapacityMap::ValueType Capacity; 00066 00067 typedef typename Graph::Node Node; 00068 typedef typename Graph::NodeIt NodeIt; 00069 typedef typename Graph::Edge Edge; 00070 typedef typename Graph::OutEdgeIt OutEdgeIt; 00071 typedef typename Graph::template EdgeMap<int> EdgeIntMap; 00072 00073 00074 typedef ResGraphWrapper<const Graph,int,CapacityMap,EdgeIntMap> ResGW; 00075 typedef typename ResGW::Edge ResGraphEdge; 00076 00077 class ModLengthMap { 00078 typedef typename Graph::template NodeMap<Length> NodeMap; 00079 const ResGW& G; 00080 const LengthMap &ol; 00081 const NodeMap &pot; 00082 public : 00083 typedef typename LengthMap::KeyType KeyType; 00084 typedef typename LengthMap::ValueType ValueType; 00085 00086 ValueType operator[](typename ResGW::Edge e) const { 00087 if (G.forward(e)) 00088 return ol[e]-(pot[G.head(e)]-pot[G.tail(e)]); 00089 else 00090 return -ol[e]-(pot[G.head(e)]-pot[G.tail(e)]); 00091 } 00092 00093 ModLengthMap(const ResGW& _G, 00094 const LengthMap &o, const NodeMap &p) : 00095 G(_G), /*rev(_rev),*/ ol(o), pot(p){}; 00096 };//ModLengthMap 00097 00098 00099 protected: 00100 00101 //Input 00102 const Graph& G; 00103 const LengthMap& length; 00104 const CapacityMap& capacity; 00105 00106 00107 //auxiliary variables 00108 00109 //To store the flow 00110 EdgeIntMap flow; 00111 //To store the potential (dual variables) 00112 typedef typename Graph::template NodeMap<Length> PotentialMap; 00113 PotentialMap potential; 00114 00115 00116 Length total_length; 00117 00118 00119 public : 00120 00122 00126 MinCostFlow(Graph& _G, LengthMap& _length, CapacityMap& _cap) : G(_G), 00127 length(_length), capacity(_cap), flow(_G), potential(_G){ } 00128 00129 00131 00143 int run(Node s, Node t, int k) { 00144 00145 //Resetting variables from previous runs 00146 total_length = 0; 00147 00148 for (typename Graph::EdgeIt e(G); e!=INVALID; ++e) flow.set(e, 0); 00149 00150 //Initialize the potential to zero 00151 for (typename Graph::NodeIt n(G); n!=INVALID; ++n) potential.set(n, 0); 00152 00153 00154 //We need a residual graph 00155 ResGW res_graph(G, capacity, flow); 00156 00157 00158 ModLengthMap mod_length(res_graph, length, potential); 00159 00160 Dijkstra<ResGW, ModLengthMap> dijkstra(res_graph, mod_length); 00161 00162 int i; 00163 for (i=0; i<k; ++i){ 00164 dijkstra.run(s); 00165 if (!dijkstra.reached(t)){ 00166 //There are no flow of value k from s to t 00167 break; 00168 }; 00169 00170 //We have to change the potential 00171 for(typename ResGW::NodeIt n(res_graph); n!=INVALID; ++n) 00172 potential[n] += dijkstra.distMap()[n]; 00173 00174 00175 //Augmenting on the sortest path 00176 Node n=t; 00177 ResGraphEdge e; 00178 while (n!=s){ 00179 e = dijkstra.pred(n); 00180 n = dijkstra.predNode(n); 00181 res_graph.augment(e,1); 00182 //Let's update the total length 00183 if (res_graph.forward(e)) 00184 total_length += length[e]; 00185 else 00186 total_length -= length[e]; 00187 } 00188 00189 00190 } 00191 00192 00193 return i; 00194 } 00195 00196 00197 00199 00202 Length totalLength(){ 00203 return total_length; 00204 } 00205 00207 00211 const EdgeIntMap &getFlow() const { return flow;} 00212 00214 00217 const PotentialMap &getPotential() const { return potential;} 00218 00220 00226 bool checkComplementarySlackness(){ 00227 Length mod_pot; 00228 Length fl_e; 00229 for(typename Graph::EdgeIt e(G); e!=INVALID; ++e) { 00230 //C^{\Pi}_{i,j} 00231 mod_pot = length[e]-potential[G.head(e)]+potential[G.tail(e)]; 00232 fl_e = flow[e]; 00233 if (0<fl_e && fl_e<capacity[e]) { 00236 if (mod_pot != 0) 00237 return false; 00238 } 00239 else { 00240 if (mod_pot > 0 && fl_e != 0) 00241 return false; 00242 if (mod_pot < 0 && fl_e != capacity[e]) 00243 return false; 00244 } 00245 } 00246 return true; 00247 } 00248 00249 00250 }; //class MinCostFlow 00251 00253 00254 } //namespace lemon 00255 00256 #endif //LEMON_MIN_COST_FLOW_H

Generated on Thu Sep 30 12:18:33 2004 for LEMON by doxygen 1.3.8