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 ↑
Ignore white space 192 line context
1 1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5 5
 * Copyright (C) 2003-2009
6 6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
8 8
 *
9 9
 * Permission to use, modify and distribute this software is granted
10 10
 * provided that this copyright notice appears in all copies. For
11 11
 * precise terms see the accompanying LICENSE file.
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.
36 37
  /// \tparam LM The type of the lower bound map.
37 38
  /// \tparam UM The type of the upper bound (capacity) map.
38 39
  /// \tparam SM The type of the supply map.
39 40
  template <typename GR, typename LM,
40 41
            typename UM, typename SM>
41 42
  struct CirculationDefaultTraits {
42 43

	
43 44
    /// \brief The type of the digraph the algorithm runs on.
44 45
    typedef GR Digraph;
45 46

	
46 47
    /// \brief The type of the lower bound map.
47 48
    ///
48 49
    /// The type of the map that stores the lower bounds on the arcs.
49 50
    /// It must conform to the \ref concepts::ReadMap "ReadMap" concept.
50 51
    typedef LM LowerMap;
51 52

	
52 53
    /// \brief The type of the upper bound (capacity) map.
53 54
    ///
54 55
    /// The type of the map that stores the upper bounds (capacities)
55 56
    /// on the arcs.
56 57
    /// It must conform to the \ref concepts::ReadMap "ReadMap" concept.
57 58
    typedef UM UpperMap;
58 59

	
59 60
    /// \brief The type of supply map.
60 61
    ///
61 62
    /// The type of the map that stores the signed supply values of the 
62 63
    /// nodes. 
63 64
    /// It must conform to the \ref concepts::ReadMap "ReadMap" concept.
64 65
    typedef SM SupplyMap;
65 66

	
66 67
    /// \brief The type of the flow values.
67 68
    typedef typename SupplyMap::Value Flow;
68 69

	
69 70
    /// \brief The type of the map that stores the flow values.
70 71
    ///
71 72
    /// The type of the map that stores the flow values.
72 73
    /// It must conform to the \ref concepts::ReadWriteMap "ReadWriteMap"
73 74
    /// concept.
74 75
    typedef typename Digraph::template ArcMap<Flow> FlowMap;
75 76

	
76 77
    /// \brief Instantiates a FlowMap.
77 78
    ///
78 79
    /// This function instantiates a \ref FlowMap.
79 80
    /// \param digraph The digraph for which we would like to define
80 81
    /// the flow map.
81 82
    static FlowMap* createFlowMap(const Digraph& digraph) {
82 83
      return new FlowMap(digraph);
83 84
    }
84 85

	
85 86
    /// \brief The elevator type used by the algorithm.
86 87
    ///
87 88
    /// The elevator type used by the algorithm.
88 89
    ///
89 90
    /// \sa Elevator
90 91
    /// \sa LinkedElevator
91 92
    typedef lemon::Elevator<Digraph, typename Digraph::Node> Elevator;
92 93

	
93 94
    /// \brief Instantiates an Elevator.
94 95
    ///
95 96
    /// This function instantiates an \ref Elevator.
96 97
    /// \param digraph The digraph for which we would like to define
97 98
    /// the elevator.
98 99
    /// \param max_level The maximum level of the elevator.
99 100
    static Elevator* createElevator(const Digraph& digraph, int max_level) {
100 101
      return new Elevator(digraph, max_level);
101 102
    }
102 103

	
103 104
    /// \brief The tolerance used by the algorithm
104 105
    ///
105 106
    /// The tolerance used by the algorithm to handle inexact computation.
106 107
    typedef lemon::Tolerance<Flow> Tolerance;
107 108

	
108 109
  };
109 110

	
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
166 171
template< typename GR,
167 172
          typename LM,
168 173
          typename UM,
169 174
          typename SM,
170 175
          typename TR >
171 176
#else
172 177
template< typename GR,
173 178
          typename LM = typename GR::template ArcMap<int>,
174 179
          typename UM = LM,
175 180
          typename SM = typename GR::template NodeMap<typename UM::Value>,
176 181
          typename TR = CirculationDefaultTraits<GR, LM, UM, SM> >
177 182
#endif
178 183
  class Circulation {
179 184
  public:
180 185

	
181 186
    ///The \ref CirculationDefaultTraits "traits class" of the algorithm.
182 187
    typedef TR Traits;
183 188
    ///The type of the digraph the algorithm runs on.
184 189
    typedef typename Traits::Digraph Digraph;
185 190
    ///The type of the flow values.
186 191
    typedef typename Traits::Flow Flow;
187 192

	
188 193
    ///The type of the lower bound map.
189 194
    typedef typename Traits::LowerMap LowerMap;
190 195
    ///The type of the upper bound (capacity) map.
191 196
    typedef typename Traits::UpperMap UpperMap;
192 197
    ///The type of the supply map.
193 198
    typedef typename Traits::SupplyMap SupplyMap;
194 199
    ///The type of the flow map.
195 200
    typedef typename Traits::FlowMap FlowMap;
196 201

	
197 202
    ///The type of the elevator.
198 203
    typedef typename Traits::Elevator Elevator;
199 204
    ///The type of the tolerance.
200 205
    typedef typename Traits::Tolerance Tolerance;
201 206

	
202 207
  private:
203 208

	
204 209
    TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
205 210

	
206 211
    const Digraph &_g;
207 212
    int _node_num;
208 213

	
209 214
    const LowerMap *_lo;
210 215
    const UpperMap *_up;
211 216
    const SupplyMap *_supply;
212 217

	
213 218
    FlowMap *_flow;
214 219
    bool _local_flow;
215 220

	
216 221
    Elevator* _level;
217 222
    bool _local_level;
218 223

	
219 224
    typedef typename Digraph::template NodeMap<Flow> ExcessMap;
220 225
    ExcessMap* _excess;
221 226

	
222 227
    Tolerance _tol;
223 228
    int _el;
224 229

	
225 230
  public:
226 231

	
227 232
    typedef Circulation Create;
228 233

	
229 234
    ///\name Named Template Parameters
230 235

	
231 236
    ///@{
232 237

	
233 238
    template <typename T>
234 239
    struct SetFlowMapTraits : public Traits {
235 240
      typedef T FlowMap;
236 241
      static FlowMap *createFlowMap(const Digraph&) {
237 242
        LEMON_ASSERT(false, "FlowMap is not initialized");
238 243
        return 0; // ignore warnings
239 244
      }
240 245
    };
241 246

	
242 247
    /// \brief \ref named-templ-param "Named parameter" for setting
243 248
    /// FlowMap type
244 249
    ///
245 250
    /// \ref named-templ-param "Named parameter" for setting FlowMap
246 251
    /// type.
247 252
    template <typename T>
248 253
    struct SetFlowMap
249 254
      : public Circulation<Digraph, LowerMap, UpperMap, SupplyMap,
250 255
                           SetFlowMapTraits<T> > {
251 256
      typedef Circulation<Digraph, LowerMap, UpperMap, SupplyMap,
252 257
                          SetFlowMapTraits<T> > Create;
253 258
    };
254 259

	
255 260
    template <typename T>
256 261
    struct SetElevatorTraits : public Traits {
257 262
      typedef T Elevator;
258 263
      static Elevator *createElevator(const Digraph&, int) {
259 264
        LEMON_ASSERT(false, "Elevator is not initialized");
260 265
        return 0; // ignore warnings
261 266
      }
262 267
    };
263 268

	
264 269
    /// \brief \ref named-templ-param "Named parameter" for setting
265 270
    /// Elevator type
266 271
    ///
267 272
    /// \ref named-templ-param "Named parameter" for setting Elevator
268 273
    /// type. If this named parameter is used, then an external
269 274
    /// elevator object must be passed to the algorithm using the
270 275
    /// \ref elevator(Elevator&) "elevator()" function before calling
271 276
    /// \ref run() or \ref init().
272 277
    /// \sa SetStandardElevator
273 278
    template <typename T>
274 279
    struct SetElevator
275 280
      : public Circulation<Digraph, LowerMap, UpperMap, SupplyMap,
276 281
                           SetElevatorTraits<T> > {
277 282
      typedef Circulation<Digraph, LowerMap, UpperMap, SupplyMap,
278 283
                          SetElevatorTraits<T> > Create;
279 284
    };
280 285

	
281 286
    template <typename T>
282 287
    struct SetStandardElevatorTraits : public Traits {
283 288
      typedef T Elevator;
284 289
      static Elevator *createElevator(const Digraph& digraph, int max_level) {
285 290
        return new Elevator(digraph, max_level);
286 291
      }
287 292
    };
288 293

	
289 294
    /// \brief \ref named-templ-param "Named parameter" for setting
290 295
    /// Elevator type with automatic allocation
291 296
    ///
292 297
    /// \ref named-templ-param "Named parameter" for setting Elevator
293 298
    /// type with automatic allocation.
294 299
    /// The Elevator should have standard constructor interface to be
295 300
    /// able to automatically created by the algorithm (i.e. the
296 301
    /// digraph and the maximum level should be passed to it).
297 302
    /// However an external elevator object could also be passed to the
298 303
    /// algorithm with the \ref elevator(Elevator&) "elevator()" function
299 304
    /// before calling \ref run() or \ref init().
300 305
    /// \sa SetElevator
301 306
    template <typename T>
302 307
    struct SetStandardElevator
303 308
      : public Circulation<Digraph, LowerMap, UpperMap, SupplyMap,
304 309
                       SetStandardElevatorTraits<T> > {
305 310
      typedef Circulation<Digraph, LowerMap, UpperMap, SupplyMap,
306 311
                      SetStandardElevatorTraits<T> > Create;
307 312
    };
308 313

	
309 314
    /// @}
310 315

	
311 316
  protected:
312 317

	
313 318
    Circulation() {}
314 319

	
315 320
  public:
316 321

	
317 322
    /// Constructor.
318 323

	
319 324
    /// The constructor of the class.
320 325
    ///
321 326
    /// \param graph The digraph the algorithm runs on.
322 327
    /// \param lower The lower bounds for the flow values on the arcs.
323 328
    /// \param upper The upper bounds (capacities) for the flow values 
324 329
    /// on the arcs.
325 330
    /// \param supply The signed supply values of the nodes.
326 331
    Circulation(const Digraph &graph, const LowerMap &lower,
327 332
                const UpperMap &upper, const SupplyMap &supply)
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) {
352 364
        _excess = new ExcessMap(_g);
353 365
      }
354 366
    }
355 367

	
356 368
    void destroyStructures() {
357 369
      if (_local_flow) {
358 370
        delete _flow;
359 371
      }
360 372
      if (_local_level) {
361 373
        delete _level;
362 374
      }
363 375
      if (_excess) {
364 376
        delete _excess;
365 377
      }
366 378
    }
367 379

	
368 380
  public:
369 381

	
370 382
    /// Sets the lower bound map.
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
    }
396 408

	
397 409
    /// \brief Sets the flow map.
398 410
    ///
399 411
    /// Sets the flow map.
400 412
    /// If you don't use this function before calling \ref run() or
401 413
    /// \ref init(), an instance will be allocated automatically.
402 414
    /// The destructor deallocates this automatically allocated map,
403 415
    /// of course.
404 416
    /// \return <tt>(*this)</tt>
405 417
    Circulation& flowMap(FlowMap& map) {
406 418
      if (_local_flow) {
407 419
        delete _flow;
408 420
        _local_flow = false;
409 421
      }
410 422
      _flow = &map;
411 423
      return *this;
412 424
    }
413 425

	
414 426
    /// \brief Sets the elevator used by algorithm.
415 427
    ///
416 428
    /// Sets the elevator used by algorithm.
417 429
    /// If you don't use this function before calling \ref run() or
418 430
    /// \ref init(), an instance will be allocated automatically.
419 431
    /// The destructor deallocates this automatically allocated elevator,
420 432
    /// of course.
421 433
    /// \return <tt>(*this)</tt>
422 434
    Circulation& elevator(Elevator& elevator) {
423 435
      if (_local_level) {
424 436
        delete _level;
425 437
        _local_level = false;
426 438
      }
427 439
      _level = &elevator;
428 440
      return *this;
429 441
    }
430 442

	
431 443
    /// \brief Returns a const reference to the elevator.
432 444
    ///
433 445
    /// Returns a const reference to the elevator.
434 446
    ///
435 447
    /// \pre Either \ref run() or \ref init() must be called before
436 448
    /// using this function.
437 449
    const Elevator& elevator() const {
438 450
      return *_level;
439 451
    }
440 452

	
441 453
    /// \brief Sets the tolerance used by algorithm.
442 454
    ///
443 455
    /// Sets the tolerance used by algorithm.
444 456
    Circulation& tolerance(const Tolerance& tolerance) const {
445 457
      _tol = tolerance;
446 458
      return *this;
447 459
    }
448 460

	
449 461
    /// \brief Returns a const reference to the tolerance.
450 462
    ///
451 463
    /// Returns a const reference to the tolerance.
452 464
    const Tolerance& tolerance() const {
453 465
      return tolerance;
454 466
    }
455 467

	
456 468
    /// \name Execution Control
457 469
    /// The simplest way to execute the algorithm is to call \ref run().\n
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

	
482 497
      // global relabeling tested, but in general case it provides
483 498
      // worse performance for random digraphs
484 499
      _level->initStart();
485 500
      for(NodeIt n(_g);n!=INVALID;++n)
486 501
        _level->initAddItem(n);
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();
523 541
      for(NodeIt n(_g);n!=INVALID;++n)
524 542
        _level->initAddItem(n);
525 543
      _level->initFinish();
526 544
      for(NodeIt n(_g);n!=INVALID;++n)
527 545
        if(_tol.positive((*_excess)[n]))
528 546
          _level->activate(n);
529 547
    }
530 548

	
531 549
    ///Executes the algorithm
532 550

	
533 551
    ///This function executes the algorithm.
534 552
    ///
535 553
    ///\return \c true if a feasible circulation is found.
536 554
    ///
537 555
    ///\sa barrier()
538 556
    ///\sa barrierMap()
539 557
    bool start()
540 558
    {
541 559

	
542 560
      Node act;
543 561
      Node bact=INVALID;
544 562
      Node last_activated=INVALID;
545 563
      while((act=_level->highestActive())!=INVALID) {
546 564
        int actlevel=(*_level)[act];
547 565
        int mlevel=_node_num;
548 566
        Flow exc=(*_excess)[act];
549 567

	
550 568
        for(OutArcIt e(_g,act);e!=INVALID; ++e) {
551 569
          Node v = _g.target(e);
552 570
          Flow fc=(*_up)[e]-(*_flow)[e];
553 571
          if(!_tol.positive(fc)) continue;
554 572
          if((*_level)[v]<actlevel) {
555 573
            if(!_tol.less(fc, exc)) {
556 574
              _flow->set(e, (*_flow)[e] + exc);
557 575
              (*_excess)[v] += exc;
558 576
              if(!_level->active(v) && _tol.positive((*_excess)[v]))
559 577
                _level->activate(v);
560 578
              (*_excess)[act] = 0;
561 579
              _level->deactivate(act);
562 580
              goto next_l;
563 581
            }
564 582
            else {
565 583
              _flow->set(e, (*_up)[e]);
566 584
              (*_excess)[v] += fc;
567 585
              if(!_level->active(v) && _tol.positive((*_excess)[v]))
568 586
                _level->activate(v);
569 587
              exc-=fc;
570 588
            }
571 589
          }
572 590
          else if((*_level)[v]<mlevel) mlevel=(*_level)[v];
573 591
        }
574 592
        for(InArcIt e(_g,act);e!=INVALID; ++e) {
575 593
          Node v = _g.source(e);
576 594
          Flow fc=(*_flow)[e]-(*_lo)[e];
577 595
          if(!_tol.positive(fc)) continue;
578 596
          if((*_level)[v]<actlevel) {
579 597
            if(!_tol.less(fc, exc)) {
580 598
              _flow->set(e, (*_flow)[e] - exc);
581 599
              (*_excess)[v] += exc;
582 600
              if(!_level->active(v) && _tol.positive((*_excess)[v]))
583 601
                _level->activate(v);
584 602
              (*_excess)[act] = 0;
585 603
              _level->deactivate(act);
586 604
              goto next_l;
587 605
            }
588 606
            else {
589 607
              _flow->set(e, (*_lo)[e]);
590 608
              (*_excess)[v] += fc;
591 609
              if(!_level->active(v) && _tol.positive((*_excess)[v]))
592 610
                _level->activate(v);
593 611
              exc-=fc;
594 612
            }
595 613
          }
596 614
          else if((*_level)[v]<mlevel) mlevel=(*_level)[v];
597 615
        }
598 616

	
599 617
        (*_excess)[act] = exc;
600 618
        if(!_tol.positive(exc)) _level->deactivate(act);
601 619
        else if(mlevel==_node_num) {
602 620
          _level->liftHighestActiveToTop();
603 621
          _el = _node_num;
604 622
          return false;
605 623
        }
606 624
        else {
... ...
@@ -655,116 +673,122 @@
655 673

	
656 674
    /// \brief Returns a const reference to the flow map.
657 675
    ///
658 676
    /// Returns a const reference to the arc map storing the found flow.
659 677
    ///
660 678
    /// \pre Either \ref run() or \ref init() must be called before
661 679
    /// using this function.
662 680
    const FlowMap& flowMap() const {
663 681
      return *_flow;
664 682
    }
665 683

	
666 684
    /**
667 685
       \brief Returns \c true if the given node is in a barrier.
668 686

	
669 687
       Barrier is a set \e B of nodes for which
670 688

	
671 689
       \f[ \sum_{uv\in A: u\in B} upper(uv) -
672 690
           \sum_{uv\in A: v\in B} lower(uv) < \sum_{v\in B} sup(v) \f]
673 691

	
674 692
       holds. The existence of a set with this property prooves that a
675 693
       feasible circualtion cannot exist.
676 694

	
677 695
       This function returns \c true if the given node is in the found
678 696
       barrier. If a feasible circulation is found, the function
679 697
       gives back \c false for every node.
680 698

	
681 699
       \pre Either \ref run() or \ref init() must be called before
682 700
       using this function.
683 701

	
684 702
       \sa barrierMap()
685 703
       \sa checkBarrier()
686 704
    */
687 705
    bool barrier(const Node& node) const
688 706
    {
689 707
      return (*_level)[node] >= _el;
690 708
    }
691 709

	
692 710
    /// \brief Gives back a barrier.
693 711
    ///
694 712
    /// This function sets \c bar to the characteristic vector of the
695 713
    /// found barrier. \c bar should be a \ref concepts::WriteMap "writable"
696 714
    /// node map with \c bool (or convertible) value type.
697 715
    ///
698 716
    /// If a feasible circulation is found, the function gives back an
699 717
    /// empty set, so \c bar[v] will be \c false for all nodes \c v.
700 718
    ///
701 719
    /// \note This function calls \ref barrier() for each node,
702 720
    /// so it runs in O(n) time.
703 721
    ///
704 722
    /// \pre Either \ref run() or \ref init() must be called before
705 723
    /// using this function.
706 724
    ///
707 725
    /// \sa barrier()
708 726
    /// \sa checkBarrier()
709 727
    template<class BarrierMap>
710 728
    void barrierMap(BarrierMap &bar) const
711 729
    {
712 730
      for(NodeIt n(_g);n!=INVALID;++n)
713 731
        bar.set(n, (*_level)[n] >= _el);
714 732
    }
715 733

	
716 734
    /// @}
717 735

	
718 736
    /// \name Checker Functions
719 737
    /// The feasibility of the results can be checked using
720 738
    /// these functions.\n
721 739
    /// Either \ref run() or \ref start() should be called before
722 740
    /// using them.
723 741

	
724 742
    ///@{
725 743

	
726 744
    ///Check if the found flow is a feasible circulation
727 745

	
728 746
    ///Check if the found flow is a feasible circulation,
729 747
    ///
730 748
    bool checkFlow() const {
731 749
      for(ArcIt e(_g);e!=INVALID;++e)
732 750
        if((*_flow)[e]<(*_lo)[e]||(*_flow)[e]>(*_up)[e]) return false;
733 751
      for(NodeIt n(_g);n!=INVALID;++n)
734 752
        {
735 753
          Flow dif=-(*_supply)[n];
736 754
          for(InArcIt e(_g,n);e!=INVALID;++e) dif-=(*_flow)[e];
737 755
          for(OutArcIt e(_g,n);e!=INVALID;++e) dif+=(*_flow)[e];
738 756
          if(_tol.negative(dif)) return false;
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)