src/hugo/min_cost_flows.h
changeset 899 f485b3008cf5
parent 898 c46cfb2651ec
child 900 fc7bc2dacee5
     1.1 --- a/src/hugo/min_cost_flows.h	Wed Sep 22 08:54:53 2004 +0000
     1.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.3 @@ -1,241 +0,0 @@
     1.4 -// -*- c++ -*-
     1.5 -#ifndef HUGO_MINCOSTFLOWS_H
     1.6 -#define HUGO_MINCOSTFLOWS_H
     1.7 -
     1.8 -///\ingroup flowalgs
     1.9 -///\file
    1.10 -///\brief An algorithm for finding a flow of value \c k (for small values of \c k) having minimal total cost 
    1.11 -
    1.12 -
    1.13 -#include <hugo/dijkstra.h>
    1.14 -#include <hugo/graph_wrapper.h>
    1.15 -#include <hugo/maps.h>
    1.16 -#include <vector>
    1.17 -
    1.18 -namespace hugo {
    1.19 -
    1.20 -/// \addtogroup flowalgs
    1.21 -/// @{
    1.22 -
    1.23 -  ///\brief Implementation of an algorithm for finding a flow of value \c k 
    1.24 -  ///(for small values of \c k) having minimal total cost between 2 nodes 
    1.25 -  /// 
    1.26 -  ///
    1.27 -  /// The class \ref hugo::MinCostFlows "MinCostFlows" implements
    1.28 -  /// an algorithm for finding a flow of value \c k 
    1.29 -  /// having minimal total cost 
    1.30 -  /// from a given source node to a given target node in an
    1.31 -  /// edge-weighted directed graph. To this end, 
    1.32 -  /// the edge-capacities and edge-weitghs have to be nonnegative. 
    1.33 -  /// The edge-capacities should be integers, but the edge-weights can be 
    1.34 -  /// integers, reals or of other comparable numeric type.
    1.35 -  /// This algorithm is intended to use only for small values of \c k, 
    1.36 -  /// since it is only polynomial in k, 
    1.37 -  /// not in the length of k (which is log k). 
    1.38 -  /// In order to find the minimum cost flow of value \c k it 
    1.39 -  /// finds the minimum cost flow of value \c i for every 
    1.40 -  /// \c i between 0 and \c k. 
    1.41 -  ///
    1.42 -  ///\param Graph The directed graph type the algorithm runs on.
    1.43 -  ///\param LengthMap The type of the length map.
    1.44 -  ///\param CapacityMap The capacity map type.
    1.45 -  ///
    1.46 -  ///\author Attila Bernath
    1.47 -  template <typename Graph, typename LengthMap, typename CapacityMap>
    1.48 -  class MinCostFlows {
    1.49 -
    1.50 -    typedef typename LengthMap::ValueType Length;
    1.51 -
    1.52 -    //Warning: this should be integer type
    1.53 -    typedef typename CapacityMap::ValueType Capacity;
    1.54 -    
    1.55 -    typedef typename Graph::Node Node;
    1.56 -    typedef typename Graph::NodeIt NodeIt;
    1.57 -    typedef typename Graph::Edge Edge;
    1.58 -    typedef typename Graph::OutEdgeIt OutEdgeIt;
    1.59 -    typedef typename Graph::template EdgeMap<int> EdgeIntMap;
    1.60 -
    1.61 -
    1.62 -    typedef ResGraphWrapper<const Graph,int,CapacityMap,EdgeIntMap> ResGraphType;
    1.63 -    typedef typename ResGraphType::Edge ResGraphEdge;
    1.64 -
    1.65 -    class ModLengthMap {   
    1.66 -      typedef typename Graph::template NodeMap<Length> NodeMap;
    1.67 -      const ResGraphType& G;
    1.68 -      const LengthMap &ol;
    1.69 -      const NodeMap &pot;
    1.70 -    public :
    1.71 -      typedef typename LengthMap::KeyType KeyType;
    1.72 -      typedef typename LengthMap::ValueType ValueType;
    1.73 -	
    1.74 -      ValueType operator[](typename ResGraphType::Edge e) const {     
    1.75 -	if (G.forward(e))
    1.76 -	  return  ol[e]-(pot[G.head(e)]-pot[G.tail(e)]);   
    1.77 -	else
    1.78 -	  return -ol[e]-(pot[G.head(e)]-pot[G.tail(e)]);   
    1.79 -      }     
    1.80 -	
    1.81 -      ModLengthMap(const ResGraphType& _G,
    1.82 -		   const LengthMap &o,  const NodeMap &p) : 
    1.83 -	G(_G), /*rev(_rev),*/ ol(o), pot(p){}; 
    1.84 -    };//ModLengthMap
    1.85 -
    1.86 -
    1.87 -  protected:
    1.88 -    
    1.89 -    //Input
    1.90 -    const Graph& G;
    1.91 -    const LengthMap& length;
    1.92 -    const CapacityMap& capacity;
    1.93 -
    1.94 -
    1.95 -    //auxiliary variables
    1.96 -
    1.97 -    //To store the flow
    1.98 -    EdgeIntMap flow; 
    1.99 -    //To store the potential (dual variables)
   1.100 -    typedef typename Graph::template NodeMap<Length> PotentialMap;
   1.101 -    PotentialMap potential;
   1.102 -    
   1.103 -
   1.104 -    Length total_length;
   1.105 -
   1.106 -
   1.107 -  public :
   1.108 -
   1.109 -    /// The constructor of the class.
   1.110 -    
   1.111 -    ///\param _G The directed graph the algorithm runs on. 
   1.112 -    ///\param _length The length (weight or cost) of the edges. 
   1.113 -    ///\param _cap The capacity of the edges. 
   1.114 -    MinCostFlows(Graph& _G, LengthMap& _length, CapacityMap& _cap) : G(_G), 
   1.115 -      length(_length), capacity(_cap), flow(_G), potential(_G){ }
   1.116 -
   1.117 -    
   1.118 -    ///Runs the algorithm.
   1.119 -    
   1.120 -    ///Runs the algorithm.
   1.121 -    ///Returns k if there is a flow of value at least k edge-disjoint 
   1.122 -    ///from s to t.
   1.123 -    ///Otherwise it returns the maximum value of a flow from s to t.
   1.124 -    ///
   1.125 -    ///\param s The source node.
   1.126 -    ///\param t The target node.
   1.127 -    ///\param k The value of the flow we are looking for.
   1.128 -    ///
   1.129 -    ///\todo May be it does make sense to be able to start with a nonzero 
   1.130 -    /// feasible primal-dual solution pair as well.
   1.131 -    int run(Node s, Node t, int k) {
   1.132 -
   1.133 -      //Resetting variables from previous runs
   1.134 -      total_length = 0;
   1.135 -      
   1.136 -      for (typename Graph::EdgeIt e(G); e!=INVALID; ++e) flow.set(e, 0);
   1.137 -
   1.138 -      //Initialize the potential to zero
   1.139 -      for (typename Graph::NodeIt n(G); n!=INVALID; ++n) potential.set(n, 0);
   1.140 -      
   1.141 -      
   1.142 -      //We need a residual graph
   1.143 -      ResGraphType res_graph(G, capacity, flow);
   1.144 -
   1.145 -
   1.146 -      ModLengthMap mod_length(res_graph, length, potential);
   1.147 -
   1.148 -      Dijkstra<ResGraphType, ModLengthMap> dijkstra(res_graph, mod_length);
   1.149 -
   1.150 -      int i;
   1.151 -      for (i=0; i<k; ++i){
   1.152 -	dijkstra.run(s);
   1.153 -	if (!dijkstra.reached(t)){
   1.154 -	  //There are no flow of value k from s to t
   1.155 -	  break;
   1.156 -	};
   1.157 -	
   1.158 -	//We have to change the potential
   1.159 -        for(typename ResGraphType::NodeIt n(res_graph); n!=INVALID; ++n)
   1.160 -	  potential[n] += dijkstra.distMap()[n];
   1.161 -
   1.162 -
   1.163 -	//Augmenting on the sortest path
   1.164 -	Node n=t;
   1.165 -	ResGraphEdge e;
   1.166 -	while (n!=s){
   1.167 -	  e = dijkstra.pred(n);
   1.168 -	  n = dijkstra.predNode(n);
   1.169 -	  res_graph.augment(e,1);
   1.170 -	  //Let's update the total length
   1.171 -	  if (res_graph.forward(e))
   1.172 -	    total_length += length[e];
   1.173 -	  else 
   1.174 -	    total_length -= length[e];	    
   1.175 -	}
   1.176 -
   1.177 -	  
   1.178 -      }
   1.179 -      
   1.180 -
   1.181 -      return i;
   1.182 -    }
   1.183 -
   1.184 -
   1.185 -
   1.186 -    /// Gives back the total weight of the found flow.
   1.187 -
   1.188 -    ///This function gives back the total weight of the found flow.
   1.189 -    ///Assumes that \c run() has been run and nothing changed since then.
   1.190 -    Length totalLength(){
   1.191 -      return total_length;
   1.192 -    }
   1.193 -
   1.194 -    ///Returns a const reference to the EdgeMap \c flow. 
   1.195 -
   1.196 -    ///Returns a const reference to the EdgeMap \c flow. 
   1.197 -    ///\pre \ref run() must
   1.198 -    ///be called before using this function.
   1.199 -    const EdgeIntMap &getFlow() const { return flow;}
   1.200 -
   1.201 -    ///Returns a const reference to the NodeMap \c potential (the dual solution).
   1.202 -
   1.203 -    ///Returns a const reference to the NodeMap \c potential (the dual solution).
   1.204 -    /// \pre \ref run() must be called before using this function.
   1.205 -    const PotentialMap &getPotential() const { return potential;}
   1.206 -
   1.207 -    /// Checking the complementary slackness optimality criteria
   1.208 -
   1.209 -    ///This function checks, whether the given solution is optimal
   1.210 -    ///If executed after the call of \c run() then it should return with true.
   1.211 -    ///This function only checks optimality, doesn't bother with feasibility.
   1.212 -    ///It is meant for testing purposes.
   1.213 -    ///
   1.214 -    bool checkComplementarySlackness(){
   1.215 -      Length mod_pot;
   1.216 -      Length fl_e;
   1.217 -        for(typename Graph::EdgeIt e(G); e!=INVALID; ++e) {
   1.218 -	//C^{\Pi}_{i,j}
   1.219 -	mod_pot = length[e]-potential[G.head(e)]+potential[G.tail(e)];
   1.220 -	fl_e = flow[e];
   1.221 -	if (0<fl_e && fl_e<capacity[e]) {
   1.222 -	  /// \todo better comparison is needed for real types, moreover, 
   1.223 -	  /// this comparison here is superfluous.
   1.224 -	  if (mod_pot != 0)
   1.225 -	    return false;
   1.226 -	} 
   1.227 -	else {
   1.228 -	  if (mod_pot > 0 && fl_e != 0)
   1.229 -	    return false;
   1.230 -	  if (mod_pot < 0 && fl_e != capacity[e])
   1.231 -	    return false;
   1.232 -	}
   1.233 -      }
   1.234 -      return true;
   1.235 -    }
   1.236 -    
   1.237 -
   1.238 -  }; //class MinCostFlows
   1.239 -
   1.240 -  ///@}
   1.241 -
   1.242 -} //namespace hugo
   1.243 -
   1.244 -#endif //HUGO_MINCOSTFLOWS_H