gravatar
kpeter (Peter Kovacs)
kpeter@inf.elte.hu
Support infinite bounds in Circulation + fixes (#270, #266) - Support infinite capacities. - Bug fix in upperMap(). - Fixes and improvements in the documentation.
0 1 0
default
1 file changed with 32 insertions and 8 deletions:
↑ Collapse diff ↑
Show white space 24 line context
... ...
@@ -12,24 +12,25 @@
12 12
 *
13 13
 * This software is provided "AS IS" with no warranty of any kind,
14 14
 * express or implied, and with no claim as to its suitability for any
15 15
 * purpose.
16 16
 *
17 17
 */
18 18

	
19 19
#ifndef LEMON_CIRCULATION_H
20 20
#define LEMON_CIRCULATION_H
21 21

	
22 22
#include <lemon/tolerance.h>
23 23
#include <lemon/elevator.h>
24
#include <limits>
24 25

	
25 26
///\ingroup max_flow
26 27
///\file
27 28
///\brief Push-relabel algorithm for finding a feasible circulation.
28 29
///
29 30
namespace lemon {
30 31

	
31 32
  /// \brief Default traits class of Circulation class.
32 33
  ///
33 34
  /// Default traits class of Circulation class.
34 35
  ///
35 36
  /// \tparam GR Type of the digraph the algorithm runs on.
... ...
@@ -110,56 +111,60 @@
110 111
  /**
111 112
     \brief Push-relabel algorithm for the network circulation problem.
112 113

	
113 114
     \ingroup max_flow
114 115
     This class implements a push-relabel algorithm for the \e network
115 116
     \e circulation problem.
116 117
     It is to find a feasible circulation when lower and upper bounds
117 118
     are given for the flow values on the arcs and lower bounds are
118 119
     given for the difference between the outgoing and incoming flow
119 120
     at the nodes.
120 121

	
121 122
     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$
125 126
     holds for all \f$uv\in A\f$, and \f$sup: V\rightarrow\mathbf{R}\f$
126 127
     denotes the signed supply values of the nodes.
127 128
     If \f$sup(u)>0\f$, then \f$u\f$ is a supply node with \f$sup(u)\f$
128 129
     supply, if \f$sup(u)<0\f$, then \f$u\f$ is a demand node with
129 130
     \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$
131 132
     solution of the following problem.
132 133

	
133 134
     \f[ \sum_{uv\in A} f(uv) - \sum_{vu\in A} f(vu)
134 135
     \geq sup(u) \quad \forall u\in V, \f]
135 136
     \f[ lower(uv) \leq f(uv) \leq upper(uv) \quad \forall uv\in A. \f]
136 137
     
137 138
     The sum of the supply values, i.e. \f$\sum_{u\in V} sup(u)\f$ must be
138 139
     zero or negative in order to have a feasible solution (since the sum
139 140
     of the expressions on the left-hand side of the inequalities is zero).
140 141
     It means that the total demand must be greater or equal to the total
141 142
     supply and all the supplies have to be carried out from the supply nodes,
142 143
     but there could be demands that are not satisfied.
143 144
     If \f$\sum_{u\in V} sup(u)\f$ is zero, then all the supply/demand
144 145
     constraints have to be satisfied with equality, i.e. all demands
145 146
     have to be satisfied and all supplies have to be used.
146 147
     
147 148
     If you need the opposite inequalities in the supply/demand constraints
148 149
     (i.e. the total demand is less than the total supply and all the demands
149 150
     have to be satisfied while there could be supplies that are not used),
150 151
     then you could easily transform the problem to the above form by reversing
151 152
     the direction of the arcs and taking the negative of the supply values
152 153
     (e.g. using \ref ReverseDigraph and \ref NegMap adaptors).
153 154

	
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

	
154 159
     Note that this algorithm also provides a feasible solution for the
155 160
     \ref min_cost_flow "minimum cost flow problem".
156 161

	
157 162
     \tparam GR The type of the digraph the algorithm runs on.
158 163
     \tparam LM The type of the lower bound map. The default
159 164
     map type is \ref concepts::Digraph::ArcMap "GR::ArcMap<int>".
160 165
     \tparam UM The type of the upper bound (capacity) map.
161 166
     The default map type is \c LM.
162 167
     \tparam SM The type of the supply map. The default map type is
163 168
     \ref concepts::Digraph::NodeMap "GR::NodeMap<UM::Value>".
164 169
  */
165 170
#ifdef DOXYGEN
... ...
@@ -328,24 +333,31 @@
328 333
      : _g(graph), _lo(&lower), _up(&upper), _supply(&supply),
329 334
        _flow(NULL), _local_flow(false), _level(NULL), _local_level(false),
330 335
        _excess(NULL) {}
331 336

	
332 337
    /// Destructor.
333 338
    ~Circulation() {
334 339
      destroyStructures();
335 340
    }
336 341

	
337 342

	
338 343
  private:
339 344

	
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

	
340 352
    void createStructures() {
341 353
      _node_num = _el = countNodes(_g);
342 354

	
343 355
      if (!_flow) {
344 356
        _flow = Traits::createFlowMap(_g);
345 357
        _local_flow = true;
346 358
      }
347 359
      if (!_level) {
348 360
        _level = Traits::createElevator(_g, _node_num);
349 361
        _local_level = true;
350 362
      }
351 363
      if (!_excess) {
... ...
@@ -371,25 +383,25 @@
371 383

	
372 384
    /// Sets the lower bound map.
373 385
    /// \return <tt>(*this)</tt>
374 386
    Circulation& lowerMap(const LowerMap& map) {
375 387
      _lo = &map;
376 388
      return *this;
377 389
    }
378 390

	
379 391
    /// Sets the upper bound (capacity) map.
380 392

	
381 393
    /// Sets the upper bound (capacity) map.
382 394
    /// \return <tt>(*this)</tt>
383
    Circulation& upperMap(const LowerMap& map) {
395
    Circulation& upperMap(const UpperMap& map) {
384 396
      _up = &map;
385 397
      return *this;
386 398
    }
387 399

	
388 400
    /// Sets the supply map.
389 401

	
390 402
    /// Sets the supply map.
391 403
    /// \return <tt>(*this)</tt>
392 404
    Circulation& supplyMap(const SupplyMap& map) {
393 405
      _supply = &map;
394 406
      return *this;
395 407
    }
... ...
@@ -458,24 +470,27 @@
458 470
    /// If you need more control on the initial solution or the execution,
459 471
    /// first you have to call one of the \ref init() functions, then
460 472
    /// the \ref start() function.
461 473

	
462 474
    ///@{
463 475

	
464 476
    /// Initializes the internal data structures.
465 477

	
466 478
    /// Initializes the internal data structures and sets all flow values
467 479
    /// to the lower bound.
468 480
    void init()
469 481
    {
482
      LEMON_DEBUG(checkBoundMaps(),
483
        "Upper bounds must be greater or equal to the lower bounds");
484

	
470 485
      createStructures();
471 486

	
472 487
      for(NodeIt n(_g);n!=INVALID;++n) {
473 488
        (*_excess)[n] = (*_supply)[n];
474 489
      }
475 490

	
476 491
      for (ArcIt e(_g);e!=INVALID;++e) {
477 492
        _flow->set(e, (*_lo)[e]);
478 493
        (*_excess)[_g.target(e)] += (*_flow)[e];
479 494
        (*_excess)[_g.source(e)] -= (*_flow)[e];
480 495
      }
481 496

	
... ...
@@ -487,36 +502,39 @@
487 502
      _level->initFinish();
488 503
      for(NodeIt n(_g);n!=INVALID;++n)
489 504
        if(_tol.positive((*_excess)[n]))
490 505
          _level->activate(n);
491 506
    }
492 507

	
493 508
    /// Initializes the internal data structures using a greedy approach.
494 509

	
495 510
    /// Initializes the internal data structures using a greedy approach
496 511
    /// to construct the initial solution.
497 512
    void greedyInit()
498 513
    {
514
      LEMON_DEBUG(checkBoundMaps(),
515
        "Upper bounds must be greater or equal to the lower bounds");
516

	
499 517
      createStructures();
500 518

	
501 519
      for(NodeIt n(_g);n!=INVALID;++n) {
502 520
        (*_excess)[n] = (*_supply)[n];
503 521
      }
504 522

	
505 523
      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])) {
507 525
          _flow->set(e, (*_up)[e]);
508 526
          (*_excess)[_g.target(e)] += (*_up)[e];
509 527
          (*_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])) {
511 529
          _flow->set(e, (*_lo)[e]);
512 530
          (*_excess)[_g.target(e)] += (*_lo)[e];
513 531
          (*_excess)[_g.source(e)] -= (*_lo)[e];
514 532
        } else {
515 533
          Flow fc = -(*_excess)[_g.target(e)];
516 534
          _flow->set(e, fc);
517 535
          (*_excess)[_g.target(e)] = 0;
518 536
          (*_excess)[_g.source(e)] -= fc;
519 537
        }
520 538
      }
521 539

	
522 540
      _level->initStart();
... ...
@@ -739,32 +757,38 @@
739 757
        }
740 758
      return true;
741 759
    }
742 760

	
743 761
    ///Check whether or not the last execution provides a barrier
744 762

	
745 763
    ///Check whether or not the last execution provides a barrier.
746 764
    ///\sa barrier()
747 765
    ///\sa barrierMap()
748 766
    bool checkBarrier() const
749 767
    {
750 768
      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();
751 772
      for(NodeIt n(_g);n!=INVALID;++n)
752 773
        if(barrier(n))
753 774
          delta-=(*_supply)[n];
754 775
      for(ArcIt e(_g);e!=INVALID;++e)
755 776
        {
756 777
          Node s=_g.source(e);
757 778
          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
          }
759 783
          else if(barrier(t)&&!barrier(s)) delta-=(*_lo)[e];
760 784
        }
761 785
      return _tol.negative(delta);
762 786
    }
763 787

	
764 788
    /// @}
765 789

	
766 790
  };
767 791

	
768 792
}
769 793

	
770 794
#endif
0 comments (0 inline)