deba@2440: /* -*- C++ -*- deba@2440: * deba@2440: * This file is a part of LEMON, a generic C++ optimization library deba@2440: * alpar@2553: * Copyright (C) 2003-2008 deba@2440: * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport deba@2440: * (Egervary Research Group on Combinatorial Optimization, EGRES). deba@2440: * deba@2440: * Permission to use, modify and distribute this software is granted deba@2440: * provided that this copyright notice appears in all copies. For deba@2440: * precise terms see the accompanying LICENSE file. deba@2440: * deba@2440: * This software is provided "AS IS" with no warranty of any kind, deba@2440: * express or implied, and with no claim as to its suitability for any deba@2440: * purpose. deba@2440: * deba@2440: */ deba@2440: deba@2440: #ifndef LEMON_CYCLE_CANCELING_H deba@2440: #define LEMON_CYCLE_CANCELING_H deba@2440: deba@2440: /// \ingroup min_cost_flow deba@2440: /// deba@2440: /// \file deba@2457: /// \brief A cycle-canceling algorithm for finding a minimum cost flow. deba@2440: deba@2440: #include kpeter@2509: #include deba@2440: #include deba@2440: deba@2457: /// \brief The used cycle-canceling method. deba@2440: #define LIMITED_CYCLE_CANCELING deba@2440: //#define MIN_MEAN_CYCLE_CANCELING deba@2440: deba@2440: #ifdef LIMITED_CYCLE_CANCELING deba@2440: #include kpeter@2556: // The maximum number of iterations for the first execution of the kpeter@2556: // Bellman-Ford algorithm. It should be at least 2. kpeter@2556: #define STARTING_LIMIT 2 kpeter@2556: // The iteration limit for the Bellman-Ford algorithm is multiplied by kpeter@2556: // ALPHA_MUL / ALPHA_DIV in every round. kpeter@2556: // ALPHA_MUL / ALPHA_DIV must be greater than 1. kpeter@2556: #define ALPHA_MUL 3 kpeter@2556: #define ALPHA_DIV 2 deba@2440: deba@2440: //#define _ONLY_ONE_CYCLE_ deba@2457: //#define _NO_BACK_STEP_ deba@2440: #endif deba@2440: deba@2440: #ifdef MIN_MEAN_CYCLE_CANCELING deba@2440: #include deba@2440: #include deba@2440: #endif deba@2440: kpeter@2556: //#define _DEBUG_ITER_ kpeter@2556: deba@2440: namespace lemon { deba@2440: deba@2440: /// \addtogroup min_cost_flow deba@2440: /// @{ deba@2440: kpeter@2556: /// \brief Implementation of a cycle-canceling algorithm for kpeter@2556: /// finding a minimum cost flow. deba@2440: /// kpeter@2556: /// \ref CycleCanceling implements a cycle-canceling algorithm for kpeter@2556: /// finding a minimum cost flow. deba@2440: /// deba@2440: /// \param Graph The directed graph type the algorithm runs on. deba@2440: /// \param LowerMap The type of the lower bound map. deba@2440: /// \param CapacityMap The type of the capacity (upper bound) map. deba@2440: /// \param CostMap The type of the cost (length) map. deba@2440: /// \param SupplyMap The type of the supply map. deba@2440: /// deba@2440: /// \warning kpeter@2556: /// - Edge capacities and costs should be non-negative integers. kpeter@2556: /// However \c CostMap::Value should be signed type. kpeter@2509: /// - Supply values should be signed integers. deba@2440: /// - \c LowerMap::Value must be convertible to kpeter@2556: /// \c CapacityMap::Value and \c CapacityMap::Value must be kpeter@2556: /// convertible to \c SupplyMap::Value. deba@2440: /// deba@2440: /// \author Peter Kovacs deba@2440: kpeter@2533: template < typename Graph, kpeter@2533: typename LowerMap = typename Graph::template EdgeMap, kpeter@2533: typename CapacityMap = LowerMap, kpeter@2533: typename CostMap = typename Graph::template EdgeMap, kpeter@2533: typename SupplyMap = typename Graph::template NodeMap kpeter@2533: > deba@2440: class CycleCanceling deba@2440: { kpeter@2556: GRAPH_TYPEDEFS(typename Graph); deba@2440: deba@2440: typedef typename LowerMap::Value Lower; deba@2440: typedef typename CapacityMap::Value Capacity; deba@2440: typedef typename CostMap::Value Cost; deba@2440: typedef typename SupplyMap::Value Supply; kpeter@2556: typedef typename Graph::template EdgeMap CapacityEdgeMap; kpeter@2556: typedef typename Graph::template NodeMap SupplyNodeMap; deba@2440: deba@2440: typedef ResGraphAdaptor< const Graph, Capacity, kpeter@2556: CapacityEdgeMap, CapacityEdgeMap > ResGraph; deba@2440: typedef typename ResGraph::Node ResNode; deba@2440: typedef typename ResGraph::NodeIt ResNodeIt; deba@2440: typedef typename ResGraph::Edge ResEdge; deba@2440: typedef typename ResGraph::EdgeIt ResEdgeIt; deba@2440: deba@2440: public: deba@2440: kpeter@2556: /// The type of the flow map. kpeter@2556: typedef typename Graph::template EdgeMap FlowMap; deba@2440: deba@2440: protected: deba@2440: kpeter@2556: /// Map adaptor class for handling residual edge costs. deba@2440: class ResCostMap : public MapBase deba@2440: { deba@2440: private: deba@2440: deba@2440: const CostMap &cost_map; deba@2440: deba@2440: public: deba@2440: deba@2440: ResCostMap(const CostMap &_cost) : cost_map(_cost) {} deba@2440: kpeter@2509: Cost operator[](const ResEdge &e) const { kpeter@2556: return ResGraph::forward(e) ? cost_map[e] : -cost_map[e]; deba@2440: } deba@2440: deba@2440: }; //class ResCostMap deba@2440: deba@2440: protected: deba@2440: kpeter@2556: /// The directed graph the algorithm runs on. deba@2440: const Graph &graph; kpeter@2556: /// The original lower bound map. deba@2440: const LowerMap *lower; kpeter@2556: /// The modified capacity map. kpeter@2556: CapacityEdgeMap capacity; kpeter@2556: /// The cost map. deba@2440: const CostMap &cost; kpeter@2556: /// The modified supply map. kpeter@2556: SupplyNodeMap supply; deba@2440: bool valid_supply; deba@2440: kpeter@2556: /// The current flow. deba@2440: FlowMap flow; kpeter@2556: /// The residual graph. deba@2440: ResGraph res_graph; kpeter@2556: /// The residual cost map. deba@2440: ResCostMap res_cost; deba@2440: deba@2440: public : deba@2440: deba@2440: /// \brief General constructor of the class (with lower bounds). deba@2440: /// deba@2440: /// General constructor of the class (with lower bounds). deba@2440: /// deba@2440: /// \param _graph The directed graph the algorithm runs on. deba@2440: /// \param _lower The lower bounds of the edges. deba@2440: /// \param _capacity The capacities (upper bounds) of the edges. deba@2440: /// \param _cost The cost (length) values of the edges. deba@2440: /// \param _supply The supply values of the nodes (signed). deba@2440: CycleCanceling( const Graph &_graph, kpeter@2556: const LowerMap &_lower, kpeter@2556: const CapacityMap &_capacity, kpeter@2556: const CostMap &_cost, kpeter@2556: const SupplyMap &_supply ) : deba@2440: graph(_graph), lower(&_lower), capacity(_graph), cost(_cost), deba@2457: supply(_graph), flow(_graph, 0), deba@2440: res_graph(_graph, capacity, flow), res_cost(cost) deba@2440: { kpeter@2556: // Removing non-zero lower bounds deba@2440: capacity = subMap(_capacity, _lower); deba@2440: Supply sum = 0; deba@2440: for (NodeIt n(graph); n != INVALID; ++n) { kpeter@2556: Supply s = _supply[n]; kpeter@2556: for (InEdgeIt e(graph, n); e != INVALID; ++e) kpeter@2556: s += _lower[e]; kpeter@2556: for (OutEdgeIt e(graph, n); e != INVALID; ++e) kpeter@2556: s -= _lower[e]; kpeter@2556: sum += (supply[n] = s); deba@2440: } deba@2440: valid_supply = sum == 0; deba@2440: } deba@2440: deba@2440: /// \brief General constructor of the class (without lower bounds). deba@2440: /// deba@2440: /// General constructor of the class (without lower bounds). deba@2440: /// deba@2440: /// \param _graph The directed graph the algorithm runs on. deba@2440: /// \param _capacity The capacities (upper bounds) of the edges. deba@2440: /// \param _cost The cost (length) values of the edges. deba@2440: /// \param _supply The supply values of the nodes (signed). deba@2440: CycleCanceling( const Graph &_graph, kpeter@2556: const CapacityMap &_capacity, kpeter@2556: const CostMap &_cost, kpeter@2556: const SupplyMap &_supply ) : deba@2440: graph(_graph), lower(NULL), capacity(_capacity), cost(_cost), deba@2457: supply(_supply), flow(_graph, 0), deba@2440: res_graph(_graph, capacity, flow), res_cost(cost) deba@2440: { deba@2440: // Checking the sum of supply values deba@2440: Supply sum = 0; deba@2440: for (NodeIt n(graph); n != INVALID; ++n) sum += supply[n]; deba@2440: valid_supply = sum == 0; deba@2440: } deba@2440: deba@2440: /// \brief Simple constructor of the class (with lower bounds). deba@2440: /// deba@2440: /// Simple constructor of the class (with lower bounds). deba@2440: /// deba@2440: /// \param _graph The directed graph the algorithm runs on. deba@2440: /// \param _lower The lower bounds of the edges. deba@2440: /// \param _capacity The capacities (upper bounds) of the edges. deba@2440: /// \param _cost The cost (length) values of the edges. deba@2440: /// \param _s The source node. deba@2440: /// \param _t The target node. deba@2440: /// \param _flow_value The required amount of flow from node \c _s kpeter@2556: /// to node \c _t (i.e. the supply of \c _s and the demand of \c _t). deba@2440: CycleCanceling( const Graph &_graph, kpeter@2556: const LowerMap &_lower, kpeter@2556: const CapacityMap &_capacity, kpeter@2556: const CostMap &_cost, kpeter@2556: Node _s, Node _t, kpeter@2556: Supply _flow_value ) : deba@2440: graph(_graph), lower(&_lower), capacity(_graph), cost(_cost), deba@2457: supply(_graph), flow(_graph, 0), deba@2440: res_graph(_graph, capacity, flow), res_cost(cost) deba@2440: { kpeter@2556: // Removing non-zero lower bounds deba@2440: capacity = subMap(_capacity, _lower); deba@2440: for (NodeIt n(graph); n != INVALID; ++n) { kpeter@2556: Supply s = 0; kpeter@2556: if (n == _s) s = _flow_value; kpeter@2556: if (n == _t) s = -_flow_value; kpeter@2556: for (InEdgeIt e(graph, n); e != INVALID; ++e) kpeter@2556: s += _lower[e]; kpeter@2556: for (OutEdgeIt e(graph, n); e != INVALID; ++e) kpeter@2556: s -= _lower[e]; kpeter@2556: supply[n] = s; deba@2440: } deba@2440: valid_supply = true; deba@2440: } deba@2440: deba@2440: /// \brief Simple constructor of the class (without lower bounds). deba@2440: /// deba@2440: /// Simple constructor of the class (without lower bounds). deba@2440: /// deba@2440: /// \param _graph The directed graph the algorithm runs on. deba@2440: /// \param _capacity The capacities (upper bounds) of the edges. deba@2440: /// \param _cost The cost (length) values of the edges. deba@2440: /// \param _s The source node. deba@2440: /// \param _t The target node. deba@2440: /// \param _flow_value The required amount of flow from node \c _s kpeter@2556: /// to node \c _t (i.e. the supply of \c _s and the demand of \c _t). deba@2440: CycleCanceling( const Graph &_graph, kpeter@2556: const CapacityMap &_capacity, kpeter@2556: const CostMap &_cost, kpeter@2556: Node _s, Node _t, kpeter@2556: Supply _flow_value ) : deba@2440: graph(_graph), lower(NULL), capacity(_capacity), cost(_cost), deba@2457: supply(_graph, 0), flow(_graph, 0), deba@2440: res_graph(_graph, capacity, flow), res_cost(cost) deba@2440: { deba@2440: supply[_s] = _flow_value; deba@2440: supply[_t] = -_flow_value; deba@2440: valid_supply = true; deba@2440: } deba@2440: kpeter@2556: /// \brief Runs the algorithm. kpeter@2556: /// kpeter@2556: /// Runs the algorithm. kpeter@2556: /// kpeter@2556: /// \return \c true if a feasible flow can be found. kpeter@2556: bool run() { kpeter@2556: return init() && start(); kpeter@2556: } kpeter@2556: deba@2440: /// \brief Returns a const reference to the flow map. deba@2440: /// deba@2440: /// Returns a const reference to the flow map. deba@2440: /// deba@2440: /// \pre \ref run() must be called before using this function. deba@2440: const FlowMap& flowMap() const { deba@2440: return flow; deba@2440: } deba@2440: deba@2440: /// \brief Returns the total cost of the found flow. deba@2440: /// deba@2440: /// Returns the total cost of the found flow. The complexity of the deba@2440: /// function is \f$ O(e) \f$. deba@2440: /// deba@2440: /// \pre \ref run() must be called before using this function. deba@2440: Cost totalCost() const { deba@2440: Cost c = 0; deba@2440: for (EdgeIt e(graph); e != INVALID; ++e) kpeter@2556: c += flow[e] * cost[e]; deba@2440: return c; deba@2440: } deba@2440: deba@2440: protected: deba@2440: kpeter@2556: /// Initializes the algorithm. deba@2440: bool init() { deba@2440: // Checking the sum of supply values deba@2440: Supply sum = 0; deba@2440: for (NodeIt n(graph); n != INVALID; ++n) sum += supply[n]; deba@2440: if (sum != 0) return false; deba@2440: deba@2440: // Finding a feasible flow kpeter@2556: Circulation< Graph, ConstMap, CapacityEdgeMap, kpeter@2556: SupplyMap > kpeter@2556: circulation( graph, constMap((Capacity)0), capacity, kpeter@2556: supply ); kpeter@2533: circulation.flowMap(flow); kpeter@2544: return circulation.run(); deba@2440: } deba@2440: deba@2440: #ifdef LIMITED_CYCLE_CANCELING deba@2457: /// \brief Executes a cycle-canceling algorithm using kpeter@2556: /// \ref Bellman-Ford algorithm with limited iteration count. deba@2440: bool start() { deba@2440: typename BellmanFord::PredMap pred(res_graph); deba@2440: typename ResGraph::template NodeMap visited(res_graph); deba@2440: std::vector cycle; deba@2440: int node_num = countNodes(graph); deba@2440: deba@2440: #ifdef _DEBUG_ITER_ deba@2440: int cycle_num = 0; deba@2440: #endif deba@2440: int length_bound = STARTING_LIMIT; deba@2440: bool optimal = false; deba@2440: while (!optimal) { kpeter@2556: BellmanFord bf(res_graph, res_cost); kpeter@2556: bf.predMap(pred); kpeter@2556: bf.init(0); kpeter@2556: int iter_num = 0; kpeter@2556: bool cycle_found = false; kpeter@2556: while (!cycle_found) { deba@2457: #ifdef _NO_BACK_STEP_ kpeter@2556: int curr_iter_num = length_bound <= node_num ? kpeter@2556: length_bound - iter_num : node_num - iter_num; deba@2457: #else kpeter@2556: int curr_iter_num = iter_num + length_bound <= node_num ? kpeter@2556: length_bound : node_num - iter_num; deba@2457: #endif kpeter@2556: iter_num += curr_iter_num; kpeter@2556: int real_iter_num = curr_iter_num; kpeter@2556: for (int i = 0; i < curr_iter_num; ++i) { kpeter@2556: if (bf.processNextWeakRound()) { kpeter@2556: real_iter_num = i; kpeter@2556: break; kpeter@2556: } kpeter@2556: } kpeter@2556: if (real_iter_num < curr_iter_num) { kpeter@2556: optimal = true; kpeter@2556: break; kpeter@2556: } else { kpeter@2556: // Searching for node disjoint negative cycles kpeter@2556: for (ResNodeIt n(res_graph); n != INVALID; ++n) kpeter@2556: visited[n] = 0; kpeter@2556: int id = 0; kpeter@2556: for (ResNodeIt n(res_graph); n != INVALID; ++n) { kpeter@2556: if (visited[n] > 0) continue; kpeter@2556: visited[n] = ++id; kpeter@2556: ResNode u = pred[n] == INVALID ? kpeter@2556: INVALID : res_graph.source(pred[n]); kpeter@2556: while (u != INVALID && visited[u] == 0) { kpeter@2556: visited[u] = id; kpeter@2556: u = pred[u] == INVALID ? kpeter@2556: INVALID : res_graph.source(pred[u]); kpeter@2556: } kpeter@2556: if (u != INVALID && visited[u] == id) { kpeter@2556: // Finding the negative cycle kpeter@2556: cycle_found = true; kpeter@2556: cycle.clear(); kpeter@2556: ResEdge e = pred[u]; kpeter@2556: cycle.push_back(e); kpeter@2556: Capacity d = res_graph.rescap(e); kpeter@2556: while (res_graph.source(e) != u) { kpeter@2556: cycle.push_back(e = pred[res_graph.source(e)]); kpeter@2556: if (res_graph.rescap(e) < d) kpeter@2556: d = res_graph.rescap(e); kpeter@2556: } deba@2440: #ifdef _DEBUG_ITER_ kpeter@2556: ++cycle_num; deba@2440: #endif kpeter@2556: // Augmenting along the cycle kpeter@2556: for (int i = 0; i < cycle.size(); ++i) kpeter@2556: res_graph.augment(cycle[i], d); deba@2440: #ifdef _ONLY_ONE_CYCLE_ kpeter@2556: break; deba@2440: #endif kpeter@2556: } kpeter@2556: } kpeter@2556: } deba@2440: kpeter@2556: if (!cycle_found) kpeter@2556: length_bound = length_bound * ALPHA_MUL / ALPHA_DIV; kpeter@2556: } deba@2440: } deba@2440: deba@2440: #ifdef _DEBUG_ITER_ deba@2457: std::cout << "Limited cycle-canceling algorithm finished. " kpeter@2556: << "Found " << cycle_num << " negative cycles." kpeter@2556: << std::endl; deba@2440: #endif deba@2440: kpeter@2556: // Handling non-zero lower bounds deba@2440: if (lower) { kpeter@2556: for (EdgeIt e(graph); e != INVALID; ++e) kpeter@2556: flow[e] += (*lower)[e]; deba@2440: } deba@2440: return true; deba@2440: } deba@2440: #endif deba@2440: deba@2440: #ifdef MIN_MEAN_CYCLE_CANCELING deba@2457: /// \brief Executes the minimum mean cycle-canceling algorithm kpeter@2556: /// using \ref MinMeanCycle. deba@2440: bool start() { deba@2440: typedef Path ResPath; deba@2440: MinMeanCycle mmc(res_graph, res_cost); deba@2440: ResPath cycle; deba@2440: deba@2440: #ifdef _DEBUG_ITER_ deba@2440: int cycle_num = 0; deba@2440: #endif deba@2440: mmc.cyclePath(cycle).init(); deba@2440: if (mmc.findMinMean()) { kpeter@2556: while (mmc.cycleLength() < 0) { deba@2440: #ifdef _DEBUG_ITER_ kpeter@2556: ++cycle_num; deba@2440: #endif kpeter@2556: // Finding the cycle kpeter@2556: mmc.findCycle(); deba@2440: kpeter@2556: // Finding the largest flow amount that can be augmented kpeter@2556: // along the cycle kpeter@2556: Capacity delta = 0; kpeter@2556: for (typename ResPath::EdgeIt e(cycle); e != INVALID; ++e) { kpeter@2556: if (delta == 0 || res_graph.rescap(e) < delta) kpeter@2556: delta = res_graph.rescap(e); kpeter@2556: } deba@2440: kpeter@2556: // Augmenting along the cycle kpeter@2556: for (typename ResPath::EdgeIt e(cycle); e != INVALID; ++e) kpeter@2556: res_graph.augment(e, delta); deba@2440: kpeter@2556: // Finding the minimum cycle mean for the modified residual kpeter@2556: // graph kpeter@2556: mmc.reset(); kpeter@2556: if (!mmc.findMinMean()) break; kpeter@2556: } deba@2440: } deba@2440: deba@2440: #ifdef _DEBUG_ITER_ deba@2457: std::cout << "Minimum mean cycle-canceling algorithm finished. " kpeter@2556: << "Found " << cycle_num << " negative cycles." kpeter@2556: << std::endl; deba@2440: #endif deba@2440: kpeter@2556: // Handling non-zero lower bounds deba@2440: if (lower) { kpeter@2556: for (EdgeIt e(graph); e != INVALID; ++e) kpeter@2556: flow[e] += (*lower)[e]; deba@2440: } deba@2440: return true; deba@2440: } deba@2440: #endif deba@2440: deba@2440: }; //class CycleCanceling deba@2440: deba@2440: ///@} deba@2440: deba@2440: } //namespace lemon deba@2440: deba@2440: #endif //LEMON_CYCLE_CANCELING_H