lemon/network_simplex.h
author kpeter
Tue, 05 Feb 2008 11:10:08 +0000
changeset 2561 ec5c56f0501e
parent 2553 bfced05fa852
child 2569 12c2c5c4330b
permissions -rw-r--r--
Translate Hungarian varible names and improve messages in dim_test.cc.
deba@2440
     1
/* -*- C++ -*-
deba@2440
     2
 *
deba@2440
     3
 * This file is a part of LEMON, a generic C++ optimization library
deba@2440
     4
 *
alpar@2553
     5
 * Copyright (C) 2003-2008
deba@2440
     6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
deba@2440
     7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
deba@2440
     8
 *
deba@2440
     9
 * Permission to use, modify and distribute this software is granted
deba@2440
    10
 * provided that this copyright notice appears in all copies. For
deba@2440
    11
 * precise terms see the accompanying LICENSE file.
deba@2440
    12
 *
deba@2440
    13
 * This software is provided "AS IS" with no warranty of any kind,
deba@2440
    14
 * express or implied, and with no claim as to its suitability for any
deba@2440
    15
 * purpose.
deba@2440
    16
 *
deba@2440
    17
 */
deba@2440
    18
deba@2440
    19
#ifndef LEMON_NETWORK_SIMPLEX_H
deba@2440
    20
#define LEMON_NETWORK_SIMPLEX_H
deba@2440
    21
deba@2440
    22
/// \ingroup min_cost_flow
deba@2440
    23
///
deba@2440
    24
/// \file
kpeter@2556
    25
/// \brief The network simplex algorithm for finding a minimum cost flow.
deba@2440
    26
deba@2440
    27
#include <limits>
kpeter@2509
    28
#include <lemon/graph_adaptor.h>
kpeter@2509
    29
#include <lemon/graph_utils.h>
deba@2440
    30
#include <lemon/smart_graph.h>
deba@2440
    31
deba@2440
    32
/// \brief The pivot rule used in the algorithm.
deba@2440
    33
//#define FIRST_ELIGIBLE_PIVOT
deba@2440
    34
//#define BEST_ELIGIBLE_PIVOT
deba@2444
    35
#define EDGE_BLOCK_PIVOT
deba@2440
    36
//#define CANDIDATE_LIST_PIVOT
deba@2440
    37
//#define SORTED_LIST_PIVOT
deba@2440
    38
deba@2444
    39
//#define _DEBUG_ITER_
deba@2444
    40
deba@2444
    41
kpeter@2556
    42
// State constant for edges at their lower bounds.
kpeter@2556
    43
#define LOWER   1
kpeter@2556
    44
// State constant for edges in the spanning tree.
kpeter@2556
    45
#define TREE    0
kpeter@2556
    46
// State constant for edges at their upper bounds.
kpeter@2556
    47
#define UPPER   -1
deba@2440
    48
deba@2440
    49
#ifdef EDGE_BLOCK_PIVOT
kpeter@2471
    50
  #include <cmath>
kpeter@2556
    51
  #define MIN_BLOCK_SIZE        10
deba@2440
    52
#endif
deba@2440
    53
deba@2440
    54
#ifdef CANDIDATE_LIST_PIVOT
kpeter@2471
    55
  #include <vector>
kpeter@2556
    56
  #define LIST_LENGTH_DIV       50
kpeter@2556
    57
  #define MINOR_LIMIT_DIV       200
deba@2440
    58
#endif
deba@2440
    59
deba@2440
    60
#ifdef SORTED_LIST_PIVOT
kpeter@2471
    61
  #include <vector>
deba@2440
    62
  #include <algorithm>
kpeter@2471
    63
  #define LIST_LENGTH_DIV       100
kpeter@2556
    64
  #define LOWER_DIV             4
deba@2440
    65
#endif
deba@2440
    66
deba@2440
    67
namespace lemon {
deba@2440
    68
deba@2440
    69
  /// \addtogroup min_cost_flow
deba@2440
    70
  /// @{
deba@2440
    71
deba@2440
    72
  /// \brief Implementation of the network simplex algorithm for
deba@2440
    73
  /// finding a minimum cost flow.
deba@2440
    74
  ///
kpeter@2556
    75
  /// \ref NetworkSimplex implements the network simplex algorithm for
kpeter@2556
    76
  /// finding a minimum cost flow.
deba@2440
    77
  ///
deba@2440
    78
  /// \param Graph The directed graph type the algorithm runs on.
deba@2440
    79
  /// \param LowerMap The type of the lower bound map.
deba@2440
    80
  /// \param CapacityMap The type of the capacity (upper bound) map.
deba@2440
    81
  /// \param CostMap The type of the cost (length) map.
deba@2440
    82
  /// \param SupplyMap The type of the supply map.
deba@2440
    83
  ///
deba@2440
    84
  /// \warning
kpeter@2556
    85
  /// - Edge capacities and costs should be non-negative integers.
kpeter@2556
    86
  ///   However \c CostMap::Value should be signed type.
kpeter@2509
    87
  /// - Supply values should be signed integers.
deba@2440
    88
  /// - \c LowerMap::Value must be convertible to
kpeter@2556
    89
  ///   \c CapacityMap::Value and \c CapacityMap::Value must be
kpeter@2556
    90
  ///   convertible to \c SupplyMap::Value.
deba@2440
    91
  ///
deba@2440
    92
  /// \author Peter Kovacs
deba@2440
    93
kpeter@2533
    94
  template < typename Graph,
kpeter@2533
    95
             typename LowerMap = typename Graph::template EdgeMap<int>,
kpeter@2533
    96
             typename CapacityMap = LowerMap,
kpeter@2533
    97
             typename CostMap = typename Graph::template EdgeMap<int>,
kpeter@2533
    98
             typename SupplyMap = typename Graph::template NodeMap
kpeter@2533
    99
                                  <typename CapacityMap::Value> >
deba@2440
   100
  class NetworkSimplex
deba@2440
   101
  {
deba@2440
   102
    typedef typename LowerMap::Value Lower;
deba@2440
   103
    typedef typename CapacityMap::Value Capacity;
deba@2440
   104
    typedef typename CostMap::Value Cost;
deba@2440
   105
    typedef typename SupplyMap::Value Supply;
deba@2440
   106
deba@2440
   107
    typedef SmartGraph SGraph;
kpeter@2556
   108
    GRAPH_TYPEDEFS(typename SGraph);
deba@2440
   109
deba@2440
   110
    typedef typename SGraph::template EdgeMap<Lower> SLowerMap;
deba@2440
   111
    typedef typename SGraph::template EdgeMap<Capacity> SCapacityMap;
deba@2440
   112
    typedef typename SGraph::template EdgeMap<Cost> SCostMap;
deba@2440
   113
    typedef typename SGraph::template NodeMap<Supply> SSupplyMap;
deba@2440
   114
    typedef typename SGraph::template NodeMap<Cost> SPotentialMap;
deba@2440
   115
deba@2440
   116
    typedef typename SGraph::template NodeMap<int> IntNodeMap;
deba@2440
   117
    typedef typename SGraph::template NodeMap<bool> BoolNodeMap;
deba@2440
   118
    typedef typename SGraph::template NodeMap<Node> NodeNodeMap;
deba@2440
   119
    typedef typename SGraph::template NodeMap<Edge> EdgeNodeMap;
deba@2440
   120
    typedef typename SGraph::template EdgeMap<int> IntEdgeMap;
deba@2440
   121
deba@2440
   122
    typedef typename Graph::template NodeMap<Node> NodeRefMap;
deba@2440
   123
    typedef typename Graph::template EdgeMap<Edge> EdgeRefMap;
deba@2440
   124
deba@2440
   125
  public:
deba@2440
   126
kpeter@2556
   127
    /// The type of the flow map.
deba@2440
   128
    typedef typename Graph::template EdgeMap<Capacity> FlowMap;
kpeter@2556
   129
    /// The type of the potential map.
deba@2440
   130
    typedef typename Graph::template NodeMap<Cost> PotentialMap;
deba@2440
   131
deba@2440
   132
  protected:
deba@2440
   133
kpeter@2556
   134
    /// Map adaptor class for handling reduced edge costs.
deba@2440
   135
    class ReducedCostMap : public MapBase<Edge, Cost>
deba@2440
   136
    {
deba@2440
   137
    private:
deba@2440
   138
deba@2440
   139
      const SGraph &gr;
deba@2440
   140
      const SCostMap &cost_map;
deba@2440
   141
      const SPotentialMap &pot_map;
deba@2440
   142
deba@2440
   143
    public:
deba@2440
   144
deba@2440
   145
      ReducedCostMap( const SGraph &_gr,
kpeter@2556
   146
                      const SCostMap &_cm,
kpeter@2556
   147
                      const SPotentialMap &_pm ) :
kpeter@2556
   148
        gr(_gr), cost_map(_cm), pot_map(_pm) {}
deba@2440
   149
kpeter@2509
   150
      Cost operator[](const Edge &e) const {
kpeter@2556
   151
        return cost_map[e] - pot_map[gr.source(e)] + pot_map[gr.target(e)];
deba@2440
   152
      }
deba@2440
   153
deba@2440
   154
    }; //class ReducedCostMap
deba@2440
   155
deba@2440
   156
  protected:
deba@2440
   157
kpeter@2556
   158
    /// The directed graph the algorithm runs on.
deba@2440
   159
    SGraph graph;
kpeter@2556
   160
    /// The original graph.
deba@2440
   161
    const Graph &graph_ref;
kpeter@2556
   162
    /// The original lower bound map.
deba@2440
   163
    const LowerMap *lower;
kpeter@2556
   164
    /// The capacity map.
deba@2440
   165
    SCapacityMap capacity;
kpeter@2556
   166
    /// The cost map.
deba@2440
   167
    SCostMap cost;
kpeter@2556
   168
    /// The supply map.
deba@2440
   169
    SSupplyMap supply;
kpeter@2556
   170
    /// The reduced cost map.
deba@2440
   171
    ReducedCostMap red_cost;
deba@2440
   172
    bool valid_supply;
deba@2440
   173
kpeter@2556
   174
    /// The edge map of the current flow.
deba@2440
   175
    SCapacityMap flow;
kpeter@2556
   176
    /// The potential node map.
kpeter@2556
   177
    SPotentialMap potential;
deba@2440
   178
    FlowMap flow_result;
deba@2440
   179
    PotentialMap potential_result;
deba@2440
   180
kpeter@2556
   181
    /// Node reference for the original graph.
deba@2440
   182
    NodeRefMap node_ref;
kpeter@2556
   183
    /// Edge reference for the original graph.
deba@2440
   184
    EdgeRefMap edge_ref;
deba@2440
   185
kpeter@2556
   186
    /// The \c depth node map of the spanning tree structure.
deba@2440
   187
    IntNodeMap depth;
kpeter@2556
   188
    /// The \c parent node map of the spanning tree structure.
deba@2440
   189
    NodeNodeMap parent;
kpeter@2556
   190
    /// The \c pred_edge node map of the spanning tree structure.
deba@2440
   191
    EdgeNodeMap pred_edge;
kpeter@2556
   192
    /// The \c thread node map of the spanning tree structure.
deba@2440
   193
    NodeNodeMap thread;
kpeter@2556
   194
    /// The \c forward node map of the spanning tree structure.
deba@2440
   195
    BoolNodeMap forward;
kpeter@2556
   196
    /// The state edge map.
deba@2440
   197
    IntEdgeMap state;
kpeter@2556
   198
    /// The root node of the starting spanning tree.
kpeter@2556
   199
    Node root;
deba@2440
   200
kpeter@2556
   201
    // The entering edge of the current pivot iteration.
kpeter@2556
   202
    Edge in_edge;
kpeter@2556
   203
    // Temporary nodes used in the current pivot iteration.
kpeter@2556
   204
    Node join, u_in, v_in, u_out, v_out;
kpeter@2556
   205
    Node right, first, second, last;
kpeter@2556
   206
    Node stem, par_stem, new_stem;
kpeter@2556
   207
    // The maximum augment amount along the found cycle in the current
kpeter@2556
   208
    // pivot iteration.
kpeter@2556
   209
    Capacity delta;
deba@2440
   210
deba@2440
   211
#ifdef EDGE_BLOCK_PIVOT
kpeter@2556
   212
    /// The size of blocks for the "Edge Block" pivot rule.
deba@2440
   213
    int block_size;
deba@2440
   214
#endif
deba@2440
   215
#ifdef CANDIDATE_LIST_PIVOT
deba@2440
   216
    /// \brief The list of candidate edges for the "Candidate List"
deba@2440
   217
    /// pivot rule.
kpeter@2471
   218
    std::vector<Edge> candidates;
kpeter@2471
   219
    /// \brief The maximum length of the edge list for the
kpeter@2471
   220
    /// "Candidate List" pivot rule.
kpeter@2471
   221
    int list_length;
kpeter@2471
   222
    /// \brief The maximum number of minor iterations between two major
kpeter@2471
   223
    /// itarations.
kpeter@2471
   224
    int minor_limit;
deba@2440
   225
    /// \brief The number of minor iterations.
deba@2440
   226
    int minor_count;
deba@2440
   227
#endif
deba@2440
   228
#ifdef SORTED_LIST_PIVOT
deba@2440
   229
    /// \brief The list of candidate edges for the "Sorted List"
deba@2440
   230
    /// pivot rule.
kpeter@2471
   231
    std::vector<Edge> candidates;
kpeter@2471
   232
    /// \brief The maximum length of the edge list for the
kpeter@2471
   233
    /// "Sorted List" pivot rule.
kpeter@2471
   234
    int list_length;
kpeter@2471
   235
    int list_index;
deba@2440
   236
#endif
deba@2440
   237
deba@2440
   238
  public :
deba@2440
   239
deba@2440
   240
    /// \brief General constructor of the class (with lower bounds).
deba@2440
   241
    ///
deba@2440
   242
    /// General constructor of the class (with lower bounds).
deba@2440
   243
    ///
deba@2440
   244
    /// \param _graph The directed graph the algorithm runs on.
deba@2440
   245
    /// \param _lower The lower bounds of the edges.
deba@2440
   246
    /// \param _capacity The capacities (upper bounds) of the edges.
deba@2440
   247
    /// \param _cost The cost (length) values of the edges.
deba@2440
   248
    /// \param _supply The supply values of the nodes (signed).
deba@2440
   249
    NetworkSimplex( const Graph &_graph,
kpeter@2556
   250
                    const LowerMap &_lower,
kpeter@2556
   251
                    const CapacityMap &_capacity,
kpeter@2556
   252
                    const CostMap &_cost,
kpeter@2556
   253
                    const SupplyMap &_supply ) :
deba@2440
   254
      graph_ref(_graph), lower(&_lower), capacity(graph), cost(graph),
deba@2440
   255
      supply(graph), flow(graph), flow_result(_graph), potential(graph),
deba@2440
   256
      potential_result(_graph), depth(graph), parent(graph),
deba@2440
   257
      pred_edge(graph), thread(graph), forward(graph), state(graph),
deba@2440
   258
      node_ref(graph_ref), edge_ref(graph_ref),
deba@2440
   259
      red_cost(graph, cost, potential)
deba@2440
   260
    {
deba@2440
   261
      // Checking the sum of supply values
deba@2440
   262
      Supply sum = 0;
deba@2440
   263
      for (typename Graph::NodeIt n(graph_ref); n != INVALID; ++n)
kpeter@2556
   264
        sum += _supply[n];
deba@2440
   265
      if (!(valid_supply = sum == 0)) return;
deba@2440
   266
deba@2440
   267
      // Copying graph_ref to graph
deba@2457
   268
      graph.reserveNode(countNodes(graph_ref) + 1);
deba@2457
   269
      graph.reserveEdge(countEdges(graph_ref) + countNodes(graph_ref));
deba@2440
   270
      copyGraph(graph, graph_ref)
kpeter@2556
   271
        .edgeMap(cost, _cost)
kpeter@2556
   272
        .nodeRef(node_ref)
kpeter@2556
   273
        .edgeRef(edge_ref)
kpeter@2556
   274
        .run();
deba@2440
   275
kpeter@2556
   276
      // Removing non-zero lower bounds
deba@2440
   277
      for (typename Graph::EdgeIt e(graph_ref); e != INVALID; ++e) {
kpeter@2556
   278
        capacity[edge_ref[e]] = _capacity[e] - _lower[e];
deba@2440
   279
      }
deba@2440
   280
      for (typename Graph::NodeIt n(graph_ref); n != INVALID; ++n) {
kpeter@2556
   281
        Supply s = _supply[n];
kpeter@2556
   282
        for (typename Graph::InEdgeIt e(graph_ref, n); e != INVALID; ++e)
kpeter@2556
   283
          s += _lower[e];
kpeter@2556
   284
        for (typename Graph::OutEdgeIt e(graph_ref, n); e != INVALID; ++e)
kpeter@2556
   285
          s -= _lower[e];
kpeter@2556
   286
        supply[node_ref[n]] = s;
deba@2440
   287
      }
deba@2440
   288
    }
deba@2440
   289
deba@2440
   290
    /// \brief General constructor of the class (without lower bounds).
deba@2440
   291
    ///
deba@2440
   292
    /// General constructor of the class (without lower bounds).
deba@2440
   293
    ///
deba@2440
   294
    /// \param _graph The directed graph the algorithm runs on.
deba@2440
   295
    /// \param _capacity The capacities (upper bounds) of the edges.
deba@2440
   296
    /// \param _cost The cost (length) values of the edges.
deba@2440
   297
    /// \param _supply The supply values of the nodes (signed).
deba@2440
   298
    NetworkSimplex( const Graph &_graph,
kpeter@2556
   299
                    const CapacityMap &_capacity,
kpeter@2556
   300
                    const CostMap &_cost,
kpeter@2556
   301
                    const SupplyMap &_supply ) :
deba@2440
   302
      graph_ref(_graph), lower(NULL), capacity(graph), cost(graph),
deba@2440
   303
      supply(graph), flow(graph), flow_result(_graph), potential(graph),
deba@2440
   304
      potential_result(_graph), depth(graph), parent(graph),
deba@2440
   305
      pred_edge(graph), thread(graph), forward(graph), state(graph),
deba@2440
   306
      node_ref(graph_ref), edge_ref(graph_ref),
deba@2440
   307
      red_cost(graph, cost, potential)
deba@2440
   308
    {
deba@2440
   309
      // Checking the sum of supply values
deba@2440
   310
      Supply sum = 0;
deba@2440
   311
      for (typename Graph::NodeIt n(graph_ref); n != INVALID; ++n)
kpeter@2556
   312
        sum += _supply[n];
deba@2440
   313
      if (!(valid_supply = sum == 0)) return;
deba@2440
   314
deba@2440
   315
      // Copying graph_ref to graph
deba@2440
   316
      copyGraph(graph, graph_ref)
kpeter@2556
   317
        .edgeMap(capacity, _capacity)
kpeter@2556
   318
        .edgeMap(cost, _cost)
kpeter@2556
   319
        .nodeMap(supply, _supply)
kpeter@2556
   320
        .nodeRef(node_ref)
kpeter@2556
   321
        .edgeRef(edge_ref)
kpeter@2556
   322
        .run();
deba@2440
   323
    }
deba@2440
   324
deba@2440
   325
    /// \brief Simple constructor of the class (with lower bounds).
deba@2440
   326
    ///
deba@2440
   327
    /// Simple constructor of the class (with lower bounds).
deba@2440
   328
    ///
deba@2440
   329
    /// \param _graph The directed graph the algorithm runs on.
deba@2440
   330
    /// \param _lower The lower bounds of the edges.
deba@2440
   331
    /// \param _capacity The capacities (upper bounds) of the edges.
deba@2440
   332
    /// \param _cost The cost (length) values of the edges.
deba@2440
   333
    /// \param _s The source node.
deba@2440
   334
    /// \param _t The target node.
deba@2440
   335
    /// \param _flow_value The required amount of flow from node \c _s
kpeter@2556
   336
    /// to node \c _t (i.e. the supply of \c _s and the demand of \c _t).
deba@2440
   337
    NetworkSimplex( const Graph &_graph,
kpeter@2556
   338
                    const LowerMap &_lower,
kpeter@2556
   339
                    const CapacityMap &_capacity,
kpeter@2556
   340
                    const CostMap &_cost,
kpeter@2556
   341
                    typename Graph::Node _s,
kpeter@2556
   342
                    typename Graph::Node _t,
kpeter@2556
   343
                    typename SupplyMap::Value _flow_value ) :
deba@2440
   344
      graph_ref(_graph), lower(&_lower), capacity(graph), cost(graph),
deba@2440
   345
      supply(graph), flow(graph), flow_result(_graph), potential(graph),
deba@2440
   346
      potential_result(_graph), depth(graph), parent(graph),
deba@2440
   347
      pred_edge(graph), thread(graph), forward(graph), state(graph),
deba@2440
   348
      node_ref(graph_ref), edge_ref(graph_ref),
deba@2440
   349
      red_cost(graph, cost, potential)
deba@2440
   350
    {
deba@2440
   351
      // Copying graph_ref to graph
deba@2440
   352
      copyGraph(graph, graph_ref)
kpeter@2556
   353
        .edgeMap(cost, _cost)
kpeter@2556
   354
        .nodeRef(node_ref)
kpeter@2556
   355
        .edgeRef(edge_ref)
kpeter@2556
   356
        .run();
deba@2440
   357
kpeter@2556
   358
      // Removing non-zero lower bounds
deba@2440
   359
      for (typename Graph::EdgeIt e(graph_ref); e != INVALID; ++e) {
kpeter@2556
   360
        capacity[edge_ref[e]] = _capacity[e] - _lower[e];
deba@2440
   361
      }
deba@2440
   362
      for (typename Graph::NodeIt n(graph_ref); n != INVALID; ++n) {
kpeter@2556
   363
        Supply s = 0;
kpeter@2556
   364
        if (n == _s) s =  _flow_value;
kpeter@2556
   365
        if (n == _t) s = -_flow_value;
kpeter@2556
   366
        for (typename Graph::InEdgeIt e(graph_ref, n); e != INVALID; ++e)
kpeter@2556
   367
          s += _lower[e];
kpeter@2556
   368
        for (typename Graph::OutEdgeIt e(graph_ref, n); e != INVALID; ++e)
kpeter@2556
   369
          s -= _lower[e];
kpeter@2556
   370
        supply[node_ref[n]] = s;
deba@2440
   371
      }
deba@2440
   372
      valid_supply = true;
deba@2440
   373
    }
deba@2440
   374
deba@2440
   375
    /// \brief Simple constructor of the class (without lower bounds).
deba@2440
   376
    ///
deba@2440
   377
    /// Simple constructor of the class (without lower bounds).
deba@2440
   378
    ///
deba@2440
   379
    /// \param _graph The directed graph the algorithm runs on.
deba@2440
   380
    /// \param _capacity The capacities (upper bounds) of the edges.
deba@2440
   381
    /// \param _cost The cost (length) values of the edges.
deba@2440
   382
    /// \param _s The source node.
deba@2440
   383
    /// \param _t The target node.
deba@2440
   384
    /// \param _flow_value The required amount of flow from node \c _s
kpeter@2556
   385
    /// to node \c _t (i.e. the supply of \c _s and the demand of \c _t).
deba@2440
   386
    NetworkSimplex( const Graph &_graph,
kpeter@2556
   387
                    const CapacityMap &_capacity,
kpeter@2556
   388
                    const CostMap &_cost,
kpeter@2556
   389
                    typename Graph::Node _s,
kpeter@2556
   390
                    typename Graph::Node _t,
kpeter@2556
   391
                    typename SupplyMap::Value _flow_value ) :
deba@2440
   392
      graph_ref(_graph), lower(NULL), capacity(graph), cost(graph),
deba@2440
   393
      supply(graph, 0), flow(graph), flow_result(_graph), potential(graph),
deba@2440
   394
      potential_result(_graph), depth(graph), parent(graph),
deba@2440
   395
      pred_edge(graph), thread(graph), forward(graph), state(graph),
deba@2440
   396
      node_ref(graph_ref), edge_ref(graph_ref),
deba@2440
   397
      red_cost(graph, cost, potential)
deba@2440
   398
    {
deba@2440
   399
      // Copying graph_ref to graph
deba@2440
   400
      copyGraph(graph, graph_ref)
kpeter@2556
   401
        .edgeMap(capacity, _capacity)
kpeter@2556
   402
        .edgeMap(cost, _cost)
kpeter@2556
   403
        .nodeRef(node_ref)
kpeter@2556
   404
        .edgeRef(edge_ref)
kpeter@2556
   405
        .run();
deba@2440
   406
      supply[node_ref[_s]] =  _flow_value;
deba@2440
   407
      supply[node_ref[_t]] = -_flow_value;
deba@2440
   408
      valid_supply = true;
deba@2440
   409
    }
deba@2440
   410
kpeter@2556
   411
    /// \brief Runs the algorithm.
kpeter@2556
   412
    ///
kpeter@2556
   413
    /// Runs the algorithm.
kpeter@2556
   414
    ///
kpeter@2556
   415
    /// \return \c true if a feasible flow can be found.
kpeter@2556
   416
    bool run() {
kpeter@2556
   417
      return init() && start();
kpeter@2556
   418
    }
kpeter@2556
   419
deba@2440
   420
    /// \brief Returns a const reference to the flow map.
deba@2440
   421
    ///
deba@2440
   422
    /// Returns a const reference to the flow map.
deba@2440
   423
    ///
deba@2440
   424
    /// \pre \ref run() must be called before using this function.
deba@2440
   425
    const FlowMap& flowMap() const {
deba@2440
   426
      return flow_result;
deba@2440
   427
    }
deba@2440
   428
deba@2440
   429
    /// \brief Returns a const reference to the potential map (the dual
deba@2440
   430
    /// solution).
deba@2440
   431
    ///
deba@2440
   432
    /// Returns a const reference to the potential map (the dual
deba@2440
   433
    /// solution).
deba@2440
   434
    ///
deba@2440
   435
    /// \pre \ref run() must be called before using this function.
deba@2440
   436
    const PotentialMap& potentialMap() const {
deba@2440
   437
      return potential_result;
deba@2440
   438
    }
deba@2440
   439
deba@2440
   440
    /// \brief Returns the total cost of the found flow.
deba@2440
   441
    ///
deba@2440
   442
    /// Returns the total cost of the found flow. The complexity of the
deba@2440
   443
    /// function is \f$ O(e) \f$.
deba@2440
   444
    ///
deba@2440
   445
    /// \pre \ref run() must be called before using this function.
deba@2440
   446
    Cost totalCost() const {
deba@2440
   447
      Cost c = 0;
deba@2440
   448
      for (typename Graph::EdgeIt e(graph_ref); e != INVALID; ++e)
kpeter@2556
   449
        c += flow_result[e] * cost[edge_ref[e]];
deba@2440
   450
      return c;
deba@2440
   451
    }
deba@2440
   452
deba@2440
   453
  protected:
deba@2440
   454
deba@2440
   455
    /// \brief Extends the underlaying graph and initializes all the
deba@2440
   456
    /// node and edge maps.
deba@2440
   457
    bool init() {
deba@2440
   458
      if (!valid_supply) return false;
deba@2440
   459
deba@2440
   460
      // Initializing state and flow maps
deba@2440
   461
      for (EdgeIt e(graph); e != INVALID; ++e) {
kpeter@2556
   462
        flow[e] = 0;
kpeter@2556
   463
        state[e] = LOWER;
deba@2440
   464
      }
deba@2440
   465
deba@2440
   466
      // Adding an artificial root node to the graph
deba@2440
   467
      root = graph.addNode();
deba@2440
   468
      parent[root] = INVALID;
deba@2440
   469
      pred_edge[root] = INVALID;
deba@2457
   470
      depth[root] = 0;
deba@2457
   471
      supply[root] = 0;
deba@2457
   472
      potential[root] = 0;
deba@2440
   473
deba@2440
   474
      // Adding artificial edges to the graph and initializing the node
deba@2440
   475
      // maps of the spanning tree data structure
deba@2440
   476
      Supply sum = 0;
deba@2440
   477
      Node last = root;
deba@2440
   478
      Edge e;
deba@2440
   479
      Cost max_cost = std::numeric_limits<Cost>::max() / 4;
deba@2440
   480
      for (NodeIt u(graph); u != INVALID; ++u) {
kpeter@2556
   481
        if (u == root) continue;
kpeter@2556
   482
        thread[last] = u;
kpeter@2556
   483
        last = u;
kpeter@2556
   484
        parent[u] = root;
kpeter@2556
   485
        depth[u] = 1;
kpeter@2556
   486
        sum += supply[u];
kpeter@2556
   487
        if (supply[u] >= 0) {
kpeter@2556
   488
          e = graph.addEdge(u, root);
kpeter@2556
   489
          flow[e] = supply[u];
kpeter@2556
   490
          forward[u] = true;
kpeter@2556
   491
          potential[u] = max_cost;
kpeter@2556
   492
        } else {
kpeter@2556
   493
          e = graph.addEdge(root, u);
kpeter@2556
   494
          flow[e] = -supply[u];
kpeter@2556
   495
          forward[u] = false;
kpeter@2556
   496
          potential[u] = -max_cost;
kpeter@2556
   497
        }
kpeter@2556
   498
        cost[e] = max_cost;
kpeter@2556
   499
        capacity[e] = std::numeric_limits<Capacity>::max();
kpeter@2556
   500
        state[e] = TREE;
kpeter@2556
   501
        pred_edge[u] = e;
deba@2440
   502
      }
deba@2440
   503
      thread[last] = root;
deba@2440
   504
deba@2440
   505
#ifdef EDGE_BLOCK_PIVOT
deba@2440
   506
      // Initializing block_size for the edge block pivot rule
deba@2440
   507
      int edge_num = countEdges(graph);
kpeter@2471
   508
      block_size = 2 * int(sqrt(countEdges(graph)));
kpeter@2471
   509
      if (block_size < MIN_BLOCK_SIZE) block_size = MIN_BLOCK_SIZE;
deba@2440
   510
#endif
deba@2440
   511
#ifdef CANDIDATE_LIST_PIVOT
kpeter@2471
   512
      int edge_num = countEdges(graph);
deba@2440
   513
      minor_count = 0;
kpeter@2471
   514
      list_length = edge_num / LIST_LENGTH_DIV;
kpeter@2471
   515
      minor_limit = edge_num / MINOR_LIMIT_DIV;
kpeter@2471
   516
#endif
kpeter@2471
   517
#ifdef SORTED_LIST_PIVOT
kpeter@2471
   518
      int edge_num = countEdges(graph);
kpeter@2471
   519
      list_index = 0;
kpeter@2471
   520
      list_length = edge_num / LIST_LENGTH_DIV;
deba@2440
   521
#endif
deba@2440
   522
deba@2440
   523
      return sum == 0;
deba@2440
   524
    }
deba@2440
   525
deba@2440
   526
#ifdef FIRST_ELIGIBLE_PIVOT
deba@2440
   527
    /// \brief Finds entering edge according to the "First Eligible"
deba@2440
   528
    /// pivot rule.
deba@2440
   529
    bool findEnteringEdge(EdgeIt &next_edge) {
deba@2440
   530
      for (EdgeIt e = next_edge; e != INVALID; ++e) {
kpeter@2556
   531
        if (state[e] * red_cost[e] < 0) {
kpeter@2556
   532
          in_edge = e;
kpeter@2556
   533
          next_edge = ++e;
kpeter@2556
   534
          return true;
kpeter@2556
   535
        }
deba@2440
   536
      }
deba@2440
   537
      for (EdgeIt e(graph); e != next_edge; ++e) {
kpeter@2556
   538
        if (state[e] * red_cost[e] < 0) {
kpeter@2556
   539
          in_edge = e;
kpeter@2556
   540
          next_edge = ++e;
kpeter@2556
   541
          return true;
kpeter@2556
   542
        }
deba@2440
   543
      }
deba@2440
   544
      return false;
deba@2440
   545
    }
deba@2440
   546
#endif
deba@2440
   547
deba@2440
   548
#ifdef BEST_ELIGIBLE_PIVOT
deba@2440
   549
    /// \brief Finds entering edge according to the "Best Eligible"
deba@2440
   550
    /// pivot rule.
deba@2440
   551
    bool findEnteringEdge() {
deba@2440
   552
      Cost min = 0;
deba@2440
   553
      for (EdgeIt e(graph); e != INVALID; ++e) {
kpeter@2556
   554
        if (state[e] * red_cost[e] < min) {
kpeter@2556
   555
          min = state[e] * red_cost[e];
kpeter@2556
   556
          in_edge = e;
kpeter@2556
   557
        }
deba@2440
   558
      }
deba@2440
   559
      return min < 0;
deba@2440
   560
    }
deba@2440
   561
#endif
deba@2440
   562
deba@2440
   563
#ifdef EDGE_BLOCK_PIVOT
deba@2440
   564
    /// \brief Finds entering edge according to the "Edge Block"
deba@2440
   565
    /// pivot rule.
deba@2440
   566
    bool findEnteringEdge(EdgeIt &next_edge) {
deba@2444
   567
      // Performing edge block selection
deba@2444
   568
      Cost curr, min = 0;
deba@2444
   569
      EdgeIt min_edge(graph);
deba@2444
   570
      int cnt = 0;
deba@2444
   571
      for (EdgeIt e = next_edge; e != INVALID; ++e) {
kpeter@2556
   572
        if ((curr = state[e] * red_cost[e]) < min) {
kpeter@2556
   573
          min = curr;
kpeter@2556
   574
          min_edge = e;
kpeter@2556
   575
        }
kpeter@2556
   576
        if (++cnt == block_size) {
kpeter@2556
   577
          if (min < 0) break;
kpeter@2556
   578
          cnt = 0;
kpeter@2556
   579
        }
deba@2444
   580
      }
deba@2444
   581
      if (!(min < 0)) {
kpeter@2556
   582
        for (EdgeIt e(graph); e != next_edge; ++e) {
kpeter@2556
   583
          if ((curr = state[e] * red_cost[e]) < min) {
kpeter@2556
   584
            min = curr;
kpeter@2556
   585
            min_edge = e;
kpeter@2556
   586
          }
kpeter@2556
   587
          if (++cnt == block_size) {
kpeter@2556
   588
            if (min < 0) break;
kpeter@2556
   589
            cnt = 0;
kpeter@2556
   590
          }
kpeter@2556
   591
        }
deba@2440
   592
      }
deba@2444
   593
      in_edge = min_edge;
deba@2444
   594
      if ((next_edge = ++min_edge) == INVALID)
kpeter@2556
   595
        next_edge = EdgeIt(graph);
deba@2444
   596
      return min < 0;
deba@2440
   597
    }
deba@2440
   598
#endif
deba@2440
   599
deba@2440
   600
#ifdef CANDIDATE_LIST_PIVOT
deba@2440
   601
    /// \brief Finds entering edge according to the "Candidate List"
deba@2440
   602
    /// pivot rule.
deba@2440
   603
    bool findEnteringEdge() {
kpeter@2471
   604
      typedef typename std::vector<Edge>::iterator ListIt;
deba@2440
   605
kpeter@2471
   606
      if (minor_count >= minor_limit || candidates.size() == 0) {
kpeter@2556
   607
        // Major iteration
kpeter@2556
   608
        candidates.clear();
kpeter@2556
   609
        for (EdgeIt e(graph); e != INVALID; ++e) {
kpeter@2556
   610
          if (state[e] * red_cost[e] < 0) {
kpeter@2556
   611
            candidates.push_back(e);
kpeter@2556
   612
            if (candidates.size() == list_length) break;
kpeter@2556
   613
          }
kpeter@2556
   614
        }
kpeter@2556
   615
        if (candidates.size() == 0) return false;
deba@2440
   616
      }
deba@2440
   617
deba@2440
   618
      // Minor iteration
deba@2440
   619
      ++minor_count;
deba@2440
   620
      Cost min = 0;
kpeter@2471
   621
      Edge e;
kpeter@2471
   622
      for (int i = 0; i < candidates.size(); ++i) {
kpeter@2471
   623
        e = candidates[i];
kpeter@2556
   624
        if (state[e] * red_cost[e] < min) {
kpeter@2556
   625
          min = state[e] * red_cost[e];
kpeter@2556
   626
          in_edge = e;
kpeter@2556
   627
        }
deba@2440
   628
      }
deba@2440
   629
      return true;
deba@2440
   630
    }
deba@2440
   631
#endif
deba@2440
   632
deba@2440
   633
#ifdef SORTED_LIST_PIVOT
deba@2440
   634
    /// \brief Functor class to compare edges during sort of the
deba@2440
   635
    /// candidate list.
deba@2440
   636
    class SortFunc
deba@2440
   637
    {
deba@2440
   638
    private:
deba@2440
   639
      const IntEdgeMap &st;
deba@2440
   640
      const ReducedCostMap &rc;
deba@2440
   641
    public:
deba@2440
   642
      SortFunc(const IntEdgeMap &_st, const ReducedCostMap &_rc) :
kpeter@2556
   643
        st(_st), rc(_rc) {}
deba@2440
   644
      bool operator()(const Edge &e1, const Edge &e2) {
kpeter@2556
   645
        return st[e1] * rc[e1] < st[e2] * rc[e2];
deba@2440
   646
      }
deba@2440
   647
    };
deba@2440
   648
deba@2440
   649
    /// \brief Finds entering edge according to the "Sorted List"
deba@2440
   650
    /// pivot rule.
deba@2440
   651
    bool findEnteringEdge() {
deba@2440
   652
      static SortFunc sort_func(state, red_cost);
deba@2440
   653
deba@2440
   654
      // Minor iteration
kpeter@2471
   655
      while (list_index < candidates.size()) {
kpeter@2556
   656
        in_edge = candidates[list_index++];
kpeter@2556
   657
        if (state[in_edge] * red_cost[in_edge] < 0) return true;
deba@2440
   658
      }
deba@2440
   659
deba@2440
   660
      // Major iteration
kpeter@2471
   661
      candidates.clear();
deba@2440
   662
      Cost curr, min = 0;
deba@2440
   663
      for (EdgeIt e(graph); e != INVALID; ++e) {
kpeter@2556
   664
        if ((curr = state[e] * red_cost[e]) < min / LOWER_DIV) {
kpeter@2556
   665
          candidates.push_back(e);
kpeter@2556
   666
          if (curr < min) min = curr;
kpeter@2556
   667
          if (candidates.size() == list_length) break;
kpeter@2556
   668
        }
deba@2440
   669
      }
deba@2440
   670
      if (candidates.size() == 0) return false;
deba@2440
   671
      sort(candidates.begin(), candidates.end(), sort_func);
kpeter@2471
   672
      in_edge = candidates[0];
kpeter@2471
   673
      list_index = 1;
deba@2440
   674
      return true;
deba@2440
   675
    }
deba@2440
   676
#endif
deba@2440
   677
deba@2440
   678
    /// \brief Finds the join node.
deba@2440
   679
    Node findJoinNode() {
deba@2440
   680
      // Finding the join node
deba@2440
   681
      Node u = graph.source(in_edge);
deba@2440
   682
      Node v = graph.target(in_edge);
deba@2440
   683
      while (u != v) {
kpeter@2556
   684
        if (depth[u] == depth[v]) {
kpeter@2556
   685
          u = parent[u];
kpeter@2556
   686
          v = parent[v];
kpeter@2556
   687
        }
kpeter@2556
   688
        else if (depth[u] > depth[v]) u = parent[u];
kpeter@2556
   689
        else v = parent[v];
deba@2440
   690
      }
deba@2440
   691
      return u;
deba@2440
   692
    }
deba@2440
   693
deba@2440
   694
    /// \brief Finds the leaving edge of the cycle. Returns \c true if
deba@2440
   695
    /// the leaving edge is not the same as the entering edge.
deba@2440
   696
    bool findLeavingEdge() {
deba@2440
   697
      // Initializing first and second nodes according to the direction
deba@2440
   698
      // of the cycle
deba@2440
   699
      if (state[in_edge] == LOWER) {
kpeter@2556
   700
        first = graph.source(in_edge);
kpeter@2556
   701
        second  = graph.target(in_edge);
deba@2440
   702
      } else {
kpeter@2556
   703
        first = graph.target(in_edge);
kpeter@2556
   704
        second  = graph.source(in_edge);
deba@2440
   705
      }
deba@2440
   706
      delta = capacity[in_edge];
deba@2440
   707
      bool result = false;
deba@2440
   708
      Capacity d;
deba@2440
   709
      Edge e;
deba@2440
   710
deba@2440
   711
      // Searching the cycle along the path form the first node to the
deba@2440
   712
      // root node
deba@2440
   713
      for (Node u = first; u != join; u = parent[u]) {
kpeter@2556
   714
        e = pred_edge[u];
kpeter@2556
   715
        d = forward[u] ? flow[e] : capacity[e] - flow[e];
kpeter@2556
   716
        if (d < delta) {
kpeter@2556
   717
          delta = d;
kpeter@2556
   718
          u_out = u;
kpeter@2556
   719
          u_in = first;
kpeter@2556
   720
          v_in = second;
kpeter@2556
   721
          result = true;
kpeter@2556
   722
        }
deba@2440
   723
      }
deba@2440
   724
      // Searching the cycle along the path form the second node to the
deba@2440
   725
      // root node
deba@2440
   726
      for (Node u = second; u != join; u = parent[u]) {
kpeter@2556
   727
        e = pred_edge[u];
kpeter@2556
   728
        d = forward[u] ? capacity[e] - flow[e] : flow[e];
kpeter@2556
   729
        if (d <= delta) {
kpeter@2556
   730
          delta = d;
kpeter@2556
   731
          u_out = u;
kpeter@2556
   732
          u_in = second;
kpeter@2556
   733
          v_in = first;
kpeter@2556
   734
          result = true;
kpeter@2556
   735
        }
deba@2440
   736
      }
deba@2440
   737
      return result;
deba@2440
   738
    }
deba@2440
   739
kpeter@2556
   740
    /// \brief Changes \c flow and \c state edge maps.
deba@2440
   741
    void changeFlows(bool change) {
deba@2440
   742
      // Augmenting along the cycle
deba@2440
   743
      if (delta > 0) {
kpeter@2556
   744
        Capacity val = state[in_edge] * delta;
kpeter@2556
   745
        flow[in_edge] += val;
kpeter@2556
   746
        for (Node u = graph.source(in_edge); u != join; u = parent[u]) {
kpeter@2556
   747
          flow[pred_edge[u]] += forward[u] ? -val : val;
kpeter@2556
   748
        }
kpeter@2556
   749
        for (Node u = graph.target(in_edge); u != join; u = parent[u]) {
kpeter@2556
   750
          flow[pred_edge[u]] += forward[u] ? val : -val;
kpeter@2556
   751
        }
deba@2440
   752
      }
deba@2440
   753
      // Updating the state of the entering and leaving edges
deba@2440
   754
      if (change) {
kpeter@2556
   755
        state[in_edge] = TREE;
kpeter@2556
   756
        state[pred_edge[u_out]] =
kpeter@2556
   757
          (flow[pred_edge[u_out]] == 0) ? LOWER : UPPER;
deba@2440
   758
      } else {
kpeter@2556
   759
        state[in_edge] = -state[in_edge];
deba@2440
   760
      }
deba@2440
   761
    }
deba@2440
   762
kpeter@2556
   763
    /// \brief Updates \c thread and \c parent node maps.
deba@2440
   764
    void updateThreadParent() {
deba@2440
   765
      Node u;
deba@2440
   766
      v_out = parent[u_out];
deba@2440
   767
deba@2440
   768
      // Handling the case when join and v_out coincide
deba@2440
   769
      bool par_first = false;
deba@2440
   770
      if (join == v_out) {
kpeter@2556
   771
        for (u = join; u != u_in && u != v_in; u = thread[u]) ;
kpeter@2556
   772
        if (u == v_in) {
kpeter@2556
   773
          par_first = true;
kpeter@2556
   774
          while (thread[u] != u_out) u = thread[u];
kpeter@2556
   775
          first = u;
kpeter@2556
   776
        }
deba@2440
   777
      }
deba@2440
   778
deba@2440
   779
      // Finding the last successor of u_in (u) and the node after it
deba@2440
   780
      // (right) according to the thread index
deba@2440
   781
      for (u = u_in; depth[thread[u]] > depth[u_in]; u = thread[u]) ;
deba@2440
   782
      right = thread[u];
deba@2440
   783
      if (thread[v_in] == u_out) {
kpeter@2556
   784
        for (last = u; depth[last] > depth[u_out]; last = thread[last]) ;
kpeter@2556
   785
        if (last == u_out) last = thread[last];
deba@2440
   786
      }
deba@2440
   787
      else last = thread[v_in];
deba@2440
   788
deba@2440
   789
      // Updating stem nodes
deba@2440
   790
      thread[v_in] = stem = u_in;
deba@2440
   791
      par_stem = v_in;
deba@2440
   792
      while (stem != u_out) {
kpeter@2556
   793
        thread[u] = new_stem = parent[stem];
deba@2440
   794
kpeter@2556
   795
        // Finding the node just before the stem node (u) according to
kpeter@2556
   796
        // the original thread index
kpeter@2556
   797
        for (u = new_stem; thread[u] != stem; u = thread[u]) ;
kpeter@2556
   798
        thread[u] = right;
deba@2440
   799
kpeter@2556
   800
        // Changing the parent node of stem and shifting stem and
kpeter@2556
   801
        // par_stem nodes
kpeter@2556
   802
        parent[stem] = par_stem;
kpeter@2556
   803
        par_stem = stem;
kpeter@2556
   804
        stem = new_stem;
deba@2440
   805
kpeter@2556
   806
        // Finding the last successor of stem (u) and the node after it
kpeter@2556
   807
        // (right) according to the thread index
kpeter@2556
   808
        for (u = stem; depth[thread[u]] > depth[stem]; u = thread[u]) ;
kpeter@2556
   809
        right = thread[u];
deba@2440
   810
      }
deba@2440
   811
      parent[u_out] = par_stem;
deba@2440
   812
      thread[u] = last;
deba@2440
   813
deba@2440
   814
      if (join == v_out && par_first) {
kpeter@2556
   815
        if (first != v_in) thread[first] = right;
deba@2440
   816
      } else {
kpeter@2556
   817
        for (u = v_out; thread[u] != u_out; u = thread[u]) ;
kpeter@2556
   818
        thread[u] = right;
deba@2440
   819
      }
deba@2440
   820
    }
deba@2440
   821
kpeter@2556
   822
    /// \brief Updates \c pred_edge and \c forward node maps.
deba@2440
   823
    void updatePredEdge() {
deba@2440
   824
      Node u = u_out, v;
deba@2440
   825
      while (u != u_in) {
kpeter@2556
   826
        v = parent[u];
kpeter@2556
   827
        pred_edge[u] = pred_edge[v];
kpeter@2556
   828
        forward[u] = !forward[v];
kpeter@2556
   829
        u = v;
deba@2440
   830
      }
deba@2440
   831
      pred_edge[u_in] = in_edge;
deba@2440
   832
      forward[u_in] = (u_in == graph.source(in_edge));
deba@2440
   833
    }
deba@2440
   834
kpeter@2556
   835
    /// \brief Updates \c depth and \c potential node maps.
deba@2440
   836
    void updateDepthPotential() {
deba@2440
   837
      depth[u_in] = depth[v_in] + 1;
deba@2440
   838
      potential[u_in] = forward[u_in] ?
kpeter@2556
   839
        potential[v_in] + cost[pred_edge[u_in]] :
kpeter@2556
   840
        potential[v_in] - cost[pred_edge[u_in]];
deba@2440
   841
deba@2440
   842
      Node u = thread[u_in], v;
deba@2440
   843
      while (true) {
kpeter@2556
   844
        v = parent[u];
kpeter@2556
   845
        if (v == INVALID) break;
kpeter@2556
   846
        depth[u] = depth[v] + 1;
kpeter@2556
   847
        potential[u] = forward[u] ?
kpeter@2556
   848
          potential[v] + cost[pred_edge[u]] :
kpeter@2556
   849
          potential[v] - cost[pred_edge[u]];
kpeter@2556
   850
        if (depth[u] <= depth[v_in]) break;
kpeter@2556
   851
        u = thread[u];
deba@2440
   852
      }
deba@2440
   853
    }
deba@2440
   854
deba@2440
   855
    /// \brief Executes the algorithm.
deba@2440
   856
    bool start() {
deba@2440
   857
      // Processing pivots
deba@2440
   858
#ifdef _DEBUG_ITER_
deba@2440
   859
      int iter_num = 0;
deba@2440
   860
#endif
deba@2440
   861
#if defined(FIRST_ELIGIBLE_PIVOT) || defined(EDGE_BLOCK_PIVOT)
deba@2440
   862
      EdgeIt next_edge(graph);
deba@2440
   863
      while (findEnteringEdge(next_edge))
deba@2440
   864
#else
deba@2440
   865
      while (findEnteringEdge())
deba@2440
   866
#endif
deba@2440
   867
      {
kpeter@2556
   868
        join = findJoinNode();
kpeter@2556
   869
        bool change = findLeavingEdge();
kpeter@2556
   870
        changeFlows(change);
kpeter@2556
   871
        if (change) {
kpeter@2556
   872
          updateThreadParent();
kpeter@2556
   873
          updatePredEdge();
kpeter@2556
   874
          updateDepthPotential();
kpeter@2556
   875
        }
deba@2440
   876
#ifdef _DEBUG_ITER_
kpeter@2556
   877
        ++iter_num;
deba@2440
   878
#endif
deba@2440
   879
      }
deba@2440
   880
deba@2440
   881
#ifdef _DEBUG_ITER_
deba@2440
   882
      std::cout << "Network Simplex algorithm finished. " << iter_num
kpeter@2556
   883
                << " pivot iterations performed." << std::endl;
deba@2440
   884
#endif
deba@2440
   885
deba@2440
   886
      // Checking if the flow amount equals zero on all the
deba@2440
   887
      // artificial edges
deba@2440
   888
      for (InEdgeIt e(graph, root); e != INVALID; ++e)
kpeter@2556
   889
        if (flow[e] > 0) return false;
deba@2440
   890
      for (OutEdgeIt e(graph, root); e != INVALID; ++e)
kpeter@2556
   891
        if (flow[e] > 0) return false;
deba@2440
   892
deba@2440
   893
      // Copying flow values to flow_result
deba@2440
   894
      if (lower) {
kpeter@2556
   895
        for (typename Graph::EdgeIt e(graph_ref); e != INVALID; ++e)
kpeter@2556
   896
          flow_result[e] = (*lower)[e] + flow[edge_ref[e]];
deba@2440
   897
      } else {
kpeter@2556
   898
        for (typename Graph::EdgeIt e(graph_ref); e != INVALID; ++e)
kpeter@2556
   899
          flow_result[e] = flow[edge_ref[e]];
deba@2440
   900
      }
deba@2440
   901
      // Copying potential values to potential_result
deba@2440
   902
      for (typename Graph::NodeIt n(graph_ref); n != INVALID; ++n)
kpeter@2556
   903
        potential_result[n] = potential[node_ref[n]];
deba@2440
   904
deba@2440
   905
      return true;
deba@2440
   906
    }
deba@2440
   907
deba@2440
   908
  }; //class NetworkSimplex
deba@2440
   909
deba@2440
   910
  ///@}
deba@2440
   911
deba@2440
   912
} //namespace lemon
deba@2440
   913
deba@2440
   914
#endif //LEMON_NETWORK_SIMPLEX_H