lemon/circulation.h
author ladanyi
Wed, 02 Jul 2008 12:37:47 +0000
changeset 2615 2bf1f6e3d5ae
parent 2541 e67ec65747fa
child 2618 6aa6fcaeaea5
permissions -rw-r--r--
Fix bug caused by m4 consuming pairs of square brackets (#108).
alpar@2375
     1
/* -*- C++ -*-
alpar@2375
     2
 *
alpar@2391
     3
 * This file is a part of LEMON, a generic C++ optimization library
alpar@2391
     4
 *
alpar@2553
     5
 * Copyright (C) 2003-2008
alpar@2391
     6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
alpar@2375
     7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
alpar@2375
     8
 *
alpar@2375
     9
 * Permission to use, modify and distribute this software is granted
alpar@2375
    10
 * provided that this copyright notice appears in all copies. For
alpar@2375
    11
 * precise terms see the accompanying LICENSE file.
alpar@2375
    12
 *
alpar@2375
    13
 * This software is provided "AS IS" with no warranty of any kind,
alpar@2375
    14
 * express or implied, and with no claim as to its suitability for any
alpar@2375
    15
 * purpose.
alpar@2375
    16
 *
alpar@2375
    17
 */
alpar@2375
    18
alpar@2375
    19
#ifndef LEMON_CIRCULATION_H
alpar@2375
    20
#define LEMON_CIRCULATION_H
alpar@2375
    21
alpar@2375
    22
#include <lemon/graph_utils.h>
alpar@2375
    23
#include <iostream>
alpar@2375
    24
#include <queue>
alpar@2375
    25
#include <lemon/tolerance.h>
alpar@2375
    26
#include <lemon/elevator.h>
alpar@2375
    27
deba@2376
    28
///\ingroup max_flow
alpar@2375
    29
///\file
alpar@2375
    30
///\brief Push-prelabel algorithm for finding a feasible circulation.
alpar@2375
    31
///
alpar@2375
    32
namespace lemon {
alpar@2375
    33
deba@2526
    34
  /// \brief Default traits class of Circulation class.
deba@2526
    35
  ///
deba@2526
    36
  /// Default traits class of Circulation class.
deba@2526
    37
  /// \param _Graph Graph type.
deba@2526
    38
  /// \param _CapacityMap Type of capacity map.
deba@2526
    39
  template <typename _Graph, typename _LCapMap, 
deba@2526
    40
	    typename _UCapMap, typename _DeltaMap>
deba@2526
    41
  struct CirculationDefaultTraits {
deba@2526
    42
deba@2526
    43
    /// \brief The graph type the algorithm runs on. 
deba@2526
    44
    typedef _Graph Graph;
deba@2526
    45
deba@2526
    46
    /// \brief The type of the map that stores the circulation lower
deba@2526
    47
    /// bound.
deba@2526
    48
    ///
deba@2526
    49
    /// The type of the map that stores the circulation lower bound.
deba@2526
    50
    /// It must meet the \ref concepts::ReadMap "ReadMap" concept.
deba@2526
    51
    typedef _LCapMap LCapMap;
deba@2526
    52
deba@2526
    53
    /// \brief The type of the map that stores the circulation upper
deba@2526
    54
    /// bound.
deba@2526
    55
    ///
deba@2526
    56
    /// The type of the map that stores the circulation upper bound.
deba@2526
    57
    /// It must meet the \ref concepts::ReadMap "ReadMap" concept.
deba@2526
    58
    typedef _UCapMap UCapMap;
deba@2526
    59
deba@2526
    60
    /// \brief The type of the map that stores the upper bound of
deba@2526
    61
    /// node excess.
deba@2526
    62
    ///
deba@2526
    63
    /// The type of the map that stores the lower bound of node
deba@2526
    64
    /// excess. It must meet the \ref concepts::ReadMap "ReadMap"
deba@2526
    65
    /// concept.
deba@2526
    66
    typedef _DeltaMap DeltaMap;
deba@2526
    67
deba@2526
    68
    /// \brief The type of the length of the edges.
deba@2526
    69
    typedef typename DeltaMap::Value Value;
deba@2526
    70
deba@2526
    71
    /// \brief The map type that stores the flow values.
deba@2526
    72
    ///
deba@2526
    73
    /// The map type that stores the flow values. 
deba@2526
    74
    /// It must meet the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
deba@2526
    75
    typedef typename Graph::template EdgeMap<Value> FlowMap;
deba@2526
    76
deba@2526
    77
    /// \brief Instantiates a FlowMap.
deba@2526
    78
    ///
deba@2526
    79
    /// This function instantiates a \ref FlowMap. 
deba@2526
    80
    /// \param graph The graph, to which we would like to define the flow map.
deba@2526
    81
    static FlowMap* createFlowMap(const Graph& graph) {
deba@2526
    82
      return new FlowMap(graph);
deba@2526
    83
    }
deba@2526
    84
deba@2526
    85
    /// \brief The eleavator type used by Circulation algorithm.
deba@2526
    86
    /// 
deba@2526
    87
    /// The elevator type used by Circulation algorithm.
deba@2526
    88
    ///
deba@2526
    89
    /// \sa Elevator
deba@2526
    90
    /// \sa LinkedElevator
deba@2526
    91
    typedef Elevator<Graph, typename Graph::Node> Elevator;
deba@2526
    92
    
deba@2526
    93
    /// \brief Instantiates an Elevator.
deba@2526
    94
    ///
deba@2526
    95
    /// This function instantiates a \ref Elevator. 
deba@2526
    96
    /// \param graph The graph, to which we would like to define the elevator.
deba@2526
    97
    /// \param max_level The maximum level of the elevator.
deba@2526
    98
    static Elevator* createElevator(const Graph& graph, int max_level) {
deba@2526
    99
      return new Elevator(graph, max_level);
deba@2526
   100
    }
deba@2526
   101
deba@2526
   102
    /// \brief The tolerance used by the algorithm
deba@2526
   103
    ///
deba@2526
   104
    /// The tolerance used by the algorithm to handle inexact computation.
deba@2526
   105
    typedef Tolerance<Value> Tolerance;
deba@2526
   106
deba@2526
   107
  };
deba@2526
   108
  
deba@2526
   109
  ///Push-relabel algorithm for the Network Circulation Problem.
alpar@2375
   110
  
deba@2378
   111
  ///\ingroup max_flow
deba@2526
   112
  ///This class implements a push-relabel algorithm
alpar@2375
   113
  ///for the Network Circulation Problem.
alpar@2375
   114
  ///The exact formulation of this problem is the following.
alpar@2450
   115
  /// \f[\sum_{e\in\rho(v)}x(e)-\sum_{e\in\delta(v)}x(e)\leq -delta(v)\quad \forall v\in V \f]
alpar@2375
   116
  /// \f[ lo(e)\leq x(e) \leq up(e) \quad \forall e\in E \f]
alpar@2375
   117
  ///
deba@2526
   118
  template<class _Graph,
deba@2526
   119
	   class _LCapMap=typename _Graph::template EdgeMap<int>,
deba@2526
   120
	   class _UCapMap=_LCapMap,
deba@2526
   121
	   class _DeltaMap=typename _Graph::template NodeMap<
deba@2526
   122
	     typename _UCapMap::Value>,
deba@2526
   123
	   class _Traits=CirculationDefaultTraits<_Graph, _LCapMap, 
deba@2526
   124
						  _UCapMap, _DeltaMap> >
alpar@2375
   125
  class Circulation {
deba@2526
   126
deba@2526
   127
    typedef _Traits Traits;
deba@2526
   128
    typedef typename Traits::Graph Graph;
deba@2526
   129
    GRAPH_TYPEDEFS(typename Graph);
deba@2526
   130
deba@2526
   131
    typedef typename Traits::Value Value;
deba@2526
   132
deba@2526
   133
    typedef typename Traits::LCapMap LCapMap;
deba@2526
   134
    typedef typename Traits::UCapMap UCapMap;
deba@2526
   135
    typedef typename Traits::DeltaMap DeltaMap;
deba@2526
   136
    typedef typename Traits::FlowMap FlowMap;
deba@2526
   137
    typedef typename Traits::Elevator Elevator;
deba@2526
   138
    typedef typename Traits::Tolerance Tolerance;
deba@2526
   139
deba@2526
   140
    typedef typename Graph::template NodeMap<Value> ExcessMap;
alpar@2375
   141
alpar@2375
   142
    const Graph &_g;
alpar@2375
   143
    int _node_num;
alpar@2375
   144
deba@2526
   145
    const LCapMap *_lo;
deba@2526
   146
    const UCapMap *_up;
deba@2526
   147
    const DeltaMap *_delta;
deba@2526
   148
deba@2526
   149
    FlowMap *_flow;
deba@2526
   150
    bool _local_flow;
deba@2526
   151
deba@2526
   152
    Elevator* _level;
deba@2526
   153
    bool _local_level;
deba@2526
   154
deba@2526
   155
    ExcessMap* _excess;
deba@2526
   156
deba@2526
   157
    Tolerance _tol;
deba@2526
   158
    int _el;
alpar@2375
   159
alpar@2375
   160
  public:
deba@2526
   161
deba@2526
   162
    typedef Circulation Create;
deba@2526
   163
deba@2526
   164
    ///\name Named template parameters
deba@2526
   165
deba@2526
   166
    ///@{
deba@2526
   167
deba@2526
   168
    template <typename _FlowMap>
deba@2526
   169
    struct DefFlowMapTraits : public Traits {
deba@2526
   170
      typedef _FlowMap FlowMap;
deba@2526
   171
      static FlowMap *createFlowMap(const Graph&) {
deba@2526
   172
	throw UninitializedParameter();
deba@2526
   173
      }
deba@2526
   174
    };
deba@2526
   175
deba@2526
   176
    /// \brief \ref named-templ-param "Named parameter" for setting
deba@2526
   177
    /// FlowMap type
deba@2526
   178
    ///
deba@2526
   179
    /// \ref named-templ-param "Named parameter" for setting FlowMap
deba@2526
   180
    /// type
deba@2526
   181
    template <typename _FlowMap>
deba@2526
   182
    struct DefFlowMap 
deba@2526
   183
      : public Circulation<Graph, LCapMap, UCapMap, DeltaMap, 
deba@2526
   184
			   DefFlowMapTraits<_FlowMap> > {
deba@2526
   185
      typedef Circulation<Graph, LCapMap, UCapMap, DeltaMap, 
deba@2526
   186
			  DefFlowMapTraits<_FlowMap> > Create;
deba@2526
   187
    };
deba@2526
   188
deba@2526
   189
    template <typename _Elevator>
deba@2526
   190
    struct DefElevatorTraits : public Traits {
deba@2526
   191
      typedef _Elevator Elevator;
deba@2526
   192
      static Elevator *createElevator(const Graph&, int) {
deba@2526
   193
	throw UninitializedParameter();
deba@2526
   194
      }
deba@2526
   195
    };
deba@2526
   196
deba@2526
   197
    /// \brief \ref named-templ-param "Named parameter" for setting
deba@2526
   198
    /// Elevator type
deba@2526
   199
    ///
deba@2526
   200
    /// \ref named-templ-param "Named parameter" for setting Elevator
deba@2526
   201
    /// type
deba@2526
   202
    template <typename _Elevator>
deba@2526
   203
    struct DefElevator 
deba@2526
   204
      : public Circulation<Graph, LCapMap, UCapMap, DeltaMap, 
deba@2526
   205
			   DefElevatorTraits<_Elevator> > {
deba@2526
   206
      typedef Circulation<Graph, LCapMap, UCapMap, DeltaMap,
deba@2526
   207
			  DefElevatorTraits<_Elevator> > Create;
deba@2526
   208
    };
deba@2526
   209
deba@2526
   210
    template <typename _Elevator>
deba@2526
   211
    struct DefStandardElevatorTraits : public Traits {
deba@2526
   212
      typedef _Elevator Elevator;
deba@2526
   213
      static Elevator *createElevator(const Graph& graph, int max_level) {
deba@2526
   214
	return new Elevator(graph, max_level);
deba@2526
   215
      }
deba@2526
   216
    };
deba@2526
   217
deba@2526
   218
    /// \brief \ref named-templ-param "Named parameter" for setting
deba@2526
   219
    /// Elevator type
deba@2526
   220
    ///
deba@2526
   221
    /// \ref named-templ-param "Named parameter" for setting Elevator
deba@2526
   222
    /// type. The Elevator should be standard constructor interface, ie.
deba@2526
   223
    /// the graph and the maximum level should be passed to it.
deba@2526
   224
    template <typename _Elevator>
deba@2526
   225
    struct DefStandardElevator 
deba@2526
   226
      : public Circulation<Graph, LCapMap, UCapMap, DeltaMap, 
deba@2526
   227
		       DefStandardElevatorTraits<_Elevator> > {
deba@2526
   228
      typedef Circulation<Graph, LCapMap, UCapMap, DeltaMap,
deba@2526
   229
		      DefStandardElevatorTraits<_Elevator> > Create;
deba@2526
   230
    };    
deba@2526
   231
deba@2526
   232
    /// @}
deba@2526
   233
deba@2527
   234
  protected:
deba@2527
   235
deba@2527
   236
    Circulation() {}
deba@2527
   237
  
deba@2527
   238
  public:
deba@2527
   239
deba@2526
   240
    /// The constructor of the class.
deba@2526
   241
deba@2526
   242
    /// The constructor of the class. 
deba@2526
   243
    /// \param g The directed graph the algorithm runs on. 
deba@2526
   244
    /// \param lo The lower bound capacity of the edges. 
deba@2526
   245
    /// \param up The upper bound capacity of the edges.
deba@2526
   246
    /// \param delta The lower bound on node excess.
deba@2526
   247
    Circulation(const Graph &g,const LCapMap &lo,
deba@2526
   248
		const UCapMap &up,const DeltaMap &delta) 
deba@2526
   249
      : _g(g), _node_num(),
deba@2526
   250
	_lo(&lo),_up(&up),_delta(&delta),_flow(0),_local_flow(false),
deba@2526
   251
	_level(0), _local_level(false), _excess(0), _el() {}
deba@2526
   252
deba@2526
   253
    /// Destrcutor.
deba@2526
   254
    ~Circulation() {
deba@2526
   255
      destroyStructures();
alpar@2375
   256
    }
deba@2526
   257
alpar@2375
   258
  private:
alpar@2375
   259
deba@2526
   260
    void createStructures() {
deba@2526
   261
      _node_num = _el = countNodes(_g);
deba@2526
   262
deba@2526
   263
      if (!_flow) {
deba@2526
   264
	_flow = Traits::createFlowMap(_g);
deba@2526
   265
	_local_flow = true;
deba@2526
   266
      }
deba@2526
   267
      if (!_level) {
deba@2526
   268
	_level = Traits::createElevator(_g, _node_num);
deba@2526
   269
	_local_level = true;
deba@2526
   270
      }
deba@2526
   271
      if (!_excess) {
deba@2526
   272
	_excess = new ExcessMap(_g);
deba@2526
   273
      }
alpar@2375
   274
    }
alpar@2375
   275
deba@2526
   276
    void destroyStructures() {
deba@2526
   277
      if (_local_flow) {
deba@2526
   278
	delete _flow;
deba@2526
   279
      }
deba@2526
   280
      if (_local_level) {
deba@2526
   281
	delete _level;
deba@2526
   282
      }
deba@2526
   283
      if (_excess) {
deba@2526
   284
	delete _excess;
deba@2526
   285
      }
alpar@2375
   286
    }
alpar@2375
   287
alpar@2375
   288
  public:
deba@2526
   289
deba@2526
   290
    /// Sets the lower bound capacity map.
deba@2526
   291
deba@2526
   292
    /// Sets the lower bound capacity map.
deba@2526
   293
    /// \return \c (*this)
deba@2526
   294
    Circulation& lowerCapMap(const LCapMap& map) {
deba@2526
   295
      _lo = &map;
deba@2526
   296
      return *this;
deba@2526
   297
    }
deba@2526
   298
deba@2526
   299
    /// Sets the upper bound capacity map.
deba@2526
   300
deba@2526
   301
    /// Sets the upper bound capacity map.
deba@2526
   302
    /// \return \c (*this)
deba@2526
   303
    Circulation& upperCapMap(const LCapMap& map) {
deba@2526
   304
      _up = &map;
deba@2526
   305
      return *this;
deba@2526
   306
    }
deba@2526
   307
deba@2526
   308
    /// Sets the lower bound map on excess.
deba@2526
   309
deba@2526
   310
    /// Sets the lower bound map on excess.
deba@2526
   311
    /// \return \c (*this)
deba@2526
   312
    Circulation& deltaMap(const DeltaMap& map) {
deba@2526
   313
      _delta = &map;
deba@2526
   314
      return *this;
deba@2526
   315
    }
deba@2526
   316
deba@2526
   317
    /// Sets the flow map.
deba@2526
   318
deba@2526
   319
    /// Sets the flow map.
deba@2526
   320
    /// \return \c (*this)
deba@2526
   321
    Circulation& flowMap(FlowMap& map) {
deba@2526
   322
      if (_local_flow) {
deba@2526
   323
	delete _flow;
deba@2526
   324
	_local_flow = false;
deba@2526
   325
      }
deba@2526
   326
      _flow = &map;
deba@2526
   327
      return *this;
deba@2526
   328
    }
deba@2526
   329
deba@2526
   330
    /// Returns the flow map.
deba@2526
   331
deba@2526
   332
    /// \return The flow map.
deba@2526
   333
    ///
deba@2526
   334
    const FlowMap& flowMap() {
deba@2526
   335
      return *_flow;
deba@2526
   336
    }
deba@2526
   337
deba@2526
   338
    /// Sets the elevator.
deba@2526
   339
deba@2526
   340
    /// Sets the elevator.
deba@2526
   341
    /// \return \c (*this)
deba@2526
   342
    Circulation& elevator(Elevator& elevator) {
deba@2526
   343
      if (_local_level) {
deba@2526
   344
	delete _level;
deba@2526
   345
	_local_level = false;
deba@2526
   346
      }
deba@2526
   347
      _level = &elevator;
deba@2526
   348
      return *this;
deba@2526
   349
    }
deba@2526
   350
deba@2526
   351
    /// Returns the elevator.
deba@2526
   352
deba@2526
   353
    /// \return The elevator.
deba@2526
   354
    ///
deba@2526
   355
    const Elevator& elevator() {
deba@2526
   356
      return *_level;
deba@2526
   357
    }
deba@2526
   358
    
deba@2526
   359
    /// Sets the tolerance used by algorithm.
deba@2526
   360
deba@2526
   361
    /// Sets the tolerance used by algorithm.
deba@2526
   362
    ///
deba@2526
   363
    Circulation& tolerance(const Tolerance& tolerance) const {
deba@2526
   364
      _tol = tolerance;
deba@2526
   365
      return *this;
deba@2526
   366
    } 
deba@2526
   367
deba@2526
   368
    /// Returns the tolerance used by algorithm.
deba@2526
   369
deba@2526
   370
    /// Returns the tolerance used by algorithm.
deba@2526
   371
    ///
deba@2526
   372
    const Tolerance& tolerance() const {
deba@2526
   373
      return tolerance;
deba@2526
   374
    } 
deba@2526
   375
    
kpeter@2533
   376
    /// \name Execution control
kpeter@2533
   377
    /// The simplest way to execute the algorithm is to use one of the
kpeter@2533
   378
    /// member functions called \c run().
deba@2526
   379
    /// \n 
deba@2526
   380
    /// If you need more control on initial solution or execution then
deba@2526
   381
    /// you have to call one \ref init() function and then the start()
deba@2526
   382
    /// function.
deba@2526
   383
    
deba@2526
   384
    ///@{
deba@2526
   385
  
deba@2526
   386
    /// Initializes the internal data structures.
deba@2526
   387
deba@2526
   388
    /// Initializes the internal data structures. This function sets
deba@2526
   389
    /// all flow values to the lower bound.  
deba@2526
   390
    /// \return This function returns false if the initialization
deba@2526
   391
    /// process found a barrier.
deba@2526
   392
    void init() 
deba@2526
   393
    {
deba@2526
   394
      createStructures();
deba@2526
   395
deba@2526
   396
      for(NodeIt n(_g);n!=INVALID;++n) {
deba@2526
   397
	_excess->set(n, (*_delta)[n]);
deba@2526
   398
      }
deba@2526
   399
     
deba@2526
   400
      for (EdgeIt e(_g);e!=INVALID;++e) {
deba@2526
   401
	_flow->set(e, (*_lo)[e]);
deba@2526
   402
	_excess->set(_g.target(e), (*_excess)[_g.target(e)] + (*_flow)[e]);
deba@2526
   403
	_excess->set(_g.source(e), (*_excess)[_g.source(e)] - (*_flow)[e]);
deba@2526
   404
      }
deba@2526
   405
deba@2526
   406
      // global relabeling tested, but in general case it provides
deba@2526
   407
      // worse performance for random graphs
deba@2526
   408
      _level->initStart();
deba@2526
   409
      for(NodeIt n(_g);n!=INVALID;++n)
deba@2526
   410
	_level->initAddItem(n);
deba@2526
   411
      _level->initFinish();
deba@2526
   412
      for(NodeIt n(_g);n!=INVALID;++n)
deba@2526
   413
	if(_tol.positive((*_excess)[n]))
deba@2526
   414
	  _level->activate(n);
deba@2526
   415
    }
deba@2526
   416
deba@2526
   417
    /// Initializes the internal data structures.
deba@2526
   418
deba@2526
   419
    /// Initializes the internal data structures. This functions uses
deba@2526
   420
    /// greedy approach to construct the initial solution. 
deba@2526
   421
    void greedyInit() 
deba@2526
   422
    {
deba@2526
   423
      createStructures();
deba@2526
   424
     
deba@2526
   425
      for(NodeIt n(_g);n!=INVALID;++n) {
deba@2526
   426
	_excess->set(n, (*_delta)[n]);
deba@2526
   427
      }
deba@2526
   428
     
deba@2526
   429
      for (EdgeIt e(_g);e!=INVALID;++e) {
deba@2526
   430
	if (!_tol.positive((*_excess)[_g.target(e)] + (*_up)[e])) {
deba@2526
   431
	  _flow->set(e, (*_up)[e]);
deba@2526
   432
	  _excess->set(_g.target(e), (*_excess)[_g.target(e)] + (*_up)[e]);
deba@2526
   433
	  _excess->set(_g.source(e), (*_excess)[_g.source(e)] - (*_up)[e]);
deba@2526
   434
	} else if (_tol.positive((*_excess)[_g.target(e)] + (*_lo)[e])) {
deba@2526
   435
	  _flow->set(e, (*_lo)[e]);
deba@2541
   436
	  _excess->set(_g.target(e), (*_excess)[_g.target(e)] + (*_lo)[e]);
deba@2541
   437
	  _excess->set(_g.source(e), (*_excess)[_g.source(e)] - (*_lo)[e]);
deba@2526
   438
	} else {
deba@2526
   439
	  Value fc = -(*_excess)[_g.target(e)];
deba@2526
   440
	  _flow->set(e, fc);
deba@2526
   441
	  _excess->set(_g.target(e), 0);
deba@2526
   442
	  _excess->set(_g.source(e), (*_excess)[_g.source(e)] - fc);
deba@2526
   443
	}
deba@2526
   444
      }
deba@2526
   445
     
deba@2526
   446
      _level->initStart();
deba@2526
   447
      for(NodeIt n(_g);n!=INVALID;++n)
deba@2526
   448
	_level->initAddItem(n);
deba@2526
   449
      _level->initFinish();
deba@2526
   450
      for(NodeIt n(_g);n!=INVALID;++n)
deba@2526
   451
	if(_tol.positive((*_excess)[n]))
deba@2526
   452
	  _level->activate(n);
deba@2526
   453
    }
deba@2526
   454
deba@2526
   455
    ///Starts the algorithm
deba@2526
   456
deba@2526
   457
    ///This function starts the algorithm.
deba@2526
   458
    ///\return This function returns true if it found a feasible circulation.
deba@2526
   459
    ///
deba@2526
   460
    ///\sa barrier()
deba@2526
   461
    bool start() 
deba@2526
   462
    {
deba@2526
   463
      
deba@2526
   464
      Node act;
deba@2526
   465
      Node bact=INVALID;
deba@2526
   466
      Node last_activated=INVALID;
deba@2526
   467
      while((act=_level->highestActive())!=INVALID) {
deba@2526
   468
	int actlevel=(*_level)[act];
deba@2526
   469
	int mlevel=_node_num;
deba@2526
   470
	Value exc=(*_excess)[act];
deba@2541
   471
deba@2526
   472
	for(OutEdgeIt e(_g,act);e!=INVALID; ++e) {
deba@2526
   473
	  Node v = _g.target(e);
deba@2526
   474
	  Value fc=(*_up)[e]-(*_flow)[e];
deba@2526
   475
	  if(!_tol.positive(fc)) continue;
deba@2526
   476
	  if((*_level)[v]<actlevel) {
deba@2526
   477
	    if(!_tol.less(fc, exc)) {
deba@2526
   478
	      _flow->set(e, (*_flow)[e] + exc);
deba@2526
   479
	      _excess->set(v, (*_excess)[v] + exc);
deba@2526
   480
	      if(!_level->active(v) && _tol.positive((*_excess)[v]))
deba@2526
   481
		_level->activate(v);
deba@2526
   482
	      _excess->set(act,0);
deba@2526
   483
	      _level->deactivate(act);
deba@2526
   484
	      goto next_l;
deba@2526
   485
	    }
deba@2526
   486
	    else {
deba@2526
   487
	      _flow->set(e, (*_up)[e]);
deba@2541
   488
	      _excess->set(v, (*_excess)[v] + fc);
deba@2526
   489
	      if(!_level->active(v) && _tol.positive((*_excess)[v]))
deba@2526
   490
		_level->activate(v);
deba@2526
   491
	      exc-=fc;
deba@2526
   492
	    }
deba@2526
   493
	  } 
deba@2526
   494
	  else if((*_level)[v]<mlevel) mlevel=(*_level)[v];
deba@2526
   495
	}
deba@2526
   496
	for(InEdgeIt e(_g,act);e!=INVALID; ++e) {
deba@2526
   497
	  Node v = _g.source(e);
deba@2526
   498
	  Value fc=(*_flow)[e]-(*_lo)[e];
deba@2526
   499
	  if(!_tol.positive(fc)) continue;
deba@2526
   500
	  if((*_level)[v]<actlevel) {
deba@2526
   501
	    if(!_tol.less(fc, exc)) {
deba@2526
   502
	      _flow->set(e, (*_flow)[e] - exc);
deba@2526
   503
	      _excess->set(v, (*_excess)[v] + exc);
deba@2526
   504
	      if(!_level->active(v) && _tol.positive((*_excess)[v]))
deba@2526
   505
		_level->activate(v);
deba@2526
   506
	      _excess->set(act,0);
deba@2526
   507
	      _level->deactivate(act);
deba@2526
   508
	      goto next_l;
deba@2526
   509
	    }
deba@2526
   510
	    else {
deba@2526
   511
	      _flow->set(e, (*_lo)[e]);
deba@2526
   512
	      _excess->set(v, (*_excess)[v] + fc);
deba@2526
   513
	      if(!_level->active(v) && _tol.positive((*_excess)[v]))
deba@2526
   514
		_level->activate(v);
deba@2526
   515
	      exc-=fc;
deba@2526
   516
	    }
deba@2526
   517
	  } 
deba@2526
   518
	  else if((*_level)[v]<mlevel) mlevel=(*_level)[v];
deba@2526
   519
	}
deba@2526
   520
   
deba@2526
   521
	_excess->set(act, exc);
deba@2526
   522
	if(!_tol.positive(exc)) _level->deactivate(act);
deba@2526
   523
	else if(mlevel==_node_num) {
deba@2526
   524
	  _level->liftHighestActiveToTop();
deba@2526
   525
	  _el = _node_num;
deba@2526
   526
	  return false;
deba@2526
   527
	}
deba@2526
   528
	else {
deba@2526
   529
	  _level->liftHighestActive(mlevel+1);
deba@2526
   530
	  if(_level->onLevel(actlevel)==0) {
deba@2526
   531
	    _el = actlevel;
deba@2526
   532
	    return false;
deba@2526
   533
	  }
deba@2526
   534
	}
deba@2526
   535
      next_l:
deba@2526
   536
	;
deba@2526
   537
      }
deba@2526
   538
      return true;
deba@2526
   539
    }
deba@2526
   540
deba@2526
   541
    /// Runs the circulation algorithm.  
deba@2526
   542
deba@2526
   543
    /// Runs the circulation algorithm.
deba@2526
   544
    /// \note fc.run() is just a shortcut of the following code.
deba@2526
   545
    /// \code
deba@2526
   546
    ///   fc.greedyInit();
deba@2526
   547
    ///   return fc.start();
deba@2526
   548
    /// \endcode
deba@2526
   549
    bool run() {
deba@2526
   550
      greedyInit();
deba@2526
   551
      return start();
deba@2526
   552
    }
deba@2526
   553
deba@2526
   554
    /// @}
deba@2526
   555
deba@2526
   556
    /// \name Query Functions
deba@2526
   557
    /// The result of the %Circulation algorithm can be obtained using
deba@2526
   558
    /// these functions.
deba@2526
   559
    /// \n
deba@2526
   560
    /// Before the use of these functions,
deba@2526
   561
    /// either run() or start() must be called.
deba@2526
   562
    
deba@2526
   563
    ///@{
deba@2526
   564
    
deba@2526
   565
    ///Returns a barrier
deba@2526
   566
    
deba@2526
   567
    ///Barrier is a set \e B of nodes for which
deba@2526
   568
    /// \f[ \sum_{v\in B}-delta(v)<\sum_{e\in\rho(B)}lo(e)-\sum_{e\in\delta(B)}up(e) \f]
deba@2526
   569
    ///holds. The existence of a set with this property prooves that a feasible
deba@2526
   570
    ///flow cannot exists.
deba@2526
   571
    ///\sa checkBarrier()
deba@2526
   572
    ///\sa run()
deba@2526
   573
    template<class GT>
deba@2526
   574
    void barrierMap(GT &bar) 
deba@2526
   575
    {
deba@2526
   576
      for(NodeIt n(_g);n!=INVALID;++n)
deba@2526
   577
	bar.set(n, (*_level)[n] >= _el);
deba@2526
   578
    }  
deba@2526
   579
deba@2526
   580
    ///Returns true if the node is in the barrier
deba@2526
   581
deba@2526
   582
    ///Returns true if the node is in the barrier
deba@2526
   583
    ///\sa barrierMap()
deba@2526
   584
    bool barrier(const Node& node) 
deba@2526
   585
    {
deba@2526
   586
      return (*_level)[node] >= _el;
deba@2526
   587
    }  
deba@2526
   588
deba@2526
   589
    /// \brief Returns the flow on the edge.
deba@2526
   590
    ///
deba@2526
   591
    /// Sets the \c flowMap to the flow on the edges. This method can
deba@2526
   592
    /// be called after the second phase of algorithm.
deba@2526
   593
    Value flow(const Edge& edge) const {
deba@2526
   594
      return (*_flow)[edge];
deba@2526
   595
    }
deba@2526
   596
deba@2526
   597
    /// @}
deba@2526
   598
deba@2526
   599
    /// \name Checker Functions
deba@2526
   600
    /// The feasibility  of the results can be checked using
deba@2526
   601
    /// these functions.
deba@2526
   602
    /// \n
deba@2526
   603
    /// Before the use of these functions,
deba@2526
   604
    /// either run() or start() must be called.
deba@2526
   605
    
deba@2526
   606
    ///@{
deba@2526
   607
deba@2526
   608
    ///Check if the  \c flow is a feasible circulation
deba@2526
   609
    bool checkFlow() {
alpar@2375
   610
      for(EdgeIt e(_g);e!=INVALID;++e)
deba@2526
   611
	if((*_flow)[e]<(*_lo)[e]||(*_flow)[e]>(*_up)[e]) return false;
alpar@2375
   612
      for(NodeIt n(_g);n!=INVALID;++n)
alpar@2375
   613
	{
deba@2526
   614
	  Value dif=-(*_delta)[n];
deba@2526
   615
	  for(InEdgeIt e(_g,n);e!=INVALID;++e) dif-=(*_flow)[e];
deba@2526
   616
	  for(OutEdgeIt e(_g,n);e!=INVALID;++e) dif+=(*_flow)[e];
alpar@2375
   617
	  if(_tol.negative(dif)) return false;
alpar@2375
   618
	}
alpar@2375
   619
      return true;
deba@2526
   620
    }
alpar@2375
   621
alpar@2408
   622
    ///Check whether or not the last execution provides a barrier
alpar@2375
   623
alpar@2408
   624
    ///Check whether or not the last execution provides a barrier
alpar@2375
   625
    ///\sa barrier()
alpar@2375
   626
    bool checkBarrier() 
alpar@2375
   627
    {
deba@2526
   628
      Value delta=0;
deba@2526
   629
      for(NodeIt n(_g);n!=INVALID;++n)
deba@2526
   630
	if(barrier(n))
deba@2526
   631
	  delta-=(*_delta)[n];
deba@2526
   632
      for(EdgeIt e(_g);e!=INVALID;++e)
deba@2526
   633
	{
deba@2526
   634
	  Node s=_g.source(e);
deba@2526
   635
	  Node t=_g.target(e);
deba@2526
   636
	  if(barrier(s)&&!barrier(t)) delta+=(*_up)[e];
deba@2526
   637
	  else if(barrier(t)&&!barrier(s)) delta-=(*_lo)[e];
deba@2526
   638
	}
deba@2526
   639
      return _tol.negative(delta);
alpar@2375
   640
    }
alpar@2375
   641
deba@2526
   642
    /// @}
alpar@2375
   643
alpar@2375
   644
  };
alpar@2375
   645
  
alpar@2375
   646
}
alpar@2375
   647
alpar@2375
   648
#endif