COIN-OR::LEMON - Graph Library

Ticket #270: 270-266-28f58740b6f8.patch

File 270-266-28f58740b6f8.patch, 4.4 KB (added by Peter Kovacs, 15 years ago)
  • lemon/circulation.h

    # HG changeset patch
    # User Peter Kovacs <kpeter@inf.elte.hu>
    # Date 1240676759 -7200
    # Node ID 28f58740b6f8f168a125b9af4c4cf141400645d2
    # Parent  b95898314e095d3b9f994b1a1068518f25016745
    Support infinite bounds in Circulation + fixes (#270, #266)
    
     - Support infinite capacities.
     - Bug fix in upperMap().
     - Fixes and improvements in the documentation.
    
    diff --git a/lemon/circulation.h b/lemon/circulation.h
    a b  
    2121
    2222#include <lemon/tolerance.h>
    2323#include <lemon/elevator.h>
     24#include <limits>
    2425
    2526///\ingroup max_flow
    2627///\file
     
    119120     at the nodes.
    120121
    121122     The exact formulation of this problem is the following.
    122      Let \f$G=(V,A)\f$ be a digraph,
    123      \f$lower, upper: A\rightarrow\mathbf{R}^+_0\f$ denote the lower and
    124      upper bounds on the arcs, for which \f$0 \leq lower(uv) \leq upper(uv)\f$
     123     Let \f$G=(V,A)\f$ be a digraph, \f$lower: A\rightarrow\mathbf{R}\f$
     124     \f$upper: A\rightarrow\mathbf{R}\cup\{\infty\}\f$ denote the lower and
     125     upper bounds on the arcs, for which \f$lower(uv) \leq upper(uv)\f$
    125126     holds for all \f$uv\in A\f$, and \f$sup: V\rightarrow\mathbf{R}\f$
    126127     denotes the signed supply values of the nodes.
    127128     If \f$sup(u)>0\f$, then \f$u\f$ is a supply node with \f$sup(u)\f$
    128129     supply, if \f$sup(u)<0\f$, then \f$u\f$ is a demand node with
    129130     \f$-sup(u)\f$ demand.
    130      A feasible circulation is an \f$f: A\rightarrow\mathbf{R}^+_0\f$
     131     A feasible circulation is an \f$f: A\rightarrow\mathbf{R}\f$
    131132     solution of the following problem.
    132133
    133134     \f[ \sum_{uv\in A} f(uv) - \sum_{vu\in A} f(vu)
     
    151152     the direction of the arcs and taking the negative of the supply values
    152153     (e.g. using \ref ReverseDigraph and \ref NegMap adaptors).
    153154
     155     This algorithm either calculates a feasible circulation, or provides
     156     a \ref barrier() "barrier", which prooves that a feasible soultion
     157     cannot exist.
     158
    154159     Note that this algorithm also provides a feasible solution for the
    155160     \ref min_cost_flow "minimum cost flow problem".
    156161
     
    337342
    338343  private:
    339344
     345    bool checkBoundMaps() {
     346      for (ArcIt e(_g);e!=INVALID;++e) {
     347        if (_tol.less((*_up)[e], (*_lo)[e])) return false;
     348      }
     349      return true;
     350    }
     351
    340352    void createStructures() {
    341353      _node_num = _el = countNodes(_g);
    342354
     
    380392
    381393    /// Sets the upper bound (capacity) map.
    382394    /// \return <tt>(*this)</tt>
    383     Circulation& upperMap(const LowerMap& map) {
     395    Circulation& upperMap(const UpperMap& map) {
    384396      _up = &map;
    385397      return *this;
    386398    }
     
    467479    /// to the lower bound.
    468480    void init()
    469481    {
     482      LEMON_DEBUG(checkBoundMaps(),
     483        "Upper bounds must be greater or equal to the lower bounds");
     484
    470485      createStructures();
    471486
    472487      for(NodeIt n(_g);n!=INVALID;++n) {
     
    496511    /// to construct the initial solution.
    497512    void greedyInit()
    498513    {
     514      LEMON_DEBUG(checkBoundMaps(),
     515        "Upper bounds must be greater or equal to the lower bounds");
     516
    499517      createStructures();
    500518
    501519      for(NodeIt n(_g);n!=INVALID;++n) {
     
    503521      }
    504522
    505523      for (ArcIt e(_g);e!=INVALID;++e) {
    506         if (!_tol.positive((*_excess)[_g.target(e)] + (*_up)[e])) {
     524        if (!_tol.less(-(*_excess)[_g.target(e)], (*_up)[e])) {
    507525          _flow->set(e, (*_up)[e]);
    508526          (*_excess)[_g.target(e)] += (*_up)[e];
    509527          (*_excess)[_g.source(e)] -= (*_up)[e];
    510         } else if (_tol.positive((*_excess)[_g.target(e)] + (*_lo)[e])) {
     528        } else if (_tol.less(-(*_excess)[_g.target(e)], (*_lo)[e])) {
    511529          _flow->set(e, (*_lo)[e]);
    512530          (*_excess)[_g.target(e)] += (*_lo)[e];
    513531          (*_excess)[_g.source(e)] -= (*_lo)[e];
     
    748766    bool checkBarrier() const
    749767    {
    750768      Flow delta=0;
     769      Flow inf_cap = std::numeric_limits<Flow>::has_infinity ?
     770        std::numeric_limits<Flow>::infinity() :
     771        std::numeric_limits<Flow>::max();
    751772      for(NodeIt n(_g);n!=INVALID;++n)
    752773        if(barrier(n))
    753774          delta-=(*_supply)[n];
     
    755776        {
    756777          Node s=_g.source(e);
    757778          Node t=_g.target(e);
    758           if(barrier(s)&&!barrier(t)) delta+=(*_up)[e];
     779          if(barrier(s)&&!barrier(t)) {
     780            if (_tol.less(inf_cap - (*_up)[e], delta)) return false;
     781            delta+=(*_up)[e];
     782          }
    759783          else if(barrier(t)&&!barrier(s)) delta-=(*_lo)[e];
    760784        }
    761785      return _tol.negative(delta);