COIN-OR::LEMON - Graph Library

Changeset 2581:054566ac0934 in lemon-0.x for lemon/cost_scaling.h


Ignore:
Timestamp:
02/28/08 03:54:27 (16 years ago)
Author:
Peter Kovacs
Branch:
default
Phase:
public
Convert:
svn:c9d7d8f5-90d6-0310-b91f-818b3a526b0e/lemon/trunk@3463
Message:

Query improvements in the min cost flow algorithms.

  • External flow and potential maps can be used.
  • New query functions: flow() and potential().
  • CycleCanceling? also provides dual solution (node potentials).
  • Doc improvements.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • lemon/cost_scaling.h

    r2577 r2581  
    5555  /// - Edge capacities and costs should be \e non-negative \e integers.
    5656  /// - Supply values should be \e signed \e integers.
    57   /// - \c LowerMap::Value must be convertible to \c CapacityMap::Value.
    58   /// - \c CapacityMap::Value and \c SupplyMap::Value must be
    59   ///   convertible to each other.
    60   /// - All value types must be convertible to \c CostMap::Value, which
    61   ///   must be signed type.
     57  /// - The value types of the maps should be convertible to each other.
     58  /// - \c CostMap::Value must be signed type.
    6259  ///
    6360  /// \note Edge costs are multiplied with the number of nodes during
     
    9895
    9996    /// The type of the flow map.
    100     typedef CapacityEdgeMap FlowMap;
     97    typedef typename Graph::template EdgeMap<Capacity> FlowMap;
    10198    /// The type of the potential map.
    10299    typedef typename Graph::template NodeMap<LCost> PotentialMap;
     
    108105    /// \ref ResidualCostMap is a map adaptor class for handling
    109106    /// residual edge costs.
    110     class ResidualCostMap : public MapBase<ResEdge, LCost>
     107    template <typename Map>
     108    class ResidualCostMap : public MapBase<ResEdge, typename Map::Value>
    111109    {
    112110    private:
    113111
    114       const LargeCostMap &_cost_map;
     112      const Map &_cost_map;
    115113
    116114    public:
    117115
    118116      ///\e
    119       ResidualCostMap(const LargeCostMap &cost_map) :
     117      ResidualCostMap(const Map &cost_map) :
    120118        _cost_map(cost_map) {}
    121119
    122120      ///\e
    123       LCost operator[](const ResEdge &e) const {
     121      typename Map::Value operator[](const ResEdge &e) const {
    124122        return ResGraph::forward(e) ?  _cost_map[e] : -_cost_map[e];
    125123      }
     
    161159
    162160    // Paramters for heuristics
    163     static const int BF_HEURISTIC_EPSILON_BOUND    = 5000;
    164     static const int BF_HEURISTIC_BOUND_FACTOR = 3;
     161    static const int BF_HEURISTIC_EPSILON_BOUND = 5000;
     162    static const int BF_HEURISTIC_BOUND_FACTOR  = 3;
    165163
    166164  private:
     
    181179
    182180    // Edge map of the current flow
    183     FlowMap _flow;
     181    FlowMap *_flow;
     182    bool _local_flow;
    184183    // Node map of the current potentials
    185     PotentialMap _potential;
     184    PotentialMap *_potential;
     185    bool _local_potential;
    186186
    187187    // The residual graph
    188     ResGraph _res_graph;
     188    ResGraph *_res_graph;
    189189    // The residual cost map
    190     ResidualCostMap _res_cost;
     190    ResidualCostMap<LargeCostMap> _res_cost;
    191191    // The reduced cost map
    192     ReducedCostMap _red_cost;
     192    ReducedCostMap *_red_cost;
    193193    // The excess map
    194194    SupplyNodeMap _excess;
     
    198198  public:
    199199
    200     /// \brief General constructor of the class (with lower bounds).
    201     ///
    202     /// General constructor of the class (with lower bounds).
     200    /// \brief General constructor (with lower bounds).
     201    ///
     202    /// General constructor (with lower bounds).
    203203    ///
    204204    /// \param graph The directed graph the algorithm runs on.
     
    213213                 const SupplyMap &supply ) :
    214214      _graph(graph), _lower(&lower), _capacity(graph), _orig_cost(cost),
    215       _cost(graph), _supply(graph), _flow(graph, 0), _potential(graph, 0),
    216       _res_graph(graph, _capacity, _flow), _res_cost(_cost),
    217       _red_cost(graph, _cost, _potential), _excess(graph, 0)
     215      _cost(graph), _supply(graph), _flow(0), _local_flow(false),
     216      _potential(0), _local_potential(false), _res_cost(_cost),
     217      _excess(graph, 0)
    218218    {
    219219      // Removing non-zero lower bounds
     
    232232    }
    233233
    234     /// \brief General constructor of the class (without lower bounds).
    235     ///
    236     /// General constructor of the class (without lower bounds).
     234    /// \brief General constructor (without lower bounds).
     235    ///
     236    /// General constructor (without lower bounds).
    237237    ///
    238238    /// \param graph The directed graph the algorithm runs on.
     
    245245                 const SupplyMap &supply ) :
    246246      _graph(graph), _lower(NULL), _capacity(capacity), _orig_cost(cost),
    247       _cost(graph), _supply(supply), _flow(graph, 0), _potential(graph, 0),
    248       _res_graph(graph, _capacity, _flow), _res_cost(_cost),
    249       _red_cost(graph, _cost, _potential), _excess(graph, 0)
     247      _cost(graph), _supply(supply), _flow(0), _local_flow(false),
     248      _potential(0), _local_potential(false), _res_cost(_cost),
     249      _excess(graph, 0)
    250250    {
    251251      // Checking the sum of supply values
     
    255255    }
    256256
    257     /// \brief Simple constructor of the class (with lower bounds).
    258     ///
    259     /// Simple constructor of the class (with lower bounds).
     257    /// \brief Simple constructor (with lower bounds).
     258    ///
     259    /// Simple constructor (with lower bounds).
    260260    ///
    261261    /// \param graph The directed graph the algorithm runs on.
     
    274274                 Supply flow_value ) :
    275275      _graph(graph), _lower(&lower), _capacity(graph), _orig_cost(cost),
    276       _cost(graph), _supply(graph), _flow(graph, 0), _potential(graph, 0),
    277       _res_graph(graph, _capacity, _flow), _res_cost(_cost),
    278       _red_cost(graph, _cost, _potential), _excess(graph, 0)
     276      _cost(graph), _supply(graph), _flow(0), _local_flow(false),
     277      _potential(0), _local_potential(false), _res_cost(_cost),
     278      _excess(graph, 0)
    279279    {
    280280      // Removing nonzero lower bounds
     
    293293    }
    294294
    295     /// \brief Simple constructor of the class (without lower bounds).
    296     ///
    297     /// Simple constructor of the class (without lower bounds).
     295    /// \brief Simple constructor (without lower bounds).
     296    ///
     297    /// Simple constructor (without lower bounds).
    298298    ///
    299299    /// \param graph The directed graph the algorithm runs on.
     
    310310                 Supply flow_value ) :
    311311      _graph(graph), _lower(NULL), _capacity(capacity), _orig_cost(cost),
    312       _cost(graph), _supply(graph, 0), _flow(graph, 0), _potential(graph, 0),
    313       _res_graph(graph, _capacity, _flow), _res_cost(_cost),
    314       _red_cost(graph, _cost, _potential), _excess(graph, 0)
     312      _cost(graph), _supply(graph, 0), _flow(0), _local_flow(false),
     313      _potential(0), _local_potential(false), _res_cost(_cost),
     314      _excess(graph, 0)
    315315    {
    316316      _supply[s] =  flow_value;
     
    319319    }
    320320
     321    /// Destructor.
     322    ~CostScaling() {
     323      if (_local_flow) delete _flow;
     324      if (_local_potential) delete _potential;
     325      delete _res_graph;
     326      delete _red_cost;
     327    }
     328
     329    /// \brief Sets the flow map.
     330    ///
     331    /// Sets the flow map.
     332    ///
     333    /// \return \c (*this)
     334    CostScaling& flowMap(FlowMap &map) {
     335      if (_local_flow) {
     336        delete _flow;
     337        _local_flow = false;
     338      }
     339      _flow = &map;
     340      return *this;
     341    }
     342
     343    /// \brief Sets the potential map.
     344    ///
     345    /// Sets the potential map.
     346    ///
     347    /// \return \c (*this)
     348    CostScaling& potentialMap(PotentialMap &map) {
     349      if (_local_potential) {
     350        delete _potential;
     351        _local_potential = false;
     352      }
     353      _potential = &map;
     354      return *this;
     355    }
     356
     357    /// \name Execution control
     358    /// The only way to execute the algorithm is to call the run()
     359    /// function.
     360
     361    /// @{
     362
    321363    /// \brief Runs the algorithm.
    322364    ///
     
    325367    /// \return \c true if a feasible flow can be found.
    326368    bool run() {
    327       init() && start();
    328     }
     369      return init() && start();
     370    }
     371
     372    /// @}
     373
     374    /// \name Query Functions
     375    /// The result of the algorithm can be obtained using these
     376    /// functions.
     377    /// \n run() must be called before using them.
     378
     379    /// @{
    329380
    330381    /// \brief Returns a const reference to the edge map storing the
     
    335386    /// \pre \ref run() must be called before using this function.
    336387    const FlowMap& flowMap() const {
    337       return _flow;
     388      return *_flow;
    338389    }
    339390
     
    346397    /// \pre \ref run() must be called before using this function.
    347398    const PotentialMap& potentialMap() const {
    348       return _potential;
     399      return *_potential;
     400    }
     401
     402    /// \brief Returns the flow on the edge.
     403    ///
     404    /// Returns the flow on the edge.
     405    ///
     406    /// \pre \ref run() must be called before using this function.
     407    Capacity flow(const Edge& edge) const {
     408      return (*_flow)[edge];
     409    }
     410
     411    /// \brief Returns the potential of the node.
     412    ///
     413    /// Returns the potential of the node.
     414    ///
     415    /// \pre \ref run() must be called before using this function.
     416    Cost potential(const Node& node) const {
     417      return (*_potential)[node];
    349418    }
    350419
     
    358427      Cost c = 0;
    359428      for (EdgeIt e(_graph); e != INVALID; ++e)
    360         c += _flow[e] * _orig_cost[e];
     429        c += (*_flow)[e] * _orig_cost[e];
    361430      return c;
    362431    }
     432
     433    /// @}
    363434
    364435  private:
     
    367438    bool init() {
    368439      if (!_valid_supply) return false;
     440
     441      // Initializing flow and potential maps
     442      if (!_flow) {
     443        _flow = new FlowMap(_graph);
     444        _local_flow = true;
     445      }
     446      if (!_potential) {
     447        _potential = new PotentialMap(_graph);
     448        _local_potential = true;
     449      }
     450
     451      _red_cost = new ReducedCostMap(_graph, _cost, *_potential);
     452      _res_graph = new ResGraph(_graph, _capacity, *_flow);
    369453
    370454      // Initializing the scaled cost map and the epsilon parameter
     
    380464      Circulation< Graph, ConstMap<Edge, Capacity>, CapacityEdgeMap,
    381465                   SupplyMap >
    382         circulation( _graph, constMap<Edge>((Capacity)0), _capacity,
     466        circulation( _graph, constMap<Edge>(Capacity(0)), _capacity,
    383467                     _supply );
    384       return circulation.flowMap(_flow).run();
     468      return circulation.flowMap(*_flow).run();
    385469    }
    386470
     
    398482        // algorithm
    399483        if (_epsilon <= BF_HEURISTIC_EPSILON_BOUND) {
    400           typedef ShiftMap<ResidualCostMap> ShiftCostMap;
     484          typedef ShiftMap< ResidualCostMap<LargeCostMap> > ShiftCostMap;
    401485          ShiftCostMap shift_cost(_res_cost, _epsilon);
    402           BellmanFord<ResGraph, ShiftCostMap> bf(_res_graph, shift_cost);
     486          BellmanFord<ResGraph, ShiftCostMap> bf(*_res_graph, shift_cost);
    403487          bf.init(0);
    404488          bool done = false;
     
    408492          if (done) {
    409493            for (NodeIt n(_graph); n != INVALID; ++n)
    410               _potential[n] = bf.dist(n);
     494              (*_potential)[n] = bf.dist(n);
    411495            continue;
    412496          }
     
    416500        Capacity delta;
    417501        for (EdgeIt e(_graph); e != INVALID; ++e) {
    418           if (_capacity[e] - _flow[e] > 0 && _red_cost[e] < 0) {
    419             delta = _capacity[e] - _flow[e];
     502          if (_capacity[e] - (*_flow)[e] > 0 && (*_red_cost)[e] < 0) {
     503            delta = _capacity[e] - (*_flow)[e];
    420504            _excess[_graph.source(e)] -= delta;
    421505            _excess[_graph.target(e)] += delta;
    422             _flow[e] = _capacity[e];
     506            (*_flow)[e] = _capacity[e];
    423507          }
    424           if (_flow[e] > 0 && -_red_cost[e] < 0) {
    425             _excess[_graph.target(e)] -= _flow[e];
    426             _excess[_graph.source(e)] += _flow[e];
    427             _flow[e] = 0;
     508          if ((*_flow)[e] > 0 && -(*_red_cost)[e] < 0) {
     509            _excess[_graph.target(e)] -= (*_flow)[e];
     510            _excess[_graph.source(e)] += (*_flow)[e];
     511            (*_flow)[e] = 0;
    428512          }
    429513        }
     
    441525          if (_excess[n] > 0) {
    442526            for (OutEdgeIt e(_graph, n); e != INVALID; ++e) {
    443               if (_capacity[e] - _flow[e] > 0 && _red_cost[e] < 0) {
    444                 delta = _capacity[e] - _flow[e] <= _excess[n] ?
    445                         _capacity[e] - _flow[e] : _excess[n];
     527              if (_capacity[e] - (*_flow)[e] > 0 && (*_red_cost)[e] < 0) {
     528                delta = _capacity[e] - (*_flow)[e] <= _excess[n] ?
     529                        _capacity[e] - (*_flow)[e] : _excess[n];
    446530                t = _graph.target(e);
    447531
     
    449533                Capacity ahead = -_excess[t];
    450534                for (OutEdgeIt oe(_graph, t); oe != INVALID; ++oe) {
    451                   if (_capacity[oe] - _flow[oe] > 0 && _red_cost[oe] < 0)
    452                     ahead += _capacity[oe] - _flow[oe];
     535                  if (_capacity[oe] - (*_flow)[oe] > 0 && (*_red_cost)[oe] < 0)
     536                    ahead += _capacity[oe] - (*_flow)[oe];
    453537                }
    454538                for (InEdgeIt ie(_graph, t); ie != INVALID; ++ie) {
    455                   if (_flow[ie] > 0 && -_red_cost[ie] < 0)
    456                     ahead += _flow[ie];
     539                  if ((*_flow)[ie] > 0 && -(*_red_cost)[ie] < 0)
     540                    ahead += (*_flow)[ie];
    457541                }
    458542                if (ahead < 0) ahead = 0;
     
    460544                // Pushing flow along the edge
    461545                if (ahead < delta) {
    462                   _flow[e] += ahead;
     546                  (*_flow)[e] += ahead;
    463547                  _excess[n] -= ahead;
    464548                  _excess[t] += ahead;
     
    468552                  break;
    469553                } else {
    470                   _flow[e] += delta;
     554                  (*_flow)[e] += delta;
    471555                  _excess[n] -= delta;
    472556                  _excess[t] += delta;
     
    482566          if (_excess[n] > 0) {
    483567            for (InEdgeIt e(_graph, n); e != INVALID; ++e) {
    484               if (_flow[e] > 0 && -_red_cost[e] < 0) {
    485                 delta = _flow[e] <= _excess[n] ? _flow[e] : _excess[n];
     568              if ((*_flow)[e] > 0 && -(*_red_cost)[e] < 0) {
     569                delta = (*_flow)[e] <= _excess[n] ? (*_flow)[e] : _excess[n];
    486570                t = _graph.source(e);
    487571
     
    489573                Capacity ahead = -_excess[t];
    490574                for (OutEdgeIt oe(_graph, t); oe != INVALID; ++oe) {
    491                   if (_capacity[oe] - _flow[oe] > 0 && _red_cost[oe] < 0)
    492                     ahead += _capacity[oe] - _flow[oe];
     575                  if (_capacity[oe] - (*_flow)[oe] > 0 && (*_red_cost)[oe] < 0)
     576                    ahead += _capacity[oe] - (*_flow)[oe];
    493577                }
    494578                for (InEdgeIt ie(_graph, t); ie != INVALID; ++ie) {
    495                   if (_flow[ie] > 0 && -_red_cost[ie] < 0)
    496                     ahead += _flow[ie];
     579                  if ((*_flow)[ie] > 0 && -(*_red_cost)[ie] < 0)
     580                    ahead += (*_flow)[ie];
    497581                }
    498582                if (ahead < 0) ahead = 0;
     
    500584                // Pushing flow along the edge
    501585                if (ahead < delta) {
    502                   _flow[e] -= ahead;
     586                  (*_flow)[e] -= ahead;
    503587                  _excess[n] -= ahead;
    504588                  _excess[t] += ahead;
     
    508592                  break;
    509593                } else {
    510                   _flow[e] -= delta;
     594                  (*_flow)[e] -= delta;
    511595                  _excess[n] -= delta;
    512596                  _excess[t] += delta;
     
    524608            LCost min_red_cost = std::numeric_limits<LCost>::max();
    525609            for (OutEdgeIt oe(_graph, n); oe != INVALID; ++oe) {
    526               if ( _capacity[oe] - _flow[oe] > 0 &&
    527                    _red_cost[oe] < min_red_cost )
    528                 min_red_cost = _red_cost[oe];
     610              if ( _capacity[oe] - (*_flow)[oe] > 0 &&
     611                   (*_red_cost)[oe] < min_red_cost )
     612                min_red_cost = (*_red_cost)[oe];
    529613            }
    530614            for (InEdgeIt ie(_graph, n); ie != INVALID; ++ie) {
    531               if (_flow[ie] > 0 && -_red_cost[ie] < min_red_cost)
    532                 min_red_cost = -_red_cost[ie];
     615              if ((*_flow)[ie] > 0 && -(*_red_cost)[ie] < min_red_cost)
     616                min_red_cost = -(*_red_cost)[ie];
    533617            }
    534             _potential[n] -= min_red_cost + _epsilon;
     618            (*_potential)[n] -= min_red_cost + _epsilon;
    535619            hyper[n] = false;
    536620          }
     
    545629      }
    546630
     631      // Computing node potentials for the original costs
     632      ResidualCostMap<CostMap> res_cost(_orig_cost);
     633      BellmanFord< ResGraph, ResidualCostMap<CostMap> >
     634        bf(*_res_graph, res_cost);
     635      bf.init(0); bf.start();
     636      for (NodeIt n(_graph); n != INVALID; ++n)
     637        (*_potential)[n] = bf.dist(n);
     638
    547639      // Handling non-zero lower bounds
    548640      if (_lower) {
    549641        for (EdgeIt e(_graph); e != INVALID; ++e)
    550           _flow[e] += (*_lower)[e];
     642          (*_flow)[e] += (*_lower)[e];
    551643      }
    552644      return true;
Note: See TracChangeset for help on using the changeset viewer.