gravatar
kpeter (Peter Kovacs)
kpeter@inf.elte.hu
Test file + doc improvements (#307)
0 4 0
default
4 files changed with 21 insertions and 7 deletions:
↑ Collapse diff ↑
Show white space 64 line context
... ...
@@ -421,75 +421,77 @@
421 421
      }
422 422
      _flow = ↦
423 423
      return *this;
424 424
    }
425 425

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

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

	
453
    /// \brief Sets the tolerance used by algorithm.
453
    /// \brief Sets the tolerance used by the algorithm.
454 454
    ///
455
    /// Sets the tolerance used by algorithm.
455
    /// Sets the tolerance object used by the algorithm.
456
    /// \return <tt>(*this)</tt>
456 457
    Circulation& tolerance(const Tolerance& tolerance) {
457 458
      _tol = tolerance;
458 459
      return *this;
459 460
    }
460 461

	
461 462
    /// \brief Returns a const reference to the tolerance.
462 463
    ///
463
    /// Returns a const reference to the tolerance.
464
    /// Returns a const reference to the tolerance object used by
465
    /// the algorithm.
464 466
    const Tolerance& tolerance() const {
465 467
      return _tol;
466 468
    }
467 469

	
468 470
    /// \name Execution Control
469 471
    /// The simplest way to execute the algorithm is to call \ref run().\n
470 472
    /// If you need more control on the initial solution or the execution,
471 473
    /// first you have to call one of the \ref init() functions, then
472 474
    /// the \ref start() function.
473 475

	
474 476
    ///@{
475 477

	
476 478
    /// Initializes the internal data structures.
477 479

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

	
485 487
      createStructures();
486 488

	
487 489
      for(NodeIt n(_g);n!=INVALID;++n) {
488 490
        (*_excess)[n] = (*_supply)[n];
489 491
      }
490 492

	
491 493
      for (ArcIt e(_g);e!=INVALID;++e) {
492 494
        _flow->set(e, (*_lo)[e]);
493 495
        (*_excess)[_g.target(e)] += (*_flow)[e];
494 496
        (*_excess)[_g.source(e)] -= (*_flow)[e];
495 497
      }
Show white space 64 line context
... ...
@@ -68,65 +68,65 @@
68 68
    /// The elevator type used by Preflow algorithm.
69 69
    ///
70 70
    /// \sa Elevator
71 71
    /// \sa LinkedElevator
72 72
    typedef LinkedElevator<Digraph, typename Digraph::Node> Elevator;
73 73

	
74 74
    /// \brief Instantiates an Elevator.
75 75
    ///
76 76
    /// This function instantiates an \ref Elevator.
77 77
    /// \param digraph The digraph for which we would like to define
78 78
    /// the elevator.
79 79
    /// \param max_level The maximum level of the elevator.
80 80
    static Elevator* createElevator(const Digraph& digraph, int max_level) {
81 81
      return new Elevator(digraph, max_level);
82 82
    }
83 83

	
84 84
    /// \brief The tolerance used by the algorithm
85 85
    ///
86 86
    /// The tolerance used by the algorithm to handle inexact computation.
87 87
    typedef lemon::Tolerance<Value> Tolerance;
88 88

	
89 89
  };
90 90

	
91 91

	
92 92
  /// \ingroup max_flow
93 93
  ///
94 94
  /// \brief %Preflow algorithm class.
95 95
  ///
96 96
  /// This class provides an implementation of Goldberg-Tarjan's \e preflow
97 97
  /// \e push-relabel algorithm producing a \ref max_flow
98 98
  /// "flow of maximum value" in a digraph.
99 99
  /// The preflow algorithms are the fastest known maximum
100
  /// flow algorithms. The current implementation use a mixture of the
100
  /// flow algorithms. The current implementation uses a mixture of the
101 101
  /// \e "highest label" and the \e "bound decrease" heuristics.
102 102
  /// The worst case time complexity of the algorithm is \f$O(n^2\sqrt{e})\f$.
103 103
  ///
104 104
  /// The algorithm consists of two phases. After the first phase
105 105
  /// the maximum flow value and the minimum cut is obtained. The
106 106
  /// second phase constructs a feasible maximum flow on each arc.
107 107
  ///
108 108
  /// \tparam GR The type of the digraph the algorithm runs on.
109 109
  /// \tparam CAP The type of the capacity map. The default map
110 110
  /// type is \ref concepts::Digraph::ArcMap "GR::ArcMap<int>".
111 111
#ifdef DOXYGEN
112 112
  template <typename GR, typename CAP, typename TR>
113 113
#else
114 114
  template <typename GR,
115 115
            typename CAP = typename GR::template ArcMap<int>,
116 116
            typename TR = PreflowDefaultTraits<GR, CAP> >
117 117
#endif
118 118
  class Preflow {
119 119
  public:
120 120

	
121 121
    ///The \ref PreflowDefaultTraits "traits class" of the algorithm.
122 122
    typedef TR Traits;
123 123
    ///The type of the digraph the algorithm runs on.
124 124
    typedef typename Traits::Digraph Digraph;
125 125
    ///The type of the capacity map.
126 126
    typedef typename Traits::CapacityMap CapacityMap;
127 127
    ///The type of the flow values.
128 128
    typedef typename Traits::Value Value;
129 129

	
130 130
    ///The type of the flow map.
131 131
    typedef typename Traits::FlowMap FlowMap;
132 132
    ///The type of the elevator.
... ...
@@ -342,75 +342,77 @@
342 342
    Preflow& target(const Node& node) {
343 343
      _target = node;
344 344
      return *this;
345 345
    }
346 346

	
347 347
    /// \brief Sets the elevator used by algorithm.
348 348
    ///
349 349
    /// Sets the elevator used by algorithm.
350 350
    /// If you don't use this function before calling \ref run() or
351 351
    /// \ref init(), an instance will be allocated automatically.
352 352
    /// The destructor deallocates this automatically allocated elevator,
353 353
    /// of course.
354 354
    /// \return <tt>(*this)</tt>
355 355
    Preflow& elevator(Elevator& elevator) {
356 356
      if (_local_level) {
357 357
        delete _level;
358 358
        _local_level = false;
359 359
      }
360 360
      _level = &elevator;
361 361
      return *this;
362 362
    }
363 363

	
364 364
    /// \brief Returns a const reference to the elevator.
365 365
    ///
366 366
    /// Returns a const reference to the elevator.
367 367
    ///
368 368
    /// \pre Either \ref run() or \ref init() must be called before
369 369
    /// using this function.
370 370
    const Elevator& elevator() const {
371 371
      return *_level;
372 372
    }
373 373

	
374
    /// \brief Sets the tolerance used by algorithm.
374
    /// \brief Sets the tolerance used by the algorithm.
375 375
    ///
376
    /// Sets the tolerance used by algorithm.
376
    /// Sets the tolerance object used by the algorithm.
377
    /// \return <tt>(*this)</tt>
377 378
    Preflow& tolerance(const Tolerance& tolerance) {
378 379
      _tolerance = tolerance;
379 380
      return *this;
380 381
    }
381 382

	
382 383
    /// \brief Returns a const reference to the tolerance.
383 384
    ///
384
    /// Returns a const reference to the tolerance.
385
    /// Returns a const reference to the tolerance object used by
386
    /// the algorithm.
385 387
    const Tolerance& tolerance() const {
386 388
      return _tolerance;
387 389
    }
388 390

	
389 391
    /// \name Execution Control
390 392
    /// The simplest way to execute the preflow algorithm is to use
391 393
    /// \ref run() or \ref runMinCut().\n
392 394
    /// If you need more control on the initial solution or the execution,
393 395
    /// first you have to call one of the \ref init() functions, then
394 396
    /// \ref startFirstPhase() and if you need it \ref startSecondPhase().
395 397

	
396 398
    ///@{
397 399

	
398 400
    /// \brief Initializes the internal data structures.
399 401
    ///
400 402
    /// Initializes the internal data structures and sets the initial
401 403
    /// flow to zero on each arc.
402 404
    void init() {
403 405
      createStructures();
404 406

	
405 407
      _phase = true;
406 408
      for (NodeIt n(_graph); n != INVALID; ++n) {
407 409
        (*_excess)[n] = 0;
408 410
      }
409 411

	
410 412
      for (ArcIt e(_graph); e != INVALID; ++e) {
411 413
        _flow->set(e, 0);
412 414
      }
413 415

	
414 416
      typename Digraph::template NodeMap<bool> reached(_graph, false);
415 417

	
416 418
      _level->initStart();
Show white space 64 line context
... ...
@@ -59,64 +59,69 @@
59 59
  typedef concepts::ReadMap<Arc,VType> CapMap;
60 60
  typedef concepts::ReadMap<Node,VType> SupplyMap;
61 61
  typedef concepts::ReadWriteMap<Arc,VType> FlowMap;
62 62
  typedef concepts::WriteMap<Node,bool> BarrierMap;
63 63

	
64 64
  typedef Elevator<Digraph, Digraph::Node> Elev;
65 65
  typedef LinkedElevator<Digraph, Digraph::Node> LinkedElev;
66 66

	
67 67
  Digraph g;
68 68
  Node n;
69 69
  Arc a;
70 70
  CapMap lcap, ucap;
71 71
  SupplyMap supply;
72 72
  FlowMap flow;
73 73
  BarrierMap bar;
74 74
  VType v;
75 75
  bool b;
76 76

	
77 77
  typedef Circulation<Digraph, CapMap, CapMap, SupplyMap>
78 78
            ::SetFlowMap<FlowMap>
79 79
            ::SetElevator<Elev>
80 80
            ::SetStandardElevator<LinkedElev>
81 81
            ::Create CirculationType;
82 82
  CirculationType circ_test(g, lcap, ucap, supply);
83 83
  const CirculationType& const_circ_test = circ_test;
84 84
   
85 85
  circ_test
86 86
    .lowerMap(lcap)
87 87
    .upperMap(ucap)
88 88
    .supplyMap(supply)
89 89
    .flowMap(flow);
90 90

	
91
  const CirculationType::Elevator& elev = const_circ_test.elevator();
92
  circ_test.elevator(const_cast<CirculationType::Elevator&>(elev));
93
  CirculationType::Tolerance tol = const_circ_test.tolerance();
94
  circ_test.tolerance(tol);
95

	
91 96
  circ_test.init();
92 97
  circ_test.greedyInit();
93 98
  circ_test.start();
94 99
  circ_test.run();
95 100

	
96 101
  v = const_circ_test.flow(a);
97 102
  const FlowMap& fm = const_circ_test.flowMap();
98 103
  b = const_circ_test.barrier(n);
99 104
  const_circ_test.barrierMap(bar);
100 105
  
101 106
  ignore_unused_variable_warning(fm);
102 107
}
103 108

	
104 109
template <class G, class LM, class UM, class DM>
105 110
void checkCirculation(const G& g, const LM& lm, const UM& um,
106 111
                      const DM& dm, bool find)
107 112
{
108 113
  Circulation<G, LM, UM, DM> circ(g, lm, um, dm);
109 114
  bool ret = circ.run();
110 115
  if (find) {
111 116
    check(ret, "A feasible solution should have been found.");
112 117
    check(circ.checkFlow(), "The found flow is corrupt.");
113 118
    check(!circ.checkBarrier(), "A barrier should not have been found.");
114 119
  } else {
115 120
    check(!ret, "A feasible solution should not have been found.");
116 121
    check(circ.checkBarrier(), "The found barrier is corrupt.");
117 122
  }
118 123
}
119 124

	
120 125
int main (int, char*[])
121 126
{
122 127
  typedef ListDigraph Digraph;
Show white space 64 line context
... ...
@@ -66,64 +66,69 @@
66 66

	
67 67
void checkPreflowCompile()
68 68
{
69 69
  typedef int VType;
70 70
  typedef concepts::Digraph Digraph;
71 71

	
72 72
  typedef Digraph::Node Node;
73 73
  typedef Digraph::Arc Arc;
74 74
  typedef concepts::ReadMap<Arc,VType> CapMap;
75 75
  typedef concepts::ReadWriteMap<Arc,VType> FlowMap;
76 76
  typedef concepts::WriteMap<Node,bool> CutMap;
77 77

	
78 78
  typedef Elevator<Digraph, Digraph::Node> Elev;
79 79
  typedef LinkedElevator<Digraph, Digraph::Node> LinkedElev;
80 80

	
81 81
  Digraph g;
82 82
  Node n;
83 83
  Arc e;
84 84
  CapMap cap;
85 85
  FlowMap flow;
86 86
  CutMap cut;
87 87
  VType v;
88 88
  bool b;
89 89

	
90 90
  typedef Preflow<Digraph, CapMap>
91 91
            ::SetFlowMap<FlowMap>
92 92
            ::SetElevator<Elev>
93 93
            ::SetStandardElevator<LinkedElev>
94 94
            ::Create PreflowType;
95 95
  PreflowType preflow_test(g, cap, n, n);
96 96
  const PreflowType& const_preflow_test = preflow_test;
97 97

	
98
  const PreflowType::Elevator& elev = const_preflow_test.elevator();
99
  preflow_test.elevator(const_cast<PreflowType::Elevator&>(elev));
100
  PreflowType::Tolerance tol = const_preflow_test.tolerance();
101
  preflow_test.tolerance(tol);
102

	
98 103
  preflow_test
99 104
    .capacityMap(cap)
100 105
    .flowMap(flow)
101 106
    .source(n)
102 107
    .target(n);
103 108

	
104 109
  preflow_test.init();
105 110
  preflow_test.init(cap);
106 111
  preflow_test.startFirstPhase();
107 112
  preflow_test.startSecondPhase();
108 113
  preflow_test.run();
109 114
  preflow_test.runMinCut();
110 115

	
111 116
  v = const_preflow_test.flowValue();
112 117
  v = const_preflow_test.flow(e);
113 118
  const FlowMap& fm = const_preflow_test.flowMap();
114 119
  b = const_preflow_test.minCut(n);
115 120
  const_preflow_test.minCutMap(cut);
116 121
  
117 122
  ignore_unused_variable_warning(fm);
118 123
}
119 124

	
120 125
int cutValue (const SmartDigraph& g,
121 126
              const SmartDigraph::NodeMap<bool>& cut,
122 127
              const SmartDigraph::ArcMap<int>& cap) {
123 128

	
124 129
  int c=0;
125 130
  for(SmartDigraph::ArcIt e(g); e!=INVALID; ++e) {
126 131
    if (cut[g.source(e)] && !cut[g.target(e)]) c+=cap[e];
127 132
  }
128 133
  return c;
129 134
}
0 comments (0 inline)