Started mincostflow.
authorathos
Thu, 13 May 2004 17:42:23 +0000
changeset 635933f593824c2
parent 634 aacabcd724f0
child 636 e59b0c363a9e
Started mincostflow.
src/work/athos/mincostflow.h
     1.1 --- a/src/work/athos/mincostflow.h	Thu May 13 17:33:40 2004 +0000
     1.2 +++ b/src/work/athos/mincostflow.h	Thu May 13 17:42:23 2004 +0000
     1.3 @@ -36,13 +36,13 @@
     1.4    /// where \c M is the value of the maximal flow.
     1.5    ///
     1.6    ///\author Attila Bernath
     1.7 -  template <typename Graph, typename LengthMap, typename SupplyMap>
     1.8 +  template <typename Graph, typename LengthMap, typename SupplyDemandMap>
     1.9    class MinCostFlow {
    1.10  
    1.11      typedef typename LengthMap::ValueType Length;
    1.12  
    1.13  
    1.14 -    typedef typename SupplyMap::ValueType Supply;
    1.15 +    typedef typename SupplyDemandMap::ValueType SupplyDemand;
    1.16      
    1.17      typedef typename Graph::Node Node;
    1.18      typedef typename Graph::NodeIt NodeIt;
    1.19 @@ -84,7 +84,7 @@
    1.20      //Input
    1.21      const Graph& G;
    1.22      const LengthMap& length;
    1.23 -    const SupplyMap& supply;//supply or demand of nodes
    1.24 +    const SupplyDemandMap& supply_demand;//supply or demand of nodes
    1.25  
    1.26  
    1.27      //auxiliary variables
    1.28 @@ -94,7 +94,7 @@
    1.29      //To store the potentila (dual variables)
    1.30      typename Graph::template NodeMap<Length> potential;
    1.31      //To store excess-deficit values
    1.32 -    SupplyMap excess;
    1.33 +    SupplyDemandMap excess_deficit;
    1.34      
    1.35  
    1.36      Length total_length;
    1.37 @@ -103,39 +103,62 @@
    1.38    public :
    1.39  
    1.40  
    1.41 -    MinCostFlow(Graph& _G, LengthMap& _length, SupplyMap& _supply) : G(_G), 
    1.42 -      length(_length), supply(_supply), flow(_G), potential(_G){ }
    1.43 +    MinCostFlow(Graph& _G, LengthMap& _length, SupplyDemandMap& _supply_demand) : G(_G), 
    1.44 +      length(_length), supply_demand(_supply_demand), flow(_G), potential(_G){ }
    1.45  
    1.46      
    1.47      ///Runs the algorithm.
    1.48  
    1.49      ///Runs the algorithm.
    1.50 -    ///Returns k if there are at least k edge-disjoint paths from s to t.
    1.51 -    ///Otherwise it returns the number of found edge-disjoint paths from s to t.
    1.52 +
    1.53      ///\todo May be it does make sense to be able to start with a nonzero 
    1.54      /// feasible primal-dual solution pair as well.
    1.55      int run() {
    1.56  
    1.57        //Resetting variables from previous runs
    1.58 -      total_length = 0;
    1.59 +      //total_length = 0;
    1.60 +
    1.61 +      typedef typename Graph::template NodeMap<int> HeapMap;
    1.62 +      typedef Heap<Node, SupplyDemand, typename Graph::template NodeMap<int>,
    1.63 +	std::greater<SupplyDemand> > 	HeapType;
    1.64 +
    1.65 +      //A heap for the excess nodes
    1.66 +      HeapMap excess_nodes_map(G,-1);
    1.67 +      HeapType excess_nodes(excess_nodes_map);
    1.68 +
    1.69 +      //A heap for the deficit nodes
    1.70 +      HeapMap deficit_nodes_map(G,-1);
    1.71 +      HeapType deficit_nodes(deficit_nodes_map);
    1.72 +
    1.73        
    1.74        FOR_EACH_LOC(typename Graph::EdgeIt, e, G){
    1.75  	flow.set(e,0);
    1.76        }
    1.77  
    1.78        //Initial value for delta
    1.79 -      Supply delta = 0;
    1.80 -      
    1.81 +      SupplyDemand delta = 0;
    1.82 +
    1.83        FOR_EACH_LOC(typename Graph::NodeIt, n, G){
    1.84 -	if (delta < abs(supply[e])){
    1.85 -	  delta = abs(supply[e]);
    1.86 +       	excess_deficit.set(n,supply_demand[n]);
    1.87 +	//A supply node
    1.88 +	if (excess_deficit[n] > 0){
    1.89 +	  excess_nodes.push(n,excess_deficit[n]);
    1.90  	}
    1.91 -	excess.set(n,supply[e]);
    1.92 +	//A demand node
    1.93 +	if (excess_deficit[n] < 0){
    1.94 +	  deficit_nodes.push(n, - excess_deficit[n]);
    1.95 +	}
    1.96 +	//Finding out starting value of delta
    1.97 +	if (delta < abs(excess_deficit[n])){
    1.98 +	  delta = abs(excess_deficit[n]);
    1.99 +	}
   1.100  	//Initialize the copy of the Dijkstra potential to zero
   1.101  	potential.set(n,0);
   1.102        }
   1.103 -      
   1.104  
   1.105 +      //It'll be allright as an initial value, though this value 
   1.106 +      //can be the maximum deficit here
   1.107 +      SupplyDemand max_excess = delta;
   1.108        
   1.109        //We need a residual graph which is uncapacitated
   1.110        ResGraphType res_graph(G, flow);
   1.111 @@ -147,45 +170,102 @@
   1.112        Dijkstra<ResGraphType, ModLengthMap> dijkstra(res_graph, mod_length);
   1.113  
   1.114  
   1.115 -      int i;
   1.116 -      for (i=0; i<k; ++i){
   1.117 -	dijkstra.run(s);
   1.118 -	if (!dijkstra.reached(t)){
   1.119 -	  //There are no k paths from s to t
   1.120 -	  break;
   1.121 -	};
   1.122 +      while (max_excess > 0){
   1.123 +
   1.124  	
   1.125 -	//We have to copy the potential
   1.126 -	FOR_EACH_LOC(typename ResGraphType::NodeIt, n, res_graph){
   1.127 -	  potential[n] += dijkstra.distMap()[n];
   1.128 +	//Merge and stuff
   1.129 +
   1.130 +	Node s = excess_nodes.top(); 
   1.131 +	SupplyDemand max_excess = excess_nodes[s];
   1.132 +	Node t = deficit_nodes.top(); 
   1.133 +	if (max_excess < dificit_nodes[t]){
   1.134 +	  max_excess = dificit_nodes[t];
   1.135 +	}
   1.136 +
   1.137 +
   1.138 +	while(max_excess > ){
   1.139 +
   1.140 +	  
   1.141 +	  //s es t valasztasa
   1.142 +
   1.143 +	  //Dijkstra part	
   1.144 +	  dijkstra.run(s);
   1.145 +
   1.146 +	  /*We know from theory that t can be reached
   1.147 +	  if (!dijkstra.reached(t)){
   1.148 +	    //There are no k paths from s to t
   1.149 +	    break;
   1.150 +	  };
   1.151 +	  */
   1.152 +	  
   1.153 +	  //We have to change the potential
   1.154 +	  FOR_EACH_LOC(typename ResGraphType::NodeIt, n, res_graph){
   1.155 +	    potential[n] += dijkstra.distMap()[n];
   1.156 +	  }
   1.157 +
   1.158 +
   1.159 +	  //Augmenting on the sortest path
   1.160 +	  Node n=t;
   1.161 +	  ResGraphEdge e;
   1.162 +	  while (n!=s){
   1.163 +	    e = dijkstra.pred(n);
   1.164 +	    n = dijkstra.predNode(n);
   1.165 +	    res_graph.augment(e,delta);
   1.166 +	    /*
   1.167 +	    //Let's update the total length
   1.168 +	    if (res_graph.forward(e))
   1.169 +	      total_length += length[e];
   1.170 +	    else 
   1.171 +	      total_length -= length[e];	    
   1.172 +	    */
   1.173 +	  }
   1.174 +
   1.175 +	  //Update the excess_nodes heap
   1.176 +	  if (delta >= excess_nodes[s]){
   1.177 +	    if (delta > excess_nodes[s])
   1.178 +	      deficit_nodes.push(s,delta - excess_nodes[s]);
   1.179 +	    excess_nodes.pop();
   1.180 +	    
   1.181 +	  } 
   1.182 +	  else{
   1.183 +	    excess_nodes[s] -= delta;
   1.184 +	  }
   1.185 +	  //Update the deficit_nodes heap
   1.186 +	  if (delta >= deficit_nodes[t]){
   1.187 +	    if (delta > deficit_nodes[t])
   1.188 +	      excess_nodes.push(t,delta - deficit_nodes[t]);
   1.189 +	    deficit_nodes.pop();
   1.190 +	    
   1.191 +	  } 
   1.192 +	  else{
   1.193 +	    deficit_nodes[t] -= delta;
   1.194 +	  }
   1.195 +	  //Dijkstra part ends here
   1.196  	}
   1.197  
   1.198  	/*
   1.199 -	{
   1.200 +	 * End of the delta scaling phase 
   1.201 +	*/
   1.202  
   1.203 -	  typename ResGraphType::NodeIt n;
   1.204 -	  for ( res_graph.first(n) ; res_graph.valid(n) ; res_graph.next(n) ) {
   1.205 -	      potential[n] += dijkstra.distMap()[n];
   1.206 +	//Whatever this means
   1.207 +	delta = delta / 2;
   1.208 +
   1.209 +	/*This is not necessary here
   1.210 +	//Update the max_excess
   1.211 +	max_excess = 0;
   1.212 +	FOR_EACH_LOC(typename Graph::NodeIt, n, G){
   1.213 +	  if (max_excess < excess_deficit[n]){
   1.214 +	    max_excess = excess_deficit[n];
   1.215  	  }
   1.216  	}
   1.217  	*/
   1.218 -
   1.219 -	//Augmenting on the sortest path
   1.220 -	Node n=t;
   1.221 -	ResGraphEdge e;
   1.222 -	while (n!=s){
   1.223 -	  e = dijkstra.pred(n);
   1.224 -	  n = dijkstra.predNode(n);
   1.225 -	  res_graph.augment(e,delta);
   1.226 -	  //Let's update the total length
   1.227 -	  if (res_graph.forward(e))
   1.228 -	    total_length += length[e];
   1.229 -	  else 
   1.230 -	    total_length -= length[e];	    
   1.231 +	//Reset delta if still too big
   1.232 +	if (8*number_of_nodes*max_excess <= delta){
   1.233 +	  delta = max_excess;
   1.234 +	  
   1.235  	}
   1.236 -
   1.237  	  
   1.238 -      }
   1.239 +      }//while(max_excess > 0)
   1.240        
   1.241  
   1.242        return i;