lemon/cycle_canceling.h
changeset 2442 27b7c7de9cac
child 2457 8c791ee69a45
equal deleted inserted replaced
-1:000000000000 0:8eb62b97ed3e
       
     1 /* -*- C++ -*-
       
     2  *
       
     3  * This file is a part of LEMON, a generic C++ optimization library
       
     4  *
       
     5  * Copyright (C) 2003-2007
       
     6  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
       
     7  * (Egervary Research Group on Combinatorial Optimization, EGRES).
       
     8  *
       
     9  * Permission to use, modify and distribute this software is granted
       
    10  * provided that this copyright notice appears in all copies. For
       
    11  * precise terms see the accompanying LICENSE file.
       
    12  *
       
    13  * This software is provided "AS IS" with no warranty of any kind,
       
    14  * express or implied, and with no claim as to its suitability for any
       
    15  * purpose.
       
    16  *
       
    17  */
       
    18 
       
    19 #ifndef LEMON_CYCLE_CANCELING_H
       
    20 #define LEMON_CYCLE_CANCELING_H
       
    21 
       
    22 /// \ingroup min_cost_flow
       
    23 ///
       
    24 /// \file
       
    25 /// \brief A cycle canceling algorithm for finding a minimum cost flow.
       
    26 
       
    27 #include <vector>
       
    28 #include <lemon/circulation.h>
       
    29 #include <lemon/graph_adaptor.h>
       
    30 
       
    31 /// \brief The used cycle canceling method.
       
    32 #define LIMITED_CYCLE_CANCELING
       
    33 //#define MIN_MEAN_CYCLE_CANCELING
       
    34 
       
    35 #ifdef LIMITED_CYCLE_CANCELING
       
    36   #include <lemon/bellman_ford.h>
       
    37   /// \brief The maximum number of iterations for the first execution
       
    38   /// of the \ref lemon::BellmanFord "Bellman-Ford" algorithm.
       
    39   #define STARTING_LIMIT	2
       
    40   /// \brief The iteration limit for the
       
    41   /// \ref lemon::BellmanFord "Bellman-Ford" algorithm is multiplied by
       
    42   /// <tt>ALPHA_MUL % ALPHA_DIV</tt> in every round.
       
    43   #define ALPHA_MUL		3
       
    44   /// \brief The iteration limit for the
       
    45   /// \ref lemon::BellmanFord "Bellman-Ford" algorithm is multiplied by
       
    46   /// <tt>ALPHA_MUL % ALPHA_DIV</tt> in every round.
       
    47   #define ALPHA_DIV		2
       
    48 
       
    49 //#define _ONLY_ONE_CYCLE_
       
    50 //#define _DEBUG_ITER_
       
    51 #endif
       
    52 
       
    53 #ifdef MIN_MEAN_CYCLE_CANCELING
       
    54   #include <lemon/min_mean_cycle.h>
       
    55   #include <lemon/path.h>
       
    56 #endif
       
    57 
       
    58 namespace lemon {
       
    59 
       
    60   /// \addtogroup min_cost_flow
       
    61   /// @{
       
    62 
       
    63   /// \brief Implementation of a cycle canceling algorithm for finding
       
    64   /// a minimum cost flow.
       
    65   ///
       
    66   /// \ref lemon::CycleCanceling "CycleCanceling" implements a cycle
       
    67   /// canceling algorithm for finding a minimum cost flow.
       
    68   ///
       
    69   /// \param Graph The directed graph type the algorithm runs on.
       
    70   /// \param LowerMap The type of the lower bound map.
       
    71   /// \param CapacityMap The type of the capacity (upper bound) map.
       
    72   /// \param CostMap The type of the cost (length) map.
       
    73   /// \param SupplyMap The type of the supply map.
       
    74   ///
       
    75   /// \warning
       
    76   /// - Edge capacities and costs should be nonnegative integers.
       
    77   ///	However \c CostMap::Value should be signed type.
       
    78   /// - Supply values should be integers.
       
    79   /// - \c LowerMap::Value must be convertible to
       
    80   ///	\c CapacityMap::Value and \c CapacityMap::Value must be
       
    81   ///	convertible to \c SupplyMap::Value.
       
    82   ///
       
    83   /// \author Peter Kovacs
       
    84 
       
    85 template < typename Graph,
       
    86 	   typename LowerMap = typename Graph::template EdgeMap<int>,
       
    87 	   typename CapacityMap = LowerMap,
       
    88 	   typename CostMap = typename Graph::template EdgeMap<int>,
       
    89 	   typename SupplyMap = typename Graph::template NodeMap
       
    90 				<typename CapacityMap::Value> >
       
    91   class CycleCanceling
       
    92   {
       
    93     typedef typename Graph::Node Node;
       
    94     typedef typename Graph::NodeIt NodeIt;
       
    95     typedef typename Graph::Edge Edge;
       
    96     typedef typename Graph::EdgeIt EdgeIt;
       
    97     typedef typename Graph::InEdgeIt InEdgeIt;
       
    98     typedef typename Graph::OutEdgeIt OutEdgeIt;
       
    99 
       
   100     typedef typename LowerMap::Value Lower;
       
   101     typedef typename CapacityMap::Value Capacity;
       
   102     typedef typename CostMap::Value Cost;
       
   103     typedef typename SupplyMap::Value Supply;
       
   104     typedef typename Graph::template EdgeMap<Capacity> CapacityRefMap;
       
   105     typedef typename Graph::template NodeMap<Supply> SupplyRefMap;
       
   106 
       
   107     typedef ResGraphAdaptor< const Graph, Capacity,
       
   108 			     CapacityRefMap, CapacityRefMap > ResGraph;
       
   109     typedef typename ResGraph::Node ResNode;
       
   110     typedef typename ResGraph::NodeIt ResNodeIt;
       
   111     typedef typename ResGraph::Edge ResEdge;
       
   112     typedef typename ResGraph::EdgeIt ResEdgeIt;
       
   113 
       
   114   public:
       
   115 
       
   116     /// \brief The type of the flow map.
       
   117     typedef CapacityRefMap FlowMap;
       
   118 
       
   119   protected:
       
   120 
       
   121     /// \brief Map adaptor class for demand map.
       
   122     class DemandMap : public MapBase<Node, Supply>
       
   123     {
       
   124     private:
       
   125 
       
   126       const SupplyMap *map;
       
   127 
       
   128     public:
       
   129 
       
   130       typedef typename MapBase<Node, Supply>::Value Value;
       
   131       typedef typename MapBase<Node, Supply>::Key Key;
       
   132 
       
   133       DemandMap(const SupplyMap &_map) : map(&_map) {}
       
   134 
       
   135       Value operator[](const Key &e) const {
       
   136 	return -(*map)[e];
       
   137       }
       
   138 
       
   139     }; //class DemandMap
       
   140 
       
   141     /// \brief Map adaptor class for handling residual edge costs.
       
   142     class ResCostMap : public MapBase<ResEdge, Cost>
       
   143     {
       
   144     private:
       
   145 
       
   146       const CostMap &cost_map;
       
   147 
       
   148     public:
       
   149 
       
   150       typedef typename MapBase<ResEdge, Cost>::Value Value;
       
   151       typedef typename MapBase<ResEdge, Cost>::Key Key;
       
   152 
       
   153       ResCostMap(const CostMap &_cost) : cost_map(_cost) {}
       
   154 
       
   155       Value operator[](const Key &e) const {
       
   156 	return ResGraph::forward(e) ? cost_map[e] : -cost_map[e];
       
   157       }
       
   158 
       
   159     }; //class ResCostMap
       
   160 
       
   161   protected:
       
   162 
       
   163     /// \brief The directed graph the algorithm runs on.
       
   164     const Graph &graph;
       
   165     /// \brief The original lower bound map.
       
   166     const LowerMap *lower;
       
   167     /// \brief The modified capacity map.
       
   168     CapacityRefMap capacity;
       
   169     /// \brief The cost map.
       
   170     const CostMap &cost;
       
   171     /// \brief The modified supply map.
       
   172     SupplyRefMap supply;
       
   173     /// \brief The modified demand map.
       
   174     DemandMap demand;
       
   175     /// \brief The sum of supply values equals zero.
       
   176     bool valid_supply;
       
   177 
       
   178     /// \brief The current flow.
       
   179     FlowMap flow;
       
   180     /// \brief The residual graph.
       
   181     ResGraph res_graph;
       
   182     /// \brief The residual cost map.
       
   183     ResCostMap res_cost;
       
   184 
       
   185   public :
       
   186 
       
   187     /// \brief General constructor of the class (with lower bounds).
       
   188     ///
       
   189     /// General constructor of the class (with lower bounds).
       
   190     ///
       
   191     /// \param _graph The directed graph the algorithm runs on.
       
   192     /// \param _lower The lower bounds of the edges.
       
   193     /// \param _capacity The capacities (upper bounds) of the edges.
       
   194     /// \param _cost The cost (length) values of the edges.
       
   195     /// \param _supply The supply values of the nodes (signed).
       
   196     CycleCanceling( const Graph &_graph,
       
   197 		    const LowerMap &_lower,
       
   198 		    const CapacityMap &_capacity,
       
   199 		    const CostMap &_cost,
       
   200 		    const SupplyMap &_supply ) :
       
   201       graph(_graph), lower(&_lower), capacity(_graph), cost(_cost),
       
   202       supply(_graph), demand(supply), flow(_graph, 0),
       
   203       res_graph(_graph, capacity, flow), res_cost(cost)
       
   204     {
       
   205       // Removing nonzero lower bounds
       
   206       capacity = subMap(_capacity, _lower);
       
   207       Supply sum = 0;
       
   208       for (NodeIt n(graph); n != INVALID; ++n) {
       
   209 	Supply s = _supply[n];
       
   210 	for (InEdgeIt e(graph, n); e != INVALID; ++e)
       
   211 	  s += _lower[e];
       
   212 	for (OutEdgeIt e(graph, n); e != INVALID; ++e)
       
   213 	  s -= _lower[e];
       
   214 	sum += (supply[n] = s);
       
   215       }
       
   216       valid_supply = sum == 0;
       
   217     }
       
   218 
       
   219     /// \brief General constructor of the class (without lower bounds).
       
   220     ///
       
   221     /// General constructor of the class (without lower bounds).
       
   222     ///
       
   223     /// \param _graph The directed graph the algorithm runs on.
       
   224     /// \param _capacity The capacities (upper bounds) of the edges.
       
   225     /// \param _cost The cost (length) values of the edges.
       
   226     /// \param _supply The supply values of the nodes (signed).
       
   227     CycleCanceling( const Graph &_graph,
       
   228 		    const CapacityMap &_capacity,
       
   229 		    const CostMap &_cost,
       
   230 		    const SupplyMap &_supply ) :
       
   231       graph(_graph), lower(NULL), capacity(_capacity), cost(_cost),
       
   232       supply(_supply), demand(supply), flow(_graph, 0),
       
   233       res_graph(_graph, capacity, flow), res_cost(cost)
       
   234     {
       
   235       // Checking the sum of supply values
       
   236       Supply sum = 0;
       
   237       for (NodeIt n(graph); n != INVALID; ++n) sum += supply[n];
       
   238       valid_supply = sum == 0;
       
   239     }
       
   240 
       
   241 
       
   242     /// \brief Simple constructor of the class (with lower bounds).
       
   243     ///
       
   244     /// Simple constructor of the class (with lower bounds).
       
   245     ///
       
   246     /// \param _graph The directed graph the algorithm runs on.
       
   247     /// \param _lower The lower bounds of the edges.
       
   248     /// \param _capacity The capacities (upper bounds) of the edges.
       
   249     /// \param _cost The cost (length) values of the edges.
       
   250     /// \param _s The source node.
       
   251     /// \param _t The target node.
       
   252     /// \param _flow_value The required amount of flow from node \c _s
       
   253     /// to node \c _t (i.e. the supply of \c _s and the demand of
       
   254     /// \c _t).
       
   255     CycleCanceling( const Graph &_graph,
       
   256 		    const LowerMap &_lower,
       
   257 		    const CapacityMap &_capacity,
       
   258 		    const CostMap &_cost,
       
   259 		    Node _s, Node _t,
       
   260 		    Supply _flow_value ) :
       
   261       graph(_graph), lower(&_lower), capacity(_graph), cost(_cost),
       
   262       supply(_graph), demand(supply), flow(_graph, 0),
       
   263       res_graph(_graph, capacity, flow), res_cost(cost)
       
   264     {
       
   265       // Removing nonzero lower bounds
       
   266       capacity = subMap(_capacity, _lower);
       
   267       for (NodeIt n(graph); n != INVALID; ++n) {
       
   268 	Supply s = 0;
       
   269 	if (n == _s) s =  _flow_value;
       
   270 	if (n == _t) s = -_flow_value;
       
   271 	for (InEdgeIt e(graph, n); e != INVALID; ++e)
       
   272 	  s += _lower[e];
       
   273 	for (OutEdgeIt e(graph, n); e != INVALID; ++e)
       
   274 	  s -= _lower[e];
       
   275 	supply[n] = s;
       
   276       }
       
   277       valid_supply = true;
       
   278     }
       
   279 
       
   280     /// \brief Simple constructor of the class (without lower bounds).
       
   281     ///
       
   282     /// Simple constructor of the class (without lower bounds).
       
   283     ///
       
   284     /// \param _graph The directed graph the algorithm runs on.
       
   285     /// \param _capacity The capacities (upper bounds) of the edges.
       
   286     /// \param _cost The cost (length) values of the edges.
       
   287     /// \param _s The source node.
       
   288     /// \param _t The target node.
       
   289     /// \param _flow_value The required amount of flow from node \c _s
       
   290     /// to node \c _t (i.e. the supply of \c _s and the demand of
       
   291     /// \c _t).
       
   292     CycleCanceling( const Graph &_graph,
       
   293 		    const CapacityMap &_capacity,
       
   294 		    const CostMap &_cost,
       
   295 		    Node _s, Node _t,
       
   296 		    Supply _flow_value ) :
       
   297       graph(_graph), lower(NULL), capacity(_capacity), cost(_cost),
       
   298       supply(_graph, 0), demand(supply), flow(_graph, 0),
       
   299       res_graph(_graph, capacity, flow), res_cost(cost)
       
   300     {
       
   301       supply[_s] =  _flow_value;
       
   302       supply[_t] = -_flow_value;
       
   303       valid_supply = true;
       
   304     }
       
   305 
       
   306     /// \brief Returns a const reference to the flow map.
       
   307     ///
       
   308     /// Returns a const reference to the flow map.
       
   309     ///
       
   310     /// \pre \ref run() must be called before using this function.
       
   311     const FlowMap& flowMap() const {
       
   312       return flow;
       
   313     }
       
   314 
       
   315     /// \brief Returns the total cost of the found flow.
       
   316     ///
       
   317     /// Returns the total cost of the found flow. The complexity of the
       
   318     /// function is \f$ O(e) \f$.
       
   319     ///
       
   320     /// \pre \ref run() must be called before using this function.
       
   321     Cost totalCost() const {
       
   322       Cost c = 0;
       
   323       for (EdgeIt e(graph); e != INVALID; ++e)
       
   324 	c += flow[e] * cost[e];
       
   325       return c;
       
   326     }
       
   327 
       
   328     /// \brief Runs the algorithm.
       
   329     ///
       
   330     /// Runs the algorithm.
       
   331     ///
       
   332     /// \return \c true if a feasible flow can be found.
       
   333     bool run() {
       
   334       return init() && start();
       
   335     }
       
   336 
       
   337   protected:
       
   338 
       
   339     /// \brief Initializes the algorithm.
       
   340     bool init() {
       
   341       // Checking the sum of supply values
       
   342       Supply sum = 0;
       
   343       for (NodeIt n(graph); n != INVALID; ++n) sum += supply[n];
       
   344       if (sum != 0) return false;
       
   345 
       
   346       // Finding a feasible flow
       
   347       Circulation< Graph, Capacity, FlowMap, ConstMap<Edge, Capacity>,
       
   348 		   CapacityRefMap, DemandMap >
       
   349 	circulation( graph, constMap<Edge>((Capacity)0),
       
   350 		     capacity, demand, flow );
       
   351       return circulation.run() == -1;
       
   352     }
       
   353 
       
   354 #ifdef LIMITED_CYCLE_CANCELING
       
   355     /// \brief Executes a cycle canceling algorithm using
       
   356     /// \ref lemon::BellmanFord "Bellman-Ford" algorithm with limited
       
   357     /// iteration count.
       
   358     bool start() {
       
   359       typename BellmanFord<ResGraph, ResCostMap>::PredMap pred(res_graph);
       
   360       typename ResGraph::template NodeMap<int> visited(res_graph);
       
   361       std::vector<ResEdge> cycle;
       
   362       int node_num = countNodes(graph);
       
   363 
       
   364 #ifdef _DEBUG_ITER_
       
   365       int cycle_num = 0;
       
   366 #endif
       
   367       int length_bound = STARTING_LIMIT;
       
   368       bool optimal = false;
       
   369       while (!optimal) {
       
   370 	BellmanFord<ResGraph, ResCostMap> bf(res_graph, res_cost);
       
   371 	bf.predMap(pred);
       
   372 	bf.init(0);
       
   373 	int iter_num = 0;
       
   374 	bool cycle_found = false;
       
   375 	while (!cycle_found) {
       
   376 	  int curr_iter_num = iter_num + length_bound <= node_num ?
       
   377 			      length_bound : node_num - iter_num;
       
   378 	  iter_num += curr_iter_num;
       
   379 	  int real_iter_num = curr_iter_num;
       
   380 	  for (int i = 0; i < curr_iter_num; ++i) {
       
   381 	    if (bf.processNextWeakRound()) {
       
   382 	      real_iter_num = i;
       
   383 	      break;
       
   384 	    }
       
   385 	  }
       
   386 	  if (real_iter_num < curr_iter_num) {
       
   387 	    optimal = true;
       
   388 	    break;
       
   389 	  } else {
       
   390 	    // Searching for node disjoint negative cycles
       
   391 	    for (ResNodeIt n(res_graph); n != INVALID; ++n)
       
   392 	      visited[n] = 0;
       
   393 	    int id = 0;
       
   394 	    for (ResNodeIt n(res_graph); n != INVALID; ++n) {
       
   395 	      if (visited[n] > 0) continue;
       
   396 	      visited[n] = ++id;
       
   397 	      ResNode u = pred[n] == INVALID ?
       
   398 			  INVALID : res_graph.source(pred[n]);
       
   399 	      while (u != INVALID && visited[u] == 0) {
       
   400 		visited[u] = id;
       
   401 		u = pred[u] == INVALID ?
       
   402 		    INVALID : res_graph.source(pred[u]);
       
   403 	      }
       
   404 	      if (u != INVALID && visited[u] == id) {
       
   405 		// Finding the negative cycle
       
   406 		cycle_found = true;
       
   407 		cycle.clear();
       
   408 		ResEdge e = pred[u];
       
   409 		cycle.push_back(e);
       
   410 		Capacity d = res_graph.rescap(e);
       
   411 		while (res_graph.source(e) != u) {
       
   412 		  cycle.push_back(e = pred[res_graph.source(e)]);
       
   413 		  if (res_graph.rescap(e) < d)
       
   414 		    d = res_graph.rescap(e);
       
   415 		}
       
   416 #ifdef _DEBUG_ITER_
       
   417 		++cycle_num;
       
   418 #endif
       
   419 		// Augmenting along the cycle
       
   420 		for (int i = 0; i < cycle.size(); ++i)
       
   421 		  res_graph.augment(cycle[i], d);
       
   422 #ifdef _ONLY_ONE_CYCLE_
       
   423 		break;
       
   424 #endif
       
   425 	      }
       
   426 	    }
       
   427 	  }
       
   428 
       
   429 	  if (!cycle_found)
       
   430 	    length_bound = length_bound * ALPHA_MUL / ALPHA_DIV;
       
   431 	}
       
   432       }
       
   433 
       
   434 #ifdef _DEBUG_ITER_
       
   435       std::cout << "Limited cycle canceling algorithm finished. "
       
   436 		<< "Found " << cycle_num << " negative cycles."
       
   437 		<< std::endl;
       
   438 #endif
       
   439 
       
   440       // Handling nonzero lower bounds
       
   441       if (lower) {
       
   442 	for (EdgeIt e(graph); e != INVALID; ++e)
       
   443 	  flow[e] += (*lower)[e];
       
   444       }
       
   445       return true;
       
   446     }
       
   447 #endif
       
   448 
       
   449 #ifdef MIN_MEAN_CYCLE_CANCELING
       
   450     /// \brief Executes the minimum mean cycle canceling algorithm
       
   451     /// using \ref lemon::MinMeanCycle "MinMeanCycle" class.
       
   452     bool start() {
       
   453       typedef Path<ResGraph> ResPath;
       
   454       MinMeanCycle<ResGraph, ResCostMap> mmc(res_graph, res_cost);
       
   455       ResPath cycle;
       
   456 
       
   457 #ifdef _DEBUG_ITER_
       
   458       int cycle_num = 0;
       
   459 #endif
       
   460       mmc.cyclePath(cycle).init();
       
   461       if (mmc.findMinMean()) {
       
   462 	while (mmc.cycleLength() < 0) {
       
   463 #ifdef _DEBUG_ITER_
       
   464 	  ++iter;
       
   465 #endif
       
   466 	  // Finding the cycle
       
   467 	  mmc.findCycle();
       
   468 
       
   469 	  // Finding the largest flow amount that can be augmented
       
   470 	  // along the cycle
       
   471 	  Capacity delta = 0;
       
   472 	  for (typename ResPath::EdgeIt e(cycle); e != INVALID; ++e) {
       
   473 	    if (delta == 0 || res_graph.rescap(e) < delta)
       
   474 	      delta = res_graph.rescap(e);
       
   475 	  }
       
   476 
       
   477 	  // Augmenting along the cycle
       
   478 	  for (typename ResPath::EdgeIt e(cycle); e != INVALID; ++e)
       
   479 	    res_graph.augment(e, delta);
       
   480 
       
   481 	  // Finding the minimum cycle mean for the modified residual
       
   482 	  // graph
       
   483 	  mmc.reset();
       
   484 	  if (!mmc.findMinMean()) break;
       
   485 	}
       
   486       }
       
   487 
       
   488 #ifdef _DEBUG_ITER_
       
   489       std::cout << "Minimum mean cycle canceling algorithm finished. "
       
   490 		<< "Found " << cycle_num << " negative cycles."
       
   491 		<< std::endl;
       
   492 #endif
       
   493 
       
   494       // Handling nonzero lower bounds
       
   495       if (lower) {
       
   496 	for (EdgeIt e(graph); e != INVALID; ++e)
       
   497 	  flow[e] += (*lower)[e];
       
   498       }
       
   499       return true;
       
   500     }
       
   501 #endif
       
   502 
       
   503   }; //class CycleCanceling
       
   504 
       
   505   ///@}
       
   506 
       
   507 } //namespace lemon
       
   508 
       
   509 #endif //LEMON_CYCLE_CANCELING_H