src/work/athos/mincostflow.h
author alpar
Fri, 28 May 2004 12:55:02 +0000
changeset 667 9cba4444d804
parent 661 d306e777117e
child 671 708df4dc6ab6
permissions -rw-r--r--
*** empty log message ***
     1 // -*- c++ -*-
     2 #ifndef HUGO_MINCOSTFLOW_H
     3 #define HUGO_MINCOSTFLOW_H
     4 
     5 ///\ingroup galgs
     6 ///\file
     7 ///\brief An algorithm for finding the minimum cost flow of given value in an uncapacitated network
     8 
     9 #include <hugo/dijkstra.h>
    10 #include <hugo/graph_wrapper.h>
    11 #include <hugo/maps.h>
    12 #include <vector>
    13 #include <list>
    14 #include <values.h>
    15 #include <hugo/for_each_macros.h>
    16 #include <hugo/unionfind.h>
    17 #include <hugo/bin_heap.h>
    18 #include <bfs_dfs.h>
    19 
    20 namespace hugo {
    21 
    22 /// \addtogroup galgs
    23 /// @{
    24 
    25   ///\brief Implementation of an algorithm for solving the minimum cost general
    26   /// flow problem in an uncapacitated network
    27   /// 
    28   ///
    29   /// The class \ref hugo::MinCostFlow "MinCostFlow" implements
    30   /// an algorithm for solving the following general minimum cost flow problem>
    31   /// 
    32   ///
    33   ///
    34   /// \warning It is assumed here that the problem has a feasible solution
    35   ///
    36   /// The range of the cost (weight) function is nonnegative reals but 
    37   /// the range of capacity function is the set of nonnegative integers. 
    38   /// It is not a polinomial time algorithm for counting the minimum cost
    39   /// maximal flow, since it counts the minimum cost flow for every value 0..M
    40   /// where \c M is the value of the maximal flow.
    41   ///
    42   ///\author Attila Bernath
    43   template <typename Graph, typename CostMap, typename SupplyDemandMap>
    44   class MinCostFlow {
    45 
    46     typedef typename CostMap::ValueType Cost;
    47 
    48 
    49     typedef typename SupplyDemandMap::ValueType SupplyDemand;
    50     
    51     typedef typename Graph::Node Node;
    52     typedef typename Graph::NodeIt NodeIt;
    53     typedef typename Graph::Edge Edge;
    54     typedef typename Graph::OutEdgeIt OutEdgeIt;
    55     typedef typename Graph::template EdgeMap<SupplyDemand> FlowMap;
    56     typedef ConstMap<Edge,SupplyDemand> ConstEdgeMap;
    57 
    58     //    typedef ConstMap<Edge,int> ConstMap;
    59 
    60     typedef ResGraphWrapper<const Graph,int,ConstEdgeMap,FlowMap> ResGraph;
    61     typedef typename ResGraph::Edge ResGraphEdge;
    62 
    63     class ModCostMap {   
    64       //typedef typename ResGraph::template NodeMap<Cost> NodeMap;
    65       typedef typename Graph::template NodeMap<Cost> NodeMap;
    66       const ResGraph& res_graph;
    67       //      const EdgeIntMap& rev;
    68       const CostMap &ol;
    69       const NodeMap &pot;
    70     public :
    71       typedef typename CostMap::KeyType KeyType;
    72       typedef typename CostMap::ValueType ValueType;
    73 	
    74       ValueType operator[](typename ResGraph::Edge e) const {     
    75 	if (res_graph.forward(e))
    76 	  return  ol[e]-(pot[res_graph.head(e)]-pot[res_graph.tail(e)]);   
    77 	else
    78 	  return -ol[e]-(pot[res_graph.head(e)]-pot[res_graph.tail(e)]);   
    79       }     
    80 	
    81       ModCostMap(const ResGraph& _res_graph,
    82 		   const CostMap &o,  const NodeMap &p) : 
    83 	res_graph(_res_graph), /*rev(_rev),*/ ol(o), pot(p){}; 
    84     };//ModCostMap
    85 
    86 
    87   protected:
    88     
    89     //Input
    90     const Graph& graph;
    91     const CostMap& cost;
    92     const SupplyDemandMap& supply_demand;//supply or demand of nodes
    93 
    94 
    95     //auxiliary variables
    96 
    97     //To store the flow
    98     FlowMap flow; 
    99     //To store the potential (dual variables)
   100     typedef typename Graph::template NodeMap<Cost> PotentialMap;
   101     PotentialMap potential;
   102     //To store excess-deficit values
   103     SupplyDemandMap excess_deficit;
   104     
   105 
   106     Cost total_cost;
   107 
   108 
   109   public :
   110 
   111 
   112    MinCostFlow(Graph& _graph, CostMap& _cost, SupplyDemandMap& _supply_demand):
   113      graph(_graph), 
   114      cost(_cost), 
   115      supply_demand(_supply_demand), 
   116      flow(_graph), 
   117      potential(_graph),
   118      excess_deficit(_graph){ }
   119 
   120     
   121     ///Runs the algorithm.
   122 
   123     ///Runs the algorithm.
   124 
   125     ///\todo May be it does make sense to be able to start with a nonzero 
   126     /// feasible primal-dual solution pair as well.
   127     void run() {
   128 
   129       //Resetting variables from previous runs
   130       //total_cost = 0;
   131 
   132       typedef typename Graph::template NodeMap<int> HeapMap;
   133       typedef BinHeap< Node, SupplyDemand, typename Graph::template NodeMap<int>,
   134 	std::greater<SupplyDemand> > 	HeapType;
   135 
   136       //A heap for the excess nodes
   137       HeapMap excess_nodes_map(graph,-1);
   138       HeapType excess_nodes(excess_nodes_map);
   139 
   140       //A heap for the deficit nodes
   141       HeapMap deficit_nodes_map(graph,-1);
   142       HeapType deficit_nodes(deficit_nodes_map);
   143 
   144       //A container to store nonabundant arcs
   145       std::list<Edge> nonabundant_arcs;
   146 
   147 	
   148       FOR_EACH_LOC(typename Graph::EdgeIt, e, graph){
   149 	flow.set(e,0);
   150 	nonabundant_arcs.push_back(e);
   151       }
   152 
   153       //Initial value for delta
   154       SupplyDemand delta = 0;
   155 
   156       typedef UnionFindEnum<Node, Graph::template NodeMap> UFE;
   157 
   158       //A union-find structure to store the abundant components
   159       typename UFE::MapType abund_comp_map(graph);
   160       UFE abundant_components(abund_comp_map);
   161 
   162 
   163 
   164       FOR_EACH_LOC(typename Graph::NodeIt, n, graph){
   165        	excess_deficit.set(n,supply_demand[n]);
   166 	//A supply node
   167 	if (excess_deficit[n] > 0){
   168 	  excess_nodes.push(n,excess_deficit[n]);
   169 	}
   170 	//A demand node
   171 	if (excess_deficit[n] < 0){
   172 	  deficit_nodes.push(n, - excess_deficit[n]);
   173 	}
   174 	//Finding out starting value of delta
   175 	if (delta < abs(excess_deficit[n])){
   176 	  delta = abs(excess_deficit[n]);
   177 	}
   178 	//Initialize the copy of the Dijkstra potential to zero
   179 	potential.set(n,0);
   180 	//Every single point is an abundant component initially 
   181 	abundant_components.insert(n);
   182       }
   183 
   184       //It'll be allright as an initial value, though this value 
   185       //can be the maximum deficit here
   186       SupplyDemand max_excess = delta;
   187       
   188       ///\bug This is a serious cheat here, before we have an uncapacitated ResGraph
   189       ConstEdgeMap const_inf_map(MAXINT);
   190       
   191       //We need a residual graph which is uncapacitated
   192       ResGraph res_graph(graph, const_inf_map, flow);
   193       
   194       //An EdgeMap to tell which arcs are abundant
   195       typename Graph::template EdgeMap<bool> abundant_arcs(graph);
   196 
   197       //Let's construct the sugraph consisting only of the abundant edges
   198       typedef ConstMap< typename Graph::Node, bool > ConstNodeMap;
   199       ConstNodeMap const_true_map(true);
   200       typedef SubGraphWrapper< const Graph, ConstNodeMap, 
   201 	 typename Graph::template EdgeMap<bool> > 
   202 	AbundantGraph;
   203       AbundantGraph abundant_graph(graph, const_true_map, abundant_arcs );
   204       
   205       //Let's construct the residual graph for the abundant graph
   206       typedef ResGraphWrapper<const AbundantGraph,int,ConstEdgeMap,FlowMap> 
   207 	ResAbGraph;
   208       //Again uncapacitated
   209       ResAbGraph res_ab_graph(abundant_graph, const_inf_map, flow);
   210       
   211       //We need things for the bfs
   212       typename ResAbGraph::template NodeMap<bool> bfs_reached(res_ab_graph);
   213       typename ResAbGraph::template NodeMap<typename ResAbGraph::Edge> 
   214 	bfs_pred(res_ab_graph); 
   215       NullMap<typename ResAbGraph::Node, int> bfs_dist_dummy;
   216       //We want to run bfs-es (more) on this graph 'res_ab_graph'
   217       Bfs < ResAbGraph , 
   218 	typename ResAbGraph::template NodeMap<bool>, 
   219 	typename ResAbGraph::template NodeMap<typename ResAbGraph::Edge>,
   220 	NullMap<typename ResAbGraph::Node, int> > 
   221 	bfs(res_ab_graph, bfs_reached, bfs_pred, bfs_dist_dummy);
   222       /*This is what Marci wants for a bfs
   223 	template <typename Graph, 
   224 	    typename ReachedMap=typename Graph::template NodeMap<bool>, 
   225 	    typename PredMap
   226 	    =typename Graph::template NodeMap<typename Graph::Edge>, 
   227 	    typename DistMap=typename Graph::template NodeMap<int> > 
   228 	    class Bfs : public BfsIterator<Graph, ReachedMap> {
   229 
   230        */
   231       
   232       ModCostMap mod_cost(res_graph, cost, potential);
   233 
   234       Dijkstra<ResGraph, ModCostMap> dijkstra(res_graph, mod_cost);
   235 
   236 
   237       while (max_excess > 0){
   238 
   239 	//Reset delta if still too big
   240 	if (8*number_of_nodes*max_excess <= delta){
   241 	  delta = max_excess;
   242 	  
   243 	}
   244 
   245 	/*
   246 	 * Beginning of the delta scaling phase 
   247 	*/
   248 	//Merge and stuff
   249 	{
   250 	  SupplyDemand buf=8*number_of_nodes*delta;
   251 	  typename std::list<Edge>::iterator i = nonabundant_arcs.begin();
   252 	  while ( i != nonabundant_arcs.end() ){
   253 	    if (flow[i]>=buf){
   254 	      Node a = abundant_components.find(res_graph.head(i));
   255 	      Node b = abundant_components.find(res_graph.tail(i));
   256 	      //Merge
   257 	      if (a != b){
   258 		abundant_components.join(a,b);
   259 		//We want to push the smaller
   260 		//Which has greater absolut value excess/deficit
   261 		Node root=(abs(excess_deficit[a])>abs(excess_deficit[b]))?a:b;
   262 		//Which is the other
   263 		Node non_root = ( a == root ) ? b : a ;
   264 		abundant_components.makeRep(root);
   265 		SupplyDemand qty_to_augment = abs(excess_deficit[non_root]); 
   266 		//Push the positive value
   267 		if (excess_deficit[non_root] < 0)
   268 		  swap(root, non_root);
   269 		//If the non_root node has excess/deficit at all
   270 		if (qty_to_augment>0){
   271 		  //Find path and augment
   272 		  bfs.run(non_root);
   273 		  //root should be reached
   274 		  
   275 		  //Augmenting on the found path
   276 		  Node n=root;
   277 		  ResGraphEdge e;
   278 		  while (n!=non_root){
   279 		    e = bfs_pred(n);
   280 		    n = res_graph.tail(e);
   281 		    res_graph.augment(e,qty_to_augment);
   282 		  }
   283 	  
   284 		  //We know that non_root had positive excess
   285 		  excess_nodes[non_root] -= qty_to_augment;
   286 		  //But what about root node
   287 		  //It might have been positive and so became larger
   288 		  if (excess_deficit[root]>0){
   289 		    excess_nodes[root] += qty_to_augment;
   290 		  }
   291 		  else{
   292 		    //Or negative but not turned into positive
   293 		    deficit_nodes[root] -= qty_to_augment;
   294 		  }
   295 
   296 		  //Update the excess_deficit map
   297 		  excess_deficit[non_root] -= qty_to_augment;
   298 		  excess_deficit[root] += qty_to_augment;
   299 
   300 		  
   301 		}
   302 	      }
   303 	      //What happens to i?
   304 	      //Marci and Zsolt says I shouldn't do such things
   305 	      nonabundant_arcs.erase(i++);
   306 	      abundant_arcs[i] = true;
   307 	    }
   308 	    else
   309 	      ++i;
   310 	  }
   311 	}
   312 
   313 
   314 	Node s = excess_nodes.top(); 
   315 	SupplyDemand max_excess = excess_nodes[s];
   316 	Node t = deficit_nodes.top(); 
   317 	if (max_excess < deficit_nodes[t]){
   318 	  max_excess = deficit_nodes[t];
   319 	}
   320 
   321 
   322 	while(max_excess > (number_of_nodes-1)*delta/number_of_nodes){
   323 	  
   324 	  
   325 	  //s es t valasztasa
   326 	  
   327 	  //Dijkstra part	
   328 	  dijkstra.run(s);
   329 	  
   330 	  /*We know from theory that t can be reached
   331 	  if (!dijkstra.reached(t)){
   332 	    //There are no k paths from s to t
   333 	    break;
   334 	  };
   335 	  */
   336 	  
   337 	  //We have to change the potential
   338 	  FOR_EACH_LOC(typename ResGraph::NodeIt, n, res_graph){
   339 	    potential[n] += dijkstra.distMap()[n];
   340 	  }
   341 
   342 
   343 	  //Augmenting on the sortest path
   344 	  Node n=t;
   345 	  ResGraphEdge e;
   346 	  while (n!=s){
   347 	    e = dijkstra.pred(n);
   348 	    n = dijkstra.predNode(n);
   349 	    res_graph.augment(e,delta);
   350 	    /*
   351 	    //Let's update the total cost
   352 	    if (res_graph.forward(e))
   353 	      total_cost += cost[e];
   354 	    else 
   355 	      total_cost -= cost[e];	    
   356 	    */
   357 	  }
   358 	  
   359 	  //Update the excess_deficit map
   360 	  excess_deficit[s] -= delta;
   361 	  excess_deficit[t] += delta;
   362 	  
   363 
   364 	  //Update the excess_nodes heap
   365 	  if (delta >= excess_nodes[s]){
   366 	    if (delta > excess_nodes[s])
   367 	      deficit_nodes.push(s,delta - excess_nodes[s]);
   368 	    excess_nodes.pop();
   369 	    
   370 	  } 
   371 	  else{
   372 	    excess_nodes[s] -= delta;
   373 	  }
   374 	  //Update the deficit_nodes heap
   375 	  if (delta >= deficit_nodes[t]){
   376 	    if (delta > deficit_nodes[t])
   377 	      excess_nodes.push(t,delta - deficit_nodes[t]);
   378 	    deficit_nodes.pop();
   379 	    
   380 	  } 
   381 	  else{
   382 	    deficit_nodes[t] -= delta;
   383 	  }
   384 	  //Dijkstra part ends here
   385 	  
   386 	  //Choose s and t again
   387 	  s = excess_nodes.top(); 
   388 	  max_excess = excess_nodes[s];
   389 	  t = deficit_nodes.top(); 
   390 	  if (max_excess < deficit_nodes[t]){
   391 	    max_excess = deficit_nodes[t];
   392 	  }
   393 
   394 	}
   395 
   396 	/*
   397 	 * End of the delta scaling phase 
   398 	*/
   399 
   400 	//Whatever this means
   401 	delta = delta / 2;
   402 
   403 	/*This is not necessary here
   404 	//Update the max_excess
   405 	max_excess = 0;
   406 	FOR_EACH_LOC(typename Graph::NodeIt, n, graph){
   407 	  if (max_excess < excess_deficit[n]){
   408 	    max_excess = excess_deficit[n];
   409 	  }
   410 	}
   411 	*/
   412 
   413 	  
   414       }//while(max_excess > 0)
   415       
   416 
   417       return i;
   418     }
   419 
   420 
   421 
   422 
   423     ///This function gives back the total cost of the found paths.
   424     ///Assumes that \c run() has been run and nothing changed since then.
   425     Cost totalCost(){
   426       return total_cost;
   427     }
   428 
   429     ///Returns a const reference to the EdgeMap \c flow. \pre \ref run() must
   430     ///be called before using this function.
   431     const FlowMap &getFlow() const { return flow;}
   432 
   433   ///Returns a const reference to the NodeMap \c potential (the dual solution).
   434     /// \pre \ref run() must be called before using this function.
   435     const PotentialMap &getPotential() const { return potential;}
   436 
   437     ///This function checks, whether the given solution is optimal
   438     ///Running after a \c run() should return with true
   439     ///In this "state of the art" this only check optimality, doesn't bother with feasibility
   440     ///
   441     ///\todo Is this OK here?
   442     bool checkComplementarySlackness(){
   443       Cost mod_pot;
   444       Cost fl_e;
   445       FOR_EACH_LOC(typename Graph::EdgeIt, e, graph){
   446 	//C^{\Pi}_{i,j}
   447 	mod_pot = cost[e]-potential[graph.head(e)]+potential[graph.tail(e)];
   448 	fl_e = flow[e];
   449 	//	std::cout << fl_e << std::endl;
   450 	if (0<fl_e && fl_e<capacity[e]){
   451 	  if (mod_pot != 0)
   452 	    return false;
   453 	}
   454 	else{
   455 	  if (mod_pot > 0 && fl_e != 0)
   456 	    return false;
   457 	  if (mod_pot < 0 && fl_e != capacity[e])
   458 	    return false;
   459 	}
   460       }
   461       return true;
   462     }
   463     
   464 
   465   }; //class MinCostFlow
   466 
   467   ///@}
   468 
   469 } //namespace hugo
   470 
   471 #endif //HUGO_MINCOSTFLOW_H