gravatar
alpar (Alpar Juttner)
alpar@cs.elte.hu
Fix wrong initialization in Preflow (#414)
0 2 0
default
2 files changed with 30 insertions and 6 deletions:
↑ Collapse diff ↑
Ignore white space 6 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_PREFLOW_H
20 20
#define LEMON_PREFLOW_H
21 21

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

	
25 25
/// \file
26 26
/// \ingroup max_flow
27 27
/// \brief Implementation of the preflow algorithm.
28 28

	
29 29
namespace lemon {
30 30

	
31 31
  /// \brief Default traits class of Preflow class.
32 32
  ///
33 33
  /// Default traits class of Preflow class.
34 34
  /// \tparam GR Digraph type.
35 35
  /// \tparam CAP Capacity map type.
36 36
  template <typename GR, typename CAP>
37 37
  struct PreflowDefaultTraits {
38 38

	
39 39
    /// \brief The type of the digraph the algorithm runs on.
40 40
    typedef GR Digraph;
41 41

	
42 42
    /// \brief The type of the map that stores the arc capacities.
43 43
    ///
44 44
    /// The type of the map that stores the arc capacities.
45 45
    /// It must meet the \ref concepts::ReadMap "ReadMap" concept.
46 46
    typedef CAP CapacityMap;
47 47

	
48 48
    /// \brief The type of the flow values.
49 49
    typedef typename CapacityMap::Value Value;
50 50

	
51 51
    /// \brief The type of the map that stores the flow values.
52 52
    ///
53 53
    /// The type of the map that stores the flow values.
54 54
    /// It must meet the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
55 55
    typedef typename Digraph::template ArcMap<Value> FlowMap;
56 56

	
57 57
    /// \brief Instantiates a FlowMap.
58 58
    ///
59 59
    /// This function instantiates a \ref FlowMap.
60 60
    /// \param digraph The digraph for which we would like to define
61 61
    /// the flow map.
62 62
    static FlowMap* createFlowMap(const Digraph& digraph) {
63 63
      return new FlowMap(digraph);
64 64
    }
65 65

	
66 66
    /// \brief The elevator type used by Preflow algorithm.
67 67
    ///
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 100
  /// flow algorithms. The current implementation use 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.
133 133
    typedef typename Traits::Elevator Elevator;
134 134
    ///The type of the tolerance.
135 135
    typedef typename Traits::Tolerance Tolerance;
136 136

	
137 137
  private:
138 138

	
139 139
    TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
140 140

	
141 141
    const Digraph& _graph;
142 142
    const CapacityMap* _capacity;
143 143

	
144 144
    int _node_num;
145 145

	
146 146
    Node _source, _target;
147 147

	
148 148
    FlowMap* _flow;
149 149
    bool _local_flow;
150 150

	
151 151
    Elevator* _level;
152 152
    bool _local_level;
153 153

	
154 154
    typedef typename Digraph::template NodeMap<Value> ExcessMap;
155 155
    ExcessMap* _excess;
156 156

	
157 157
    Tolerance _tolerance;
158 158

	
159 159
    bool _phase;
160 160

	
161 161

	
162 162
    void createStructures() {
163 163
      _node_num = countNodes(_graph);
164 164

	
165 165
      if (!_flow) {
166 166
        _flow = Traits::createFlowMap(_graph);
167 167
        _local_flow = true;
168 168
      }
169 169
      if (!_level) {
170 170
        _level = Traits::createElevator(_graph, _node_num);
171 171
        _local_level = true;
172 172
      }
173 173
      if (!_excess) {
174 174
        _excess = new ExcessMap(_graph);
175 175
      }
176 176
    }
177 177

	
178 178
    void destroyStructures() {
179 179
      if (_local_flow) {
180 180
        delete _flow;
181 181
      }
182 182
      if (_local_level) {
183 183
        delete _level;
184 184
      }
185 185
      if (_excess) {
186 186
        delete _excess;
187 187
      }
188 188
    }
189 189

	
190 190
  public:
191 191

	
192 192
    typedef Preflow Create;
193 193

	
194 194
    ///\name Named Template Parameters
195 195

	
196 196
    ///@{
197 197

	
198 198
    template <typename T>
199 199
    struct SetFlowMapTraits : public Traits {
200 200
      typedef T FlowMap;
201 201
      static FlowMap *createFlowMap(const Digraph&) {
202 202
        LEMON_ASSERT(false, "FlowMap is not initialized");
203 203
        return 0; // ignore warnings
204 204
      }
205 205
    };
206 206

	
207 207
    /// \brief \ref named-templ-param "Named parameter" for setting
208 208
    /// FlowMap type
209 209
    ///
210 210
    /// \ref named-templ-param "Named parameter" for setting FlowMap
211 211
    /// type.
212 212
    template <typename T>
213 213
    struct SetFlowMap
214 214
      : public Preflow<Digraph, CapacityMap, SetFlowMapTraits<T> > {
215 215
      typedef Preflow<Digraph, CapacityMap,
216 216
                      SetFlowMapTraits<T> > Create;
217 217
    };
218 218

	
219 219
    template <typename T>
220 220
    struct SetElevatorTraits : public Traits {
221 221
      typedef T Elevator;
222 222
      static Elevator *createElevator(const Digraph&, int) {
223 223
        LEMON_ASSERT(false, "Elevator is not initialized");
224 224
        return 0; // ignore warnings
225 225
      }
226 226
    };
227 227

	
228 228
    /// \brief \ref named-templ-param "Named parameter" for setting
229 229
    /// Elevator type
230 230
    ///
231 231
    /// \ref named-templ-param "Named parameter" for setting Elevator
232 232
    /// type. If this named parameter is used, then an external
233 233
    /// elevator object must be passed to the algorithm using the
234 234
    /// \ref elevator(Elevator&) "elevator()" function before calling
235 235
    /// \ref run() or \ref init().
236 236
    /// \sa SetStandardElevator
237 237
    template <typename T>
238 238
    struct SetElevator
239 239
      : public Preflow<Digraph, CapacityMap, SetElevatorTraits<T> > {
240 240
      typedef Preflow<Digraph, CapacityMap,
241 241
                      SetElevatorTraits<T> > Create;
242 242
    };
243 243

	
244 244
    template <typename T>
245 245
    struct SetStandardElevatorTraits : public Traits {
246 246
      typedef T Elevator;
247 247
      static Elevator *createElevator(const Digraph& digraph, int max_level) {
248 248
        return new Elevator(digraph, max_level);
249 249
      }
250 250
    };
251 251

	
252 252
    /// \brief \ref named-templ-param "Named parameter" for setting
253 253
    /// Elevator type with automatic allocation
254 254
    ///
255 255
    /// \ref named-templ-param "Named parameter" for setting Elevator
256 256
    /// type with automatic allocation.
257 257
    /// The Elevator should have standard constructor interface to be
258 258
    /// able to automatically created by the algorithm (i.e. the
259 259
    /// digraph and the maximum level should be passed to it).
260 260
    /// However an external elevator object could also be passed to the
261 261
    /// algorithm with the \ref elevator(Elevator&) "elevator()" function
262 262
    /// before calling \ref run() or \ref init().
263 263
    /// \sa SetElevator
264 264
    template <typename T>
265 265
    struct SetStandardElevator
266 266
      : public Preflow<Digraph, CapacityMap,
267 267
                       SetStandardElevatorTraits<T> > {
268 268
      typedef Preflow<Digraph, CapacityMap,
269 269
                      SetStandardElevatorTraits<T> > Create;
270 270
    };
271 271

	
272 272
    /// @}
273 273

	
274 274
  protected:
275 275

	
276 276
    Preflow() {}
277 277

	
278 278
  public:
279 279

	
280 280

	
281 281
    /// \brief The constructor of the class.
282 282
    ///
283 283
    /// The constructor of the class.
284 284
    /// \param digraph The digraph the algorithm runs on.
285 285
    /// \param capacity The capacity of the arcs.
286 286
    /// \param source The source node.
287 287
    /// \param target The target node.
288 288
    Preflow(const Digraph& digraph, const CapacityMap& capacity,
289 289
            Node source, Node target)
290 290
      : _graph(digraph), _capacity(&capacity),
291 291
        _node_num(0), _source(source), _target(target),
292 292
        _flow(0), _local_flow(false),
293 293
        _level(0), _local_level(false),
294 294
        _excess(0), _tolerance(), _phase() {}
295 295

	
296 296
    /// \brief Destructor.
297 297
    ///
298 298
    /// Destructor.
299 299
    ~Preflow() {
300 300
      destroyStructures();
301 301
    }
302 302

	
303 303
    /// \brief Sets the capacity map.
304 304
    ///
305 305
    /// Sets the capacity map.
306 306
    /// \return <tt>(*this)</tt>
307 307
    Preflow& capacityMap(const CapacityMap& map) {
308 308
      _capacity = &map;
309 309
      return *this;
310 310
    }
311 311

	
312 312
    /// \brief Sets the flow map.
313 313
    ///
314 314
    /// Sets the flow map.
315 315
    /// If you don't use this function before calling \ref run() or
316 316
    /// \ref init(), an instance will be allocated automatically.
317 317
    /// The destructor deallocates this automatically allocated map,
318 318
    /// of course.
319 319
    /// \return <tt>(*this)</tt>
320 320
    Preflow& flowMap(FlowMap& map) {
321 321
      if (_local_flow) {
322 322
        delete _flow;
323 323
        _local_flow = false;
324 324
      }
325 325
      _flow = &map;
326 326
      return *this;
327 327
    }
328 328

	
329 329
    /// \brief Sets the source node.
330 330
    ///
331 331
    /// Sets the source node.
332 332
    /// \return <tt>(*this)</tt>
333 333
    Preflow& source(const Node& node) {
334 334
      _source = node;
335 335
      return *this;
336 336
    }
337 337

	
338 338
    /// \brief Sets the target node.
339 339
    ///
340 340
    /// Sets the target node.
341 341
    /// \return <tt>(*this)</tt>
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 374
    /// \brief Sets the tolerance used by algorithm.
375 375
    ///
376 376
    /// Sets the tolerance used by algorithm.
377 377
    Preflow& tolerance(const Tolerance& tolerance) {
378 378
      _tolerance = tolerance;
379 379
      return *this;
380 380
    }
381 381

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

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

	
396 396
    ///@{
397 397

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

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

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

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

	
416 416
      _level->initStart();
417 417
      _level->initAddItem(_target);
418 418

	
419 419
      std::vector<Node> queue;
420 420
      reached[_source] = true;
421 421

	
422 422
      queue.push_back(_target);
423 423
      reached[_target] = true;
424 424
      while (!queue.empty()) {
425 425
        _level->initNewLevel();
426 426
        std::vector<Node> nqueue;
427 427
        for (int i = 0; i < int(queue.size()); ++i) {
428 428
          Node n = queue[i];
429 429
          for (InArcIt e(_graph, n); e != INVALID; ++e) {
430 430
            Node u = _graph.source(e);
431 431
            if (!reached[u] && _tolerance.positive((*_capacity)[e])) {
432 432
              reached[u] = true;
433 433
              _level->initAddItem(u);
434 434
              nqueue.push_back(u);
435 435
            }
436 436
          }
437 437
        }
438 438
        queue.swap(nqueue);
439 439
      }
440 440
      _level->initFinish();
441 441

	
442 442
      for (OutArcIt e(_graph, _source); e != INVALID; ++e) {
443 443
        if (_tolerance.positive((*_capacity)[e])) {
444 444
          Node u = _graph.target(e);
445 445
          if ((*_level)[u] == _level->maxLevel()) continue;
446 446
          _flow->set(e, (*_capacity)[e]);
447 447
          (*_excess)[u] += (*_capacity)[e];
448 448
          if (u != _target && !_level->active(u)) {
449 449
            _level->activate(u);
450 450
          }
451 451
        }
452 452
      }
453 453
    }
454 454

	
455 455
    /// \brief Initializes the internal data structures using the
456 456
    /// given flow map.
457 457
    ///
458 458
    /// Initializes the internal data structures and sets the initial
459 459
    /// flow to the given \c flowMap. The \c flowMap should contain a
460 460
    /// flow or at least a preflow, i.e. at each node excluding the
461 461
    /// source node the incoming flow should greater or equal to the
462 462
    /// outgoing flow.
463 463
    /// \return \c false if the given \c flowMap is not a preflow.
464 464
    template <typename FlowMap>
465 465
    bool init(const FlowMap& flowMap) {
466 466
      createStructures();
467 467

	
468 468
      for (ArcIt e(_graph); e != INVALID; ++e) {
469 469
        _flow->set(e, flowMap[e]);
470 470
      }
471 471

	
472 472
      for (NodeIt n(_graph); n != INVALID; ++n) {
473 473
        Value excess = 0;
474 474
        for (InArcIt e(_graph, n); e != INVALID; ++e) {
475 475
          excess += (*_flow)[e];
476 476
        }
477 477
        for (OutArcIt e(_graph, n); e != INVALID; ++e) {
478 478
          excess -= (*_flow)[e];
479 479
        }
480 480
        if (excess < 0 && n != _source) return false;
481 481
        (*_excess)[n] = excess;
482 482
      }
483 483

	
484 484
      typename Digraph::template NodeMap<bool> reached(_graph, false);
485 485

	
486 486
      _level->initStart();
487 487
      _level->initAddItem(_target);
488 488

	
489 489
      std::vector<Node> queue;
490 490
      reached[_source] = true;
491 491

	
492 492
      queue.push_back(_target);
493 493
      reached[_target] = true;
494 494
      while (!queue.empty()) {
495 495
        _level->initNewLevel();
496 496
        std::vector<Node> nqueue;
497 497
        for (int i = 0; i < int(queue.size()); ++i) {
498 498
          Node n = queue[i];
499 499
          for (InArcIt e(_graph, n); e != INVALID; ++e) {
500 500
            Node u = _graph.source(e);
501 501
            if (!reached[u] &&
502 502
                _tolerance.positive((*_capacity)[e] - (*_flow)[e])) {
503 503
              reached[u] = true;
504 504
              _level->initAddItem(u);
505 505
              nqueue.push_back(u);
506 506
            }
507 507
          }
508 508
          for (OutArcIt e(_graph, n); e != INVALID; ++e) {
509 509
            Node v = _graph.target(e);
510 510
            if (!reached[v] && _tolerance.positive((*_flow)[e])) {
511 511
              reached[v] = true;
512 512
              _level->initAddItem(v);
513 513
              nqueue.push_back(v);
514 514
            }
515 515
          }
516 516
        }
517 517
        queue.swap(nqueue);
518 518
      }
519 519
      _level->initFinish();
520 520

	
521 521
      for (OutArcIt e(_graph, _source); e != INVALID; ++e) {
522 522
        Value rem = (*_capacity)[e] - (*_flow)[e];
523 523
        if (_tolerance.positive(rem)) {
524 524
          Node u = _graph.target(e);
525 525
          if ((*_level)[u] == _level->maxLevel()) continue;
526 526
          _flow->set(e, (*_capacity)[e]);
527 527
          (*_excess)[u] += rem;
528
          if (u != _target && !_level->active(u)) {
529
            _level->activate(u);
530
          }
531 528
        }
532 529
      }
533 530
      for (InArcIt e(_graph, _source); e != INVALID; ++e) {
534 531
        Value rem = (*_flow)[e];
535 532
        if (_tolerance.positive(rem)) {
536 533
          Node v = _graph.source(e);
537 534
          if ((*_level)[v] == _level->maxLevel()) continue;
538 535
          _flow->set(e, 0);
539 536
          (*_excess)[v] += rem;
540
          if (v != _target && !_level->active(v)) {
541
            _level->activate(v);
542
          }
543 537
        }
544 538
      }
539
      for (NodeIt n(_graph); n != INVALID; ++n) 
540
        if(n!=_source && n!=_target && _tolerance.positive((*_excess)[n]))
541
          _level->activate(n);
542
          
545 543
      return true;
546 544
    }
547 545

	
548 546
    /// \brief Starts the first phase of the preflow algorithm.
549 547
    ///
550 548
    /// The preflow algorithm consists of two phases, this method runs
551 549
    /// the first phase. After the first phase the maximum flow value
552 550
    /// and a minimum value cut can already be computed, although a
553 551
    /// maximum flow is not yet obtained. So after calling this method
554 552
    /// \ref flowValue() returns the value of a maximum flow and \ref
555 553
    /// minCut() returns a minimum cut.
556 554
    /// \pre One of the \ref init() functions must be called before
557 555
    /// using this function.
558 556
    void startFirstPhase() {
559 557
      _phase = true;
560 558

	
561 559
      while (true) {
562 560
        int num = _node_num;
563 561

	
564 562
        Node n = INVALID;
565 563
        int level = -1;
566 564

	
567 565
        while (num > 0) {
568 566
          n = _level->highestActive();
569 567
          if (n == INVALID) goto first_phase_done;
570 568
          level = _level->highestActiveLevel();
571 569
          --num;
572 570
          
573 571
          Value excess = (*_excess)[n];
574 572
          int new_level = _level->maxLevel();
575 573

	
576 574
          for (OutArcIt e(_graph, n); e != INVALID; ++e) {
577 575
            Value rem = (*_capacity)[e] - (*_flow)[e];
578 576
            if (!_tolerance.positive(rem)) continue;
579 577
            Node v = _graph.target(e);
580 578
            if ((*_level)[v] < level) {
581 579
              if (!_level->active(v) && v != _target) {
582 580
                _level->activate(v);
583 581
              }
584 582
              if (!_tolerance.less(rem, excess)) {
585 583
                _flow->set(e, (*_flow)[e] + excess);
586 584
                (*_excess)[v] += excess;
587 585
                excess = 0;
588 586
                goto no_more_push_1;
589 587
              } else {
590 588
                excess -= rem;
591 589
                (*_excess)[v] += rem;
592 590
                _flow->set(e, (*_capacity)[e]);
593 591
              }
594 592
            } else if (new_level > (*_level)[v]) {
595 593
              new_level = (*_level)[v];
596 594
            }
597 595
          }
598 596

	
599 597
          for (InArcIt e(_graph, n); e != INVALID; ++e) {
600 598
            Value rem = (*_flow)[e];
601 599
            if (!_tolerance.positive(rem)) continue;
602 600
            Node v = _graph.source(e);
603 601
            if ((*_level)[v] < level) {
604 602
              if (!_level->active(v) && v != _target) {
605 603
                _level->activate(v);
606 604
              }
607 605
              if (!_tolerance.less(rem, excess)) {
608 606
                _flow->set(e, (*_flow)[e] - excess);
609 607
                (*_excess)[v] += excess;
610 608
                excess = 0;
611 609
                goto no_more_push_1;
612 610
              } else {
613 611
                excess -= rem;
614 612
                (*_excess)[v] += rem;
615 613
                _flow->set(e, 0);
616 614
              }
617 615
            } else if (new_level > (*_level)[v]) {
618 616
              new_level = (*_level)[v];
619 617
            }
620 618
          }
621 619

	
622 620
        no_more_push_1:
623 621

	
624 622
          (*_excess)[n] = excess;
625 623

	
626 624
          if (excess != 0) {
627 625
            if (new_level + 1 < _level->maxLevel()) {
628 626
              _level->liftHighestActive(new_level + 1);
629 627
            } else {
630 628
              _level->liftHighestActiveToTop();
631 629
            }
632 630
            if (_level->emptyLevel(level)) {
633 631
              _level->liftToTop(level);
634 632
            }
635 633
          } else {
636 634
            _level->deactivate(n);
637 635
          }
638 636
        }
639 637

	
640 638
        num = _node_num * 20;
641 639
        while (num > 0) {
642 640
          while (level >= 0 && _level->activeFree(level)) {
643 641
            --level;
644 642
          }
645 643
          if (level == -1) {
646 644
            n = _level->highestActive();
647 645
            level = _level->highestActiveLevel();
648 646
            if (n == INVALID) goto first_phase_done;
649 647
          } else {
650 648
            n = _level->activeOn(level);
651 649
          }
652 650
          --num;
653 651

	
654 652
          Value excess = (*_excess)[n];
655 653
          int new_level = _level->maxLevel();
656 654

	
657 655
          for (OutArcIt e(_graph, n); e != INVALID; ++e) {
658 656
            Value rem = (*_capacity)[e] - (*_flow)[e];
659 657
            if (!_tolerance.positive(rem)) continue;
660 658
            Node v = _graph.target(e);
661 659
            if ((*_level)[v] < level) {
662 660
              if (!_level->active(v) && v != _target) {
663 661
                _level->activate(v);
664 662
              }
665 663
              if (!_tolerance.less(rem, excess)) {
666 664
                _flow->set(e, (*_flow)[e] + excess);
667 665
                (*_excess)[v] += excess;
668 666
                excess = 0;
669 667
                goto no_more_push_2;
670 668
              } else {
671 669
                excess -= rem;
672 670
                (*_excess)[v] += rem;
673 671
                _flow->set(e, (*_capacity)[e]);
674 672
              }
675 673
            } else if (new_level > (*_level)[v]) {
676 674
              new_level = (*_level)[v];
677 675
            }
678 676
          }
679 677

	
680 678
          for (InArcIt e(_graph, n); e != INVALID; ++e) {
681 679
            Value rem = (*_flow)[e];
682 680
            if (!_tolerance.positive(rem)) continue;
683 681
            Node v = _graph.source(e);
684 682
            if ((*_level)[v] < level) {
685 683
              if (!_level->active(v) && v != _target) {
686 684
                _level->activate(v);
687 685
              }
688 686
              if (!_tolerance.less(rem, excess)) {
689 687
                _flow->set(e, (*_flow)[e] - excess);
690 688
                (*_excess)[v] += excess;
691 689
                excess = 0;
692 690
                goto no_more_push_2;
693 691
              } else {
694 692
                excess -= rem;
695 693
                (*_excess)[v] += rem;
696 694
                _flow->set(e, 0);
697 695
              }
698 696
            } else if (new_level > (*_level)[v]) {
699 697
              new_level = (*_level)[v];
700 698
            }
701 699
          }
702 700

	
703 701
        no_more_push_2:
704 702

	
705 703
          (*_excess)[n] = excess;
706 704

	
707 705
          if (excess != 0) {
708 706
            if (new_level + 1 < _level->maxLevel()) {
709 707
              _level->liftActiveOn(level, new_level + 1);
710 708
            } else {
711 709
              _level->liftActiveToTop(level);
712 710
            }
713 711
            if (_level->emptyLevel(level)) {
714 712
              _level->liftToTop(level);
715 713
            }
716 714
          } else {
717 715
            _level->deactivate(n);
718 716
          }
719 717
        }
720 718
      }
721 719
    first_phase_done:;
722 720
    }
723 721

	
724 722
    /// \brief Starts the second phase of the preflow algorithm.
725 723
    ///
726 724
    /// The preflow algorithm consists of two phases, this method runs
727 725
    /// the second phase. After calling one of the \ref init() functions
728 726
    /// and \ref startFirstPhase() and then \ref startSecondPhase(),
729 727
    /// \ref flowMap() returns a maximum flow, \ref flowValue() returns the
730 728
    /// value of a maximum flow, \ref minCut() returns a minimum cut
731 729
    /// \pre One of the \ref init() functions and \ref startFirstPhase()
732 730
    /// must be called before using this function.
733 731
    void startSecondPhase() {
734 732
      _phase = false;
735 733

	
736 734
      typename Digraph::template NodeMap<bool> reached(_graph);
737 735
      for (NodeIt n(_graph); n != INVALID; ++n) {
738 736
        reached[n] = (*_level)[n] < _level->maxLevel();
739 737
      }
740 738

	
741 739
      _level->initStart();
742 740
      _level->initAddItem(_source);
743 741

	
744 742
      std::vector<Node> queue;
745 743
      queue.push_back(_source);
746 744
      reached[_source] = true;
747 745

	
748 746
      while (!queue.empty()) {
749 747
        _level->initNewLevel();
750 748
        std::vector<Node> nqueue;
751 749
        for (int i = 0; i < int(queue.size()); ++i) {
752 750
          Node n = queue[i];
753 751
          for (OutArcIt e(_graph, n); e != INVALID; ++e) {
754 752
            Node v = _graph.target(e);
755 753
            if (!reached[v] && _tolerance.positive((*_flow)[e])) {
756 754
              reached[v] = true;
757 755
              _level->initAddItem(v);
758 756
              nqueue.push_back(v);
759 757
            }
760 758
          }
761 759
          for (InArcIt e(_graph, n); e != INVALID; ++e) {
762 760
            Node u = _graph.source(e);
763 761
            if (!reached[u] &&
764 762
                _tolerance.positive((*_capacity)[e] - (*_flow)[e])) {
765 763
              reached[u] = true;
766 764
              _level->initAddItem(u);
767 765
              nqueue.push_back(u);
768 766
            }
769 767
          }
770 768
        }
771 769
        queue.swap(nqueue);
772 770
      }
773 771
      _level->initFinish();
774 772

	
775 773
      for (NodeIt n(_graph); n != INVALID; ++n) {
776 774
        if (!reached[n]) {
777 775
          _level->dirtyTopButOne(n);
778 776
        } else if ((*_excess)[n] > 0 && _target != n) {
779 777
          _level->activate(n);
780 778
        }
781 779
      }
782 780

	
783 781
      Node n;
784 782
      while ((n = _level->highestActive()) != INVALID) {
785 783
        Value excess = (*_excess)[n];
786 784
        int level = _level->highestActiveLevel();
787 785
        int new_level = _level->maxLevel();
788 786

	
789 787
        for (OutArcIt e(_graph, n); e != INVALID; ++e) {
790 788
          Value rem = (*_capacity)[e] - (*_flow)[e];
791 789
          if (!_tolerance.positive(rem)) continue;
792 790
          Node v = _graph.target(e);
793 791
          if ((*_level)[v] < level) {
794 792
            if (!_level->active(v) && v != _source) {
795 793
              _level->activate(v);
796 794
            }
797 795
            if (!_tolerance.less(rem, excess)) {
798 796
              _flow->set(e, (*_flow)[e] + excess);
799 797
              (*_excess)[v] += excess;
800 798
              excess = 0;
801 799
              goto no_more_push;
802 800
            } else {
803 801
              excess -= rem;
804 802
              (*_excess)[v] += rem;
805 803
              _flow->set(e, (*_capacity)[e]);
806 804
            }
807 805
          } else if (new_level > (*_level)[v]) {
808 806
            new_level = (*_level)[v];
809 807
          }
810 808
        }
811 809

	
812 810
        for (InArcIt e(_graph, n); e != INVALID; ++e) {
813 811
          Value rem = (*_flow)[e];
814 812
          if (!_tolerance.positive(rem)) continue;
815 813
          Node v = _graph.source(e);
816 814
          if ((*_level)[v] < level) {
817 815
            if (!_level->active(v) && v != _source) {
818 816
              _level->activate(v);
819 817
            }
820 818
            if (!_tolerance.less(rem, excess)) {
821 819
              _flow->set(e, (*_flow)[e] - excess);
822 820
              (*_excess)[v] += excess;
823 821
              excess = 0;
824 822
              goto no_more_push;
825 823
            } else {
826 824
              excess -= rem;
827 825
              (*_excess)[v] += rem;
828 826
              _flow->set(e, 0);
829 827
            }
830 828
          } else if (new_level > (*_level)[v]) {
831 829
            new_level = (*_level)[v];
832 830
          }
833 831
        }
834 832

	
835 833
      no_more_push:
836 834

	
837 835
        (*_excess)[n] = excess;
838 836

	
839 837
        if (excess != 0) {
840 838
          if (new_level + 1 < _level->maxLevel()) {
841 839
            _level->liftHighestActive(new_level + 1);
842 840
          } else {
843 841
            // Calculation error
844 842
            _level->liftHighestActiveToTop();
845 843
          }
846 844
          if (_level->emptyLevel(level)) {
847 845
            // Calculation error
848 846
            _level->liftToTop(level);
849 847
          }
850 848
        } else {
851 849
          _level->deactivate(n);
852 850
        }
853 851

	
854 852
      }
855 853
    }
856 854

	
857 855
    /// \brief Runs the preflow algorithm.
858 856
    ///
859 857
    /// Runs the preflow algorithm.
860 858
    /// \note pf.run() is just a shortcut of the following code.
861 859
    /// \code
862 860
    ///   pf.init();
863 861
    ///   pf.startFirstPhase();
864 862
    ///   pf.startSecondPhase();
865 863
    /// \endcode
866 864
    void run() {
867 865
      init();
868 866
      startFirstPhase();
869 867
      startSecondPhase();
870 868
    }
871 869

	
872 870
    /// \brief Runs the preflow algorithm to compute the minimum cut.
873 871
    ///
874 872
    /// Runs the preflow algorithm to compute the minimum cut.
875 873
    /// \note pf.runMinCut() is just a shortcut of the following code.
876 874
    /// \code
877 875
    ///   pf.init();
878 876
    ///   pf.startFirstPhase();
879 877
    /// \endcode
880 878
    void runMinCut() {
881 879
      init();
882 880
      startFirstPhase();
883 881
    }
884 882

	
885 883
    /// @}
886 884

	
887 885
    /// \name Query Functions
888 886
    /// The results of the preflow algorithm can be obtained using these
889 887
    /// functions.\n
890 888
    /// Either one of the \ref run() "run*()" functions or one of the
891 889
    /// \ref startFirstPhase() "start*()" functions should be called
892 890
    /// before using them.
893 891

	
894 892
    ///@{
895 893

	
896 894
    /// \brief Returns the value of the maximum flow.
897 895
    ///
898 896
    /// Returns the value of the maximum flow by returning the excess
899 897
    /// of the target node. This value equals to the value of
900 898
    /// the maximum flow already after the first phase of the algorithm.
901 899
    ///
902 900
    /// \pre Either \ref run() or \ref init() must be called before
903 901
    /// using this function.
904 902
    Value flowValue() const {
905 903
      return (*_excess)[_target];
906 904
    }
907 905

	
908 906
    /// \brief Returns the flow value on the given arc.
909 907
    ///
910 908
    /// Returns the flow value on the given arc. This method can
911 909
    /// be called after the second phase of the algorithm.
912 910
    ///
913 911
    /// \pre Either \ref run() or \ref init() must be called before
914 912
    /// using this function.
915 913
    Value flow(const Arc& arc) const {
916 914
      return (*_flow)[arc];
917 915
    }
918 916

	
919 917
    /// \brief Returns a const reference to the flow map.
920 918
    ///
921 919
    /// Returns a const reference to the arc map storing the found flow.
922 920
    /// This method can be called after the second phase of the algorithm.
923 921
    ///
924 922
    /// \pre Either \ref run() or \ref init() must be called before
925 923
    /// using this function.
926 924
    const FlowMap& flowMap() const {
927 925
      return *_flow;
928 926
    }
929 927

	
930 928
    /// \brief Returns \c true when the node is on the source side of the
931 929
    /// minimum cut.
932 930
    ///
933 931
    /// Returns true when the node is on the source side of the found
934 932
    /// minimum cut. This method can be called both after running \ref
935 933
    /// startFirstPhase() and \ref startSecondPhase().
936 934
    ///
937 935
    /// \pre Either \ref run() or \ref init() must be called before
938 936
    /// using this function.
939 937
    bool minCut(const Node& node) const {
940 938
      return ((*_level)[node] == _level->maxLevel()) == _phase;
941 939
    }
942 940

	
943 941
    /// \brief Gives back a minimum value cut.
944 942
    ///
945 943
    /// Sets \c cutMap to the characteristic vector of a minimum value
946 944
    /// cut. \c cutMap should be a \ref concepts::WriteMap "writable"
947 945
    /// node map with \c bool (or convertible) value type.
948 946
    ///
949 947
    /// This method can be called both after running \ref startFirstPhase()
950 948
    /// and \ref startSecondPhase(). The result after the second phase
951 949
    /// could be slightly different if inexact computation is used.
952 950
    ///
953 951
    /// \note This function calls \ref minCut() for each node, so it runs in
954 952
    /// O(n) time.
955 953
    ///
956 954
    /// \pre Either \ref run() or \ref init() must be called before
957 955
    /// using this function.
958 956
    template <typename CutMap>
959 957
    void minCutMap(CutMap& cutMap) const {
960 958
      for (NodeIt n(_graph); n != INVALID; ++n) {
961 959
        cutMap.set(n, minCut(n));
962 960
      }
963 961
    }
964 962

	
965 963
    /// @}
966 964
  };
967 965
}
968 966

	
969 967
#endif
Ignore white space 49152 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
#include <iostream>
20 20

	
21 21
#include "test_tools.h"
22 22
#include <lemon/smart_graph.h>
23 23
#include <lemon/preflow.h>
24 24
#include <lemon/concepts/digraph.h>
25 25
#include <lemon/concepts/maps.h>
26 26
#include <lemon/lgf_reader.h>
27 27
#include <lemon/elevator.h>
28 28

	
29 29
using namespace lemon;
30 30

	
31 31
char test_lgf[] =
32 32
  "@nodes\n"
33 33
  "label\n"
34 34
  "0\n"
35 35
  "1\n"
36 36
  "2\n"
37 37
  "3\n"
38 38
  "4\n"
39 39
  "5\n"
40 40
  "6\n"
41 41
  "7\n"
42 42
  "8\n"
43 43
  "9\n"
44 44
  "@arcs\n"
45 45
  "    label capacity\n"
46 46
  "0 1 0     20\n"
47 47
  "0 2 1     0\n"
48 48
  "1 1 2     3\n"
49 49
  "1 2 3     8\n"
50 50
  "1 3 4     8\n"
51 51
  "2 5 5     5\n"
52 52
  "3 2 6     5\n"
53 53
  "3 5 7     5\n"
54 54
  "3 6 8     5\n"
55 55
  "4 3 9     3\n"
56 56
  "5 7 10    3\n"
57 57
  "5 6 11    10\n"
58 58
  "5 8 12    10\n"
59 59
  "6 8 13    8\n"
60 60
  "8 9 14    20\n"
61 61
  "8 1 15    5\n"
62 62
  "9 5 16    5\n"
63 63
  "@attributes\n"
64 64
  "source 1\n"
65 65
  "target 8\n";
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 98
  preflow_test
99 99
    .capacityMap(cap)
100 100
    .flowMap(flow)
101 101
    .source(n)
102 102
    .target(n);
103 103

	
104 104
  preflow_test.init();
105 105
  preflow_test.init(cap);
106 106
  preflow_test.startFirstPhase();
107 107
  preflow_test.startSecondPhase();
108 108
  preflow_test.run();
109 109
  preflow_test.runMinCut();
110 110

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

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

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

	
131 131
bool checkFlow(const SmartDigraph& g,
132 132
               const SmartDigraph::ArcMap<int>& flow,
133 133
               const SmartDigraph::ArcMap<int>& cap,
134 134
               SmartDigraph::Node s, SmartDigraph::Node t) {
135 135

	
136 136
  for (SmartDigraph::ArcIt e(g); e != INVALID; ++e) {
137 137
    if (flow[e] < 0 || flow[e] > cap[e]) return false;
138 138
  }
139 139

	
140 140
  for (SmartDigraph::NodeIt n(g); n != INVALID; ++n) {
141 141
    if (n == s || n == t) continue;
142 142
    int sum = 0;
143 143
    for (SmartDigraph::OutArcIt e(g, n); e != INVALID; ++e) {
144 144
      sum += flow[e];
145 145
    }
146 146
    for (SmartDigraph::InArcIt e(g, n); e != INVALID; ++e) {
147 147
      sum -= flow[e];
148 148
    }
149 149
    if (sum != 0) return false;
150 150
  }
151 151
  return true;
152 152
}
153 153

	
154
void initFlowTest()
155
{
156
  DIGRAPH_TYPEDEFS(SmartDigraph);
157
  
158
  SmartDigraph g;
159
  SmartDigraph::ArcMap<int> cap(g),iflow(g);
160
  Node s=g.addNode(); Node t=g.addNode();
161
  Node n1=g.addNode(); Node n2=g.addNode();
162
  Arc a;
163
  a=g.addArc(s,n1); cap[a]=20; iflow[a]=20;
164
  a=g.addArc(n1,n2); cap[a]=10; iflow[a]=0;
165
  a=g.addArc(n2,t); cap[a]=20; iflow[a]=0;
166

	
167
  Preflow<SmartDigraph> pre(g,cap,s,t);
168
  pre.init(iflow);
169
  pre.startFirstPhase();
170
  check(pre.flowValue() == 10, "The incorrect max flow value.");
171
  check(pre.minCut(s), "Wrong min cut (Node s).");
172
  check(pre.minCut(n1), "Wrong min cut (Node n1).");
173
  check(!pre.minCut(n2), "Wrong min cut (Node n2).");
174
  check(!pre.minCut(t), "Wrong min cut (Node t).");
175
}
176

	
177

	
154 178
int main() {
155 179

	
156 180
  typedef SmartDigraph Digraph;
157 181

	
158 182
  typedef Digraph::Node Node;
159 183
  typedef Digraph::NodeIt NodeIt;
160 184
  typedef Digraph::ArcIt ArcIt;
161 185
  typedef Digraph::ArcMap<int> CapMap;
162 186
  typedef Digraph::ArcMap<int> FlowMap;
163 187
  typedef Digraph::NodeMap<bool> CutMap;
164 188

	
165 189
  typedef Preflow<Digraph, CapMap> PType;
166 190

	
167 191
  Digraph g;
168 192
  Node s, t;
169 193
  CapMap cap(g);
170 194
  std::istringstream input(test_lgf);
171 195
  DigraphReader<Digraph>(g,input).
172 196
    arcMap("capacity", cap).
173 197
    node("source",s).
174 198
    node("target",t).
175 199
    run();
176 200

	
177 201
  PType preflow_test(g, cap, s, t);
178 202
  preflow_test.run();
179 203

	
180 204
  check(checkFlow(g, preflow_test.flowMap(), cap, s, t),
181 205
        "The flow is not feasible.");
182 206

	
183 207
  CutMap min_cut(g);
184 208
  preflow_test.minCutMap(min_cut);
185 209
  int min_cut_value=cutValue(g,min_cut,cap);
186 210

	
187 211
  check(preflow_test.flowValue() == min_cut_value,
188 212
        "The max flow value is not equal to the three min cut values.");
189 213

	
190 214
  FlowMap flow(g);
191 215
  for(ArcIt e(g); e!=INVALID; ++e) flow[e] = preflow_test.flowMap()[e];
192 216

	
193 217
  int flow_value=preflow_test.flowValue();
194 218

	
195 219
  for(ArcIt e(g); e!=INVALID; ++e) cap[e]=2*cap[e];
196 220
  preflow_test.init(flow);
197 221
  preflow_test.startFirstPhase();
198 222

	
199 223
  CutMap min_cut1(g);
200 224
  preflow_test.minCutMap(min_cut1);
201 225
  min_cut_value=cutValue(g,min_cut1,cap);
202 226

	
203 227
  check(preflow_test.flowValue() == min_cut_value &&
204 228
        min_cut_value == 2*flow_value,
205 229
        "The max flow value or the min cut value is wrong.");
206 230

	
207 231
  preflow_test.startSecondPhase();
208 232

	
209 233
  check(checkFlow(g, preflow_test.flowMap(), cap, s, t),
210 234
        "The flow is not feasible.");
211 235

	
212 236
  CutMap min_cut2(g);
213 237
  preflow_test.minCutMap(min_cut2);
214 238
  min_cut_value=cutValue(g,min_cut2,cap);
215 239

	
216 240
  check(preflow_test.flowValue() == min_cut_value &&
217 241
        min_cut_value == 2*flow_value,
218 242
        "The max flow value or the three min cut values were not doubled");
219 243

	
220 244

	
221 245
  preflow_test.flowMap(flow);
222 246

	
223 247
  NodeIt tmp1(g,s);
224 248
  ++tmp1;
225 249
  if ( tmp1 != INVALID ) s=tmp1;
226 250

	
227 251
  NodeIt tmp2(g,t);
228 252
  ++tmp2;
229 253
  if ( tmp2 != INVALID ) t=tmp2;
230 254

	
231 255
  preflow_test.source(s);
232 256
  preflow_test.target(t);
233 257

	
234 258
  preflow_test.run();
235 259

	
236 260
  CutMap min_cut3(g);
237 261
  preflow_test.minCutMap(min_cut3);
238 262
  min_cut_value=cutValue(g,min_cut3,cap);
239 263

	
240 264

	
241 265
  check(preflow_test.flowValue() == min_cut_value,
242 266
        "The max flow value or the three min cut values are incorrect.");
243 267

	
268
  initFlowTest();
269
  
244 270
  return 0;
245 271
}
0 comments (0 inline)