lemon/network_simplex.h
author Balazs Dezso <deba@inf.elte.hu>
Thu, 24 Jun 2010 09:27:53 +0200
changeset 894 bb70ad62c95f
parent 663 8b0df68370a4
child 892 cbf32bf95954
permissions -rw-r--r--
Fix critical bug in preflow (#372)

The wrong transition between the bound decrease and highest active
heuristics caused the bug. The last node chosen in bound decrease mode
is used in the first iteration in highest active mode.
kpeter@601
     1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
kpeter@601
     2
 *
kpeter@601
     3
 * This file is a part of LEMON, a generic C++ optimization library.
kpeter@601
     4
 *
kpeter@601
     5
 * Copyright (C) 2003-2009
kpeter@601
     6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
kpeter@601
     7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
kpeter@601
     8
 *
kpeter@601
     9
 * Permission to use, modify and distribute this software is granted
kpeter@601
    10
 * provided that this copyright notice appears in all copies. For
kpeter@601
    11
 * precise terms see the accompanying LICENSE file.
kpeter@601
    12
 *
kpeter@601
    13
 * This software is provided "AS IS" with no warranty of any kind,
kpeter@601
    14
 * express or implied, and with no claim as to its suitability for any
kpeter@601
    15
 * purpose.
kpeter@601
    16
 *
kpeter@601
    17
 */
kpeter@601
    18
kpeter@601
    19
#ifndef LEMON_NETWORK_SIMPLEX_H
kpeter@601
    20
#define LEMON_NETWORK_SIMPLEX_H
kpeter@601
    21
kpeter@663
    22
/// \ingroup min_cost_flow_algs
kpeter@601
    23
///
kpeter@601
    24
/// \file
kpeter@605
    25
/// \brief Network Simplex algorithm for finding a minimum cost flow.
kpeter@601
    26
kpeter@601
    27
#include <vector>
kpeter@601
    28
#include <limits>
kpeter@601
    29
#include <algorithm>
kpeter@601
    30
kpeter@603
    31
#include <lemon/core.h>
kpeter@601
    32
#include <lemon/math.h>
kpeter@601
    33
kpeter@601
    34
namespace lemon {
kpeter@601
    35
kpeter@663
    36
  /// \addtogroup min_cost_flow_algs
kpeter@601
    37
  /// @{
kpeter@601
    38
kpeter@605
    39
  /// \brief Implementation of the primal Network Simplex algorithm
kpeter@601
    40
  /// for finding a \ref min_cost_flow "minimum cost flow".
kpeter@601
    41
  ///
kpeter@605
    42
  /// \ref NetworkSimplex implements the primal Network Simplex algorithm
kpeter@601
    43
  /// for finding a \ref min_cost_flow "minimum cost flow".
kpeter@606
    44
  /// This algorithm is a specialized version of the linear programming
kpeter@606
    45
  /// simplex method directly for the minimum cost flow problem.
kpeter@606
    46
  /// It is one of the most efficient solution methods.
kpeter@606
    47
  ///
kpeter@606
    48
  /// In general this class is the fastest implementation available
kpeter@606
    49
  /// in LEMON for the minimum cost flow problem.
kpeter@640
    50
  /// Moreover it supports both directions of the supply/demand inequality
kpeter@640
    51
  /// constraints. For more information see \ref SupplyType.
kpeter@640
    52
  ///
kpeter@640
    53
  /// Most of the parameters of the problem (except for the digraph)
kpeter@640
    54
  /// can be given using separate functions, and the algorithm can be
kpeter@640
    55
  /// executed using the \ref run() function. If some parameters are not
kpeter@640
    56
  /// specified, then default values will be used.
kpeter@601
    57
  ///
kpeter@605
    58
  /// \tparam GR The digraph type the algorithm runs on.
kpeter@641
    59
  /// \tparam V The value type used for flow amounts, capacity bounds
kpeter@607
    60
  /// and supply values in the algorithm. By default it is \c int.
kpeter@607
    61
  /// \tparam C The value type used for costs and potentials in the
kpeter@641
    62
  /// algorithm. By default it is the same as \c V.
kpeter@601
    63
  ///
kpeter@608
    64
  /// \warning Both value types must be signed and all input data must
kpeter@608
    65
  /// be integer.
kpeter@601
    66
  ///
kpeter@605
    67
  /// \note %NetworkSimplex provides five different pivot rule
kpeter@609
    68
  /// implementations, from which the most efficient one is used
kpeter@609
    69
  /// by default. For more information see \ref PivotRule.
kpeter@641
    70
  template <typename GR, typename V = int, typename C = V>
kpeter@601
    71
  class NetworkSimplex
kpeter@601
    72
  {
kpeter@605
    73
  public:
kpeter@601
    74
kpeter@642
    75
    /// The type of the flow amounts, capacity bounds and supply values
kpeter@641
    76
    typedef V Value;
kpeter@642
    77
    /// The type of the arc costs
kpeter@607
    78
    typedef C Cost;
kpeter@605
    79
kpeter@605
    80
  public:
kpeter@605
    81
kpeter@640
    82
    /// \brief Problem type constants for the \c run() function.
kpeter@605
    83
    ///
kpeter@640
    84
    /// Enum type containing the problem type constants that can be
kpeter@640
    85
    /// returned by the \ref run() function of the algorithm.
kpeter@640
    86
    enum ProblemType {
kpeter@640
    87
      /// The problem has no feasible solution (flow).
kpeter@640
    88
      INFEASIBLE,
kpeter@640
    89
      /// The problem has optimal solution (i.e. it is feasible and
kpeter@640
    90
      /// bounded), and the algorithm has found optimal flow and node
kpeter@640
    91
      /// potentials (primal and dual solutions).
kpeter@640
    92
      OPTIMAL,
kpeter@640
    93
      /// The objective function of the problem is unbounded, i.e.
kpeter@640
    94
      /// there is a directed cycle having negative total cost and
kpeter@640
    95
      /// infinite upper bound.
kpeter@640
    96
      UNBOUNDED
kpeter@640
    97
    };
kpeter@640
    98
    
kpeter@640
    99
    /// \brief Constants for selecting the type of the supply constraints.
kpeter@640
   100
    ///
kpeter@640
   101
    /// Enum type containing constants for selecting the supply type,
kpeter@640
   102
    /// i.e. the direction of the inequalities in the supply/demand
kpeter@640
   103
    /// constraints of the \ref min_cost_flow "minimum cost flow problem".
kpeter@640
   104
    ///
kpeter@663
   105
    /// The default supply type is \c GEQ, the \c LEQ type can be
kpeter@663
   106
    /// selected using \ref supplyType().
kpeter@663
   107
    /// The equality form is a special case of both supply types.
kpeter@640
   108
    enum SupplyType {
kpeter@640
   109
      /// This option means that there are <em>"greater or equal"</em>
kpeter@663
   110
      /// supply/demand constraints in the definition of the problem.
kpeter@640
   111
      GEQ,
kpeter@640
   112
      /// This option means that there are <em>"less or equal"</em>
kpeter@663
   113
      /// supply/demand constraints in the definition of the problem.
kpeter@663
   114
      LEQ
kpeter@640
   115
    };
kpeter@640
   116
    
kpeter@640
   117
    /// \brief Constants for selecting the pivot rule.
kpeter@640
   118
    ///
kpeter@640
   119
    /// Enum type containing constants for selecting the pivot rule for
kpeter@640
   120
    /// the \ref run() function.
kpeter@640
   121
    ///
kpeter@605
   122
    /// \ref NetworkSimplex provides five different pivot rule
kpeter@605
   123
    /// implementations that significantly affect the running time
kpeter@605
   124
    /// of the algorithm.
kpeter@605
   125
    /// By default \ref BLOCK_SEARCH "Block Search" is used, which
kpeter@605
   126
    /// proved to be the most efficient and the most robust on various
kpeter@605
   127
    /// test inputs according to our benchmark tests.
kpeter@605
   128
    /// However another pivot rule can be selected using the \ref run()
kpeter@605
   129
    /// function with the proper parameter.
kpeter@605
   130
    enum PivotRule {
kpeter@605
   131
kpeter@605
   132
      /// The First Eligible pivot rule.
kpeter@605
   133
      /// The next eligible arc is selected in a wraparound fashion
kpeter@605
   134
      /// in every iteration.
kpeter@605
   135
      FIRST_ELIGIBLE,
kpeter@605
   136
kpeter@605
   137
      /// The Best Eligible pivot rule.
kpeter@605
   138
      /// The best eligible arc is selected in every iteration.
kpeter@605
   139
      BEST_ELIGIBLE,
kpeter@605
   140
kpeter@605
   141
      /// The Block Search pivot rule.
kpeter@605
   142
      /// A specified number of arcs are examined in every iteration
kpeter@605
   143
      /// in a wraparound fashion and the best eligible arc is selected
kpeter@605
   144
      /// from this block.
kpeter@605
   145
      BLOCK_SEARCH,
kpeter@605
   146
kpeter@605
   147
      /// The Candidate List pivot rule.
kpeter@605
   148
      /// In a major iteration a candidate list is built from eligible arcs
kpeter@605
   149
      /// in a wraparound fashion and in the following minor iterations
kpeter@605
   150
      /// the best eligible arc is selected from this list.
kpeter@605
   151
      CANDIDATE_LIST,
kpeter@605
   152
kpeter@605
   153
      /// The Altering Candidate List pivot rule.
kpeter@605
   154
      /// It is a modified version of the Candidate List method.
kpeter@605
   155
      /// It keeps only the several best eligible arcs from the former
kpeter@605
   156
      /// candidate list and extends this list in every iteration.
kpeter@605
   157
      ALTERING_LIST
kpeter@605
   158
    };
kpeter@609
   159
    
kpeter@605
   160
  private:
kpeter@605
   161
kpeter@605
   162
    TEMPLATE_DIGRAPH_TYPEDEFS(GR);
kpeter@605
   163
kpeter@601
   164
    typedef std::vector<Arc> ArcVector;
kpeter@601
   165
    typedef std::vector<Node> NodeVector;
kpeter@601
   166
    typedef std::vector<int> IntVector;
kpeter@601
   167
    typedef std::vector<bool> BoolVector;
kpeter@642
   168
    typedef std::vector<Value> ValueVector;
kpeter@607
   169
    typedef std::vector<Cost> CostVector;
kpeter@601
   170
kpeter@601
   171
    // State constants for arcs
kpeter@601
   172
    enum ArcStateEnum {
kpeter@601
   173
      STATE_UPPER = -1,
kpeter@601
   174
      STATE_TREE  =  0,
kpeter@601
   175
      STATE_LOWER =  1
kpeter@601
   176
    };
kpeter@601
   177
kpeter@601
   178
  private:
kpeter@601
   179
kpeter@605
   180
    // Data related to the underlying digraph
kpeter@605
   181
    const GR &_graph;
kpeter@605
   182
    int _node_num;
kpeter@605
   183
    int _arc_num;
kpeter@663
   184
    int _all_arc_num;
kpeter@663
   185
    int _search_arc_num;
kpeter@605
   186
kpeter@605
   187
    // Parameters of the problem
kpeter@642
   188
    bool _have_lower;
kpeter@640
   189
    SupplyType _stype;
kpeter@641
   190
    Value _sum_supply;
kpeter@601
   191
kpeter@605
   192
    // Data structures for storing the digraph
kpeter@603
   193
    IntNodeMap _node_id;
kpeter@642
   194
    IntArcMap _arc_id;
kpeter@603
   195
    IntVector _source;
kpeter@603
   196
    IntVector _target;
kpeter@603
   197
kpeter@605
   198
    // Node and arc data
kpeter@642
   199
    ValueVector _lower;
kpeter@642
   200
    ValueVector _upper;
kpeter@642
   201
    ValueVector _cap;
kpeter@607
   202
    CostVector _cost;
kpeter@642
   203
    ValueVector _supply;
kpeter@642
   204
    ValueVector _flow;
kpeter@607
   205
    CostVector _pi;
kpeter@601
   206
kpeter@603
   207
    // Data for storing the spanning tree structure
kpeter@601
   208
    IntVector _parent;
kpeter@601
   209
    IntVector _pred;
kpeter@601
   210
    IntVector _thread;
kpeter@604
   211
    IntVector _rev_thread;
kpeter@604
   212
    IntVector _succ_num;
kpeter@604
   213
    IntVector _last_succ;
kpeter@604
   214
    IntVector _dirty_revs;
kpeter@601
   215
    BoolVector _forward;
kpeter@601
   216
    IntVector _state;
kpeter@601
   217
    int _root;
kpeter@601
   218
kpeter@601
   219
    // Temporary data used in the current pivot iteration
kpeter@603
   220
    int in_arc, join, u_in, v_in, u_out, v_out;
kpeter@603
   221
    int first, second, right, last;
kpeter@601
   222
    int stem, par_stem, new_stem;
kpeter@641
   223
    Value delta;
kpeter@601
   224
kpeter@640
   225
  public:
kpeter@640
   226
  
kpeter@640
   227
    /// \brief Constant for infinite upper bounds (capacities).
kpeter@640
   228
    ///
kpeter@640
   229
    /// Constant for infinite upper bounds (capacities).
kpeter@641
   230
    /// It is \c std::numeric_limits<Value>::infinity() if available,
kpeter@641
   231
    /// \c std::numeric_limits<Value>::max() otherwise.
kpeter@641
   232
    const Value INF;
kpeter@640
   233
kpeter@601
   234
  private:
kpeter@601
   235
kpeter@605
   236
    // Implementation of the First Eligible pivot rule
kpeter@601
   237
    class FirstEligiblePivotRule
kpeter@601
   238
    {
kpeter@601
   239
    private:
kpeter@601
   240
kpeter@601
   241
      // References to the NetworkSimplex class
kpeter@601
   242
      const IntVector  &_source;
kpeter@601
   243
      const IntVector  &_target;
kpeter@607
   244
      const CostVector &_cost;
kpeter@601
   245
      const IntVector  &_state;
kpeter@607
   246
      const CostVector &_pi;
kpeter@601
   247
      int &_in_arc;
kpeter@663
   248
      int _search_arc_num;
kpeter@601
   249
kpeter@601
   250
      // Pivot rule data
kpeter@601
   251
      int _next_arc;
kpeter@601
   252
kpeter@601
   253
    public:
kpeter@601
   254
kpeter@605
   255
      // Constructor
kpeter@601
   256
      FirstEligiblePivotRule(NetworkSimplex &ns) :
kpeter@603
   257
        _source(ns._source), _target(ns._target),
kpeter@601
   258
        _cost(ns._cost), _state(ns._state), _pi(ns._pi),
kpeter@663
   259
        _in_arc(ns.in_arc), _search_arc_num(ns._search_arc_num),
kpeter@663
   260
        _next_arc(0)
kpeter@601
   261
      {}
kpeter@601
   262
kpeter@605
   263
      // Find next entering arc
kpeter@601
   264
      bool findEnteringArc() {
kpeter@607
   265
        Cost c;
kpeter@663
   266
        for (int e = _next_arc; e < _search_arc_num; ++e) {
kpeter@601
   267
          c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
kpeter@601
   268
          if (c < 0) {
kpeter@601
   269
            _in_arc = e;
kpeter@601
   270
            _next_arc = e + 1;
kpeter@601
   271
            return true;
kpeter@601
   272
          }
kpeter@601
   273
        }
kpeter@601
   274
        for (int e = 0; e < _next_arc; ++e) {
kpeter@601
   275
          c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
kpeter@601
   276
          if (c < 0) {
kpeter@601
   277
            _in_arc = e;
kpeter@601
   278
            _next_arc = e + 1;
kpeter@601
   279
            return true;
kpeter@601
   280
          }
kpeter@601
   281
        }
kpeter@601
   282
        return false;
kpeter@601
   283
      }
kpeter@601
   284
kpeter@601
   285
    }; //class FirstEligiblePivotRule
kpeter@601
   286
kpeter@601
   287
kpeter@605
   288
    // Implementation of the Best Eligible pivot rule
kpeter@601
   289
    class BestEligiblePivotRule
kpeter@601
   290
    {
kpeter@601
   291
    private:
kpeter@601
   292
kpeter@601
   293
      // References to the NetworkSimplex class
kpeter@601
   294
      const IntVector  &_source;
kpeter@601
   295
      const IntVector  &_target;
kpeter@607
   296
      const CostVector &_cost;
kpeter@601
   297
      const IntVector  &_state;
kpeter@607
   298
      const CostVector &_pi;
kpeter@601
   299
      int &_in_arc;
kpeter@663
   300
      int _search_arc_num;
kpeter@601
   301
kpeter@601
   302
    public:
kpeter@601
   303
kpeter@605
   304
      // Constructor
kpeter@601
   305
      BestEligiblePivotRule(NetworkSimplex &ns) :
kpeter@603
   306
        _source(ns._source), _target(ns._target),
kpeter@601
   307
        _cost(ns._cost), _state(ns._state), _pi(ns._pi),
kpeter@663
   308
        _in_arc(ns.in_arc), _search_arc_num(ns._search_arc_num)
kpeter@601
   309
      {}
kpeter@601
   310
kpeter@605
   311
      // Find next entering arc
kpeter@601
   312
      bool findEnteringArc() {
kpeter@607
   313
        Cost c, min = 0;
kpeter@663
   314
        for (int e = 0; e < _search_arc_num; ++e) {
kpeter@601
   315
          c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
kpeter@601
   316
          if (c < min) {
kpeter@601
   317
            min = c;
kpeter@601
   318
            _in_arc = e;
kpeter@601
   319
          }
kpeter@601
   320
        }
kpeter@601
   321
        return min < 0;
kpeter@601
   322
      }
kpeter@601
   323
kpeter@601
   324
    }; //class BestEligiblePivotRule
kpeter@601
   325
kpeter@601
   326
kpeter@605
   327
    // Implementation of the Block Search pivot rule
kpeter@601
   328
    class BlockSearchPivotRule
kpeter@601
   329
    {
kpeter@601
   330
    private:
kpeter@601
   331
kpeter@601
   332
      // References to the NetworkSimplex class
kpeter@601
   333
      const IntVector  &_source;
kpeter@601
   334
      const IntVector  &_target;
kpeter@607
   335
      const CostVector &_cost;
kpeter@601
   336
      const IntVector  &_state;
kpeter@607
   337
      const CostVector &_pi;
kpeter@601
   338
      int &_in_arc;
kpeter@663
   339
      int _search_arc_num;
kpeter@601
   340
kpeter@601
   341
      // Pivot rule data
kpeter@601
   342
      int _block_size;
kpeter@601
   343
      int _next_arc;
kpeter@601
   344
kpeter@601
   345
    public:
kpeter@601
   346
kpeter@605
   347
      // Constructor
kpeter@601
   348
      BlockSearchPivotRule(NetworkSimplex &ns) :
kpeter@603
   349
        _source(ns._source), _target(ns._target),
kpeter@601
   350
        _cost(ns._cost), _state(ns._state), _pi(ns._pi),
kpeter@663
   351
        _in_arc(ns.in_arc), _search_arc_num(ns._search_arc_num),
kpeter@663
   352
        _next_arc(0)
kpeter@601
   353
      {
kpeter@601
   354
        // The main parameters of the pivot rule
kpeter@663
   355
        const double BLOCK_SIZE_FACTOR = 0.5;
kpeter@601
   356
        const int MIN_BLOCK_SIZE = 10;
kpeter@601
   357
alpar@612
   358
        _block_size = std::max( int(BLOCK_SIZE_FACTOR *
kpeter@663
   359
                                    std::sqrt(double(_search_arc_num))),
kpeter@601
   360
                                MIN_BLOCK_SIZE );
kpeter@601
   361
      }
kpeter@601
   362
kpeter@605
   363
      // Find next entering arc
kpeter@601
   364
      bool findEnteringArc() {
kpeter@607
   365
        Cost c, min = 0;
kpeter@601
   366
        int cnt = _block_size;
kpeter@601
   367
        int e, min_arc = _next_arc;
kpeter@663
   368
        for (e = _next_arc; e < _search_arc_num; ++e) {
kpeter@601
   369
          c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
kpeter@601
   370
          if (c < min) {
kpeter@601
   371
            min = c;
kpeter@601
   372
            min_arc = e;
kpeter@601
   373
          }
kpeter@601
   374
          if (--cnt == 0) {
kpeter@601
   375
            if (min < 0) break;
kpeter@601
   376
            cnt = _block_size;
kpeter@601
   377
          }
kpeter@601
   378
        }
kpeter@601
   379
        if (min == 0 || cnt > 0) {
kpeter@601
   380
          for (e = 0; e < _next_arc; ++e) {
kpeter@601
   381
            c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
kpeter@601
   382
            if (c < min) {
kpeter@601
   383
              min = c;
kpeter@601
   384
              min_arc = e;
kpeter@601
   385
            }
kpeter@601
   386
            if (--cnt == 0) {
kpeter@601
   387
              if (min < 0) break;
kpeter@601
   388
              cnt = _block_size;
kpeter@601
   389
            }
kpeter@601
   390
          }
kpeter@601
   391
        }
kpeter@601
   392
        if (min >= 0) return false;
kpeter@601
   393
        _in_arc = min_arc;
kpeter@601
   394
        _next_arc = e;
kpeter@601
   395
        return true;
kpeter@601
   396
      }
kpeter@601
   397
kpeter@601
   398
    }; //class BlockSearchPivotRule
kpeter@601
   399
kpeter@601
   400
kpeter@605
   401
    // Implementation of the Candidate List pivot rule
kpeter@601
   402
    class CandidateListPivotRule
kpeter@601
   403
    {
kpeter@601
   404
    private:
kpeter@601
   405
kpeter@601
   406
      // References to the NetworkSimplex class
kpeter@601
   407
      const IntVector  &_source;
kpeter@601
   408
      const IntVector  &_target;
kpeter@607
   409
      const CostVector &_cost;
kpeter@601
   410
      const IntVector  &_state;
kpeter@607
   411
      const CostVector &_pi;
kpeter@601
   412
      int &_in_arc;
kpeter@663
   413
      int _search_arc_num;
kpeter@601
   414
kpeter@601
   415
      // Pivot rule data
kpeter@601
   416
      IntVector _candidates;
kpeter@601
   417
      int _list_length, _minor_limit;
kpeter@601
   418
      int _curr_length, _minor_count;
kpeter@601
   419
      int _next_arc;
kpeter@601
   420
kpeter@601
   421
    public:
kpeter@601
   422
kpeter@601
   423
      /// Constructor
kpeter@601
   424
      CandidateListPivotRule(NetworkSimplex &ns) :
kpeter@603
   425
        _source(ns._source), _target(ns._target),
kpeter@601
   426
        _cost(ns._cost), _state(ns._state), _pi(ns._pi),
kpeter@663
   427
        _in_arc(ns.in_arc), _search_arc_num(ns._search_arc_num),
kpeter@663
   428
        _next_arc(0)
kpeter@601
   429
      {
kpeter@601
   430
        // The main parameters of the pivot rule
kpeter@601
   431
        const double LIST_LENGTH_FACTOR = 1.0;
kpeter@601
   432
        const int MIN_LIST_LENGTH = 10;
kpeter@601
   433
        const double MINOR_LIMIT_FACTOR = 0.1;
kpeter@601
   434
        const int MIN_MINOR_LIMIT = 3;
kpeter@601
   435
alpar@612
   436
        _list_length = std::max( int(LIST_LENGTH_FACTOR *
kpeter@663
   437
                                     std::sqrt(double(_search_arc_num))),
kpeter@601
   438
                                 MIN_LIST_LENGTH );
kpeter@601
   439
        _minor_limit = std::max( int(MINOR_LIMIT_FACTOR * _list_length),
kpeter@601
   440
                                 MIN_MINOR_LIMIT );
kpeter@601
   441
        _curr_length = _minor_count = 0;
kpeter@601
   442
        _candidates.resize(_list_length);
kpeter@601
   443
      }
kpeter@601
   444
kpeter@601
   445
      /// Find next entering arc
kpeter@601
   446
      bool findEnteringArc() {
kpeter@607
   447
        Cost min, c;
kpeter@601
   448
        int e, min_arc = _next_arc;
kpeter@601
   449
        if (_curr_length > 0 && _minor_count < _minor_limit) {
kpeter@601
   450
          // Minor iteration: select the best eligible arc from the
kpeter@601
   451
          // current candidate list
kpeter@601
   452
          ++_minor_count;
kpeter@601
   453
          min = 0;
kpeter@601
   454
          for (int i = 0; i < _curr_length; ++i) {
kpeter@601
   455
            e = _candidates[i];
kpeter@601
   456
            c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
kpeter@601
   457
            if (c < min) {
kpeter@601
   458
              min = c;
kpeter@601
   459
              min_arc = e;
kpeter@601
   460
            }
kpeter@601
   461
            if (c >= 0) {
kpeter@601
   462
              _candidates[i--] = _candidates[--_curr_length];
kpeter@601
   463
            }
kpeter@601
   464
          }
kpeter@601
   465
          if (min < 0) {
kpeter@601
   466
            _in_arc = min_arc;
kpeter@601
   467
            return true;
kpeter@601
   468
          }
kpeter@601
   469
        }
kpeter@601
   470
kpeter@601
   471
        // Major iteration: build a new candidate list
kpeter@601
   472
        min = 0;
kpeter@601
   473
        _curr_length = 0;
kpeter@663
   474
        for (e = _next_arc; e < _search_arc_num; ++e) {
kpeter@601
   475
          c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
kpeter@601
   476
          if (c < 0) {
kpeter@601
   477
            _candidates[_curr_length++] = e;
kpeter@601
   478
            if (c < min) {
kpeter@601
   479
              min = c;
kpeter@601
   480
              min_arc = e;
kpeter@601
   481
            }
kpeter@601
   482
            if (_curr_length == _list_length) break;
kpeter@601
   483
          }
kpeter@601
   484
        }
kpeter@601
   485
        if (_curr_length < _list_length) {
kpeter@601
   486
          for (e = 0; e < _next_arc; ++e) {
kpeter@601
   487
            c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
kpeter@601
   488
            if (c < 0) {
kpeter@601
   489
              _candidates[_curr_length++] = e;
kpeter@601
   490
              if (c < min) {
kpeter@601
   491
                min = c;
kpeter@601
   492
                min_arc = e;
kpeter@601
   493
              }
kpeter@601
   494
              if (_curr_length == _list_length) break;
kpeter@601
   495
            }
kpeter@601
   496
          }
kpeter@601
   497
        }
kpeter@601
   498
        if (_curr_length == 0) return false;
kpeter@601
   499
        _minor_count = 1;
kpeter@601
   500
        _in_arc = min_arc;
kpeter@601
   501
        _next_arc = e;
kpeter@601
   502
        return true;
kpeter@601
   503
      }
kpeter@601
   504
kpeter@601
   505
    }; //class CandidateListPivotRule
kpeter@601
   506
kpeter@601
   507
kpeter@605
   508
    // Implementation of the Altering Candidate List pivot rule
kpeter@601
   509
    class AlteringListPivotRule
kpeter@601
   510
    {
kpeter@601
   511
    private:
kpeter@601
   512
kpeter@601
   513
      // References to the NetworkSimplex class
kpeter@601
   514
      const IntVector  &_source;
kpeter@601
   515
      const IntVector  &_target;
kpeter@607
   516
      const CostVector &_cost;
kpeter@601
   517
      const IntVector  &_state;
kpeter@607
   518
      const CostVector &_pi;
kpeter@601
   519
      int &_in_arc;
kpeter@663
   520
      int _search_arc_num;
kpeter@601
   521
kpeter@601
   522
      // Pivot rule data
kpeter@601
   523
      int _block_size, _head_length, _curr_length;
kpeter@601
   524
      int _next_arc;
kpeter@601
   525
      IntVector _candidates;
kpeter@607
   526
      CostVector _cand_cost;
kpeter@601
   527
kpeter@601
   528
      // Functor class to compare arcs during sort of the candidate list
kpeter@601
   529
      class SortFunc
kpeter@601
   530
      {
kpeter@601
   531
      private:
kpeter@607
   532
        const CostVector &_map;
kpeter@601
   533
      public:
kpeter@607
   534
        SortFunc(const CostVector &map) : _map(map) {}
kpeter@601
   535
        bool operator()(int left, int right) {
kpeter@601
   536
          return _map[left] > _map[right];
kpeter@601
   537
        }
kpeter@601
   538
      };
kpeter@601
   539
kpeter@601
   540
      SortFunc _sort_func;
kpeter@601
   541
kpeter@601
   542
    public:
kpeter@601
   543
kpeter@605
   544
      // Constructor
kpeter@601
   545
      AlteringListPivotRule(NetworkSimplex &ns) :
kpeter@603
   546
        _source(ns._source), _target(ns._target),
kpeter@601
   547
        _cost(ns._cost), _state(ns._state), _pi(ns._pi),
kpeter@663
   548
        _in_arc(ns.in_arc), _search_arc_num(ns._search_arc_num),
kpeter@663
   549
        _next_arc(0), _cand_cost(ns._search_arc_num), _sort_func(_cand_cost)
kpeter@601
   550
      {
kpeter@601
   551
        // The main parameters of the pivot rule
kpeter@601
   552
        const double BLOCK_SIZE_FACTOR = 1.5;
kpeter@601
   553
        const int MIN_BLOCK_SIZE = 10;
kpeter@601
   554
        const double HEAD_LENGTH_FACTOR = 0.1;
kpeter@601
   555
        const int MIN_HEAD_LENGTH = 3;
kpeter@601
   556
alpar@612
   557
        _block_size = std::max( int(BLOCK_SIZE_FACTOR *
kpeter@663
   558
                                    std::sqrt(double(_search_arc_num))),
kpeter@601
   559
                                MIN_BLOCK_SIZE );
kpeter@601
   560
        _head_length = std::max( int(HEAD_LENGTH_FACTOR * _block_size),
kpeter@601
   561
                                 MIN_HEAD_LENGTH );
kpeter@601
   562
        _candidates.resize(_head_length + _block_size);
kpeter@601
   563
        _curr_length = 0;
kpeter@601
   564
      }
kpeter@601
   565
kpeter@605
   566
      // Find next entering arc
kpeter@601
   567
      bool findEnteringArc() {
kpeter@601
   568
        // Check the current candidate list
kpeter@601
   569
        int e;
kpeter@601
   570
        for (int i = 0; i < _curr_length; ++i) {
kpeter@601
   571
          e = _candidates[i];
kpeter@601
   572
          _cand_cost[e] = _state[e] *
kpeter@601
   573
            (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
kpeter@601
   574
          if (_cand_cost[e] >= 0) {
kpeter@601
   575
            _candidates[i--] = _candidates[--_curr_length];
kpeter@601
   576
          }
kpeter@601
   577
        }
kpeter@601
   578
kpeter@601
   579
        // Extend the list
kpeter@601
   580
        int cnt = _block_size;
kpeter@603
   581
        int last_arc = 0;
kpeter@601
   582
        int limit = _head_length;
kpeter@601
   583
kpeter@663
   584
        for (int e = _next_arc; e < _search_arc_num; ++e) {
kpeter@601
   585
          _cand_cost[e] = _state[e] *
kpeter@601
   586
            (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
kpeter@601
   587
          if (_cand_cost[e] < 0) {
kpeter@601
   588
            _candidates[_curr_length++] = e;
kpeter@603
   589
            last_arc = e;
kpeter@601
   590
          }
kpeter@601
   591
          if (--cnt == 0) {
kpeter@601
   592
            if (_curr_length > limit) break;
kpeter@601
   593
            limit = 0;
kpeter@601
   594
            cnt = _block_size;
kpeter@601
   595
          }
kpeter@601
   596
        }
kpeter@601
   597
        if (_curr_length <= limit) {
kpeter@601
   598
          for (int e = 0; e < _next_arc; ++e) {
kpeter@601
   599
            _cand_cost[e] = _state[e] *
kpeter@601
   600
              (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
kpeter@601
   601
            if (_cand_cost[e] < 0) {
kpeter@601
   602
              _candidates[_curr_length++] = e;
kpeter@603
   603
              last_arc = e;
kpeter@601
   604
            }
kpeter@601
   605
            if (--cnt == 0) {
kpeter@601
   606
              if (_curr_length > limit) break;
kpeter@601
   607
              limit = 0;
kpeter@601
   608
              cnt = _block_size;
kpeter@601
   609
            }
kpeter@601
   610
          }
kpeter@601
   611
        }
kpeter@601
   612
        if (_curr_length == 0) return false;
kpeter@603
   613
        _next_arc = last_arc + 1;
kpeter@601
   614
kpeter@601
   615
        // Make heap of the candidate list (approximating a partial sort)
kpeter@601
   616
        make_heap( _candidates.begin(), _candidates.begin() + _curr_length,
kpeter@601
   617
                   _sort_func );
kpeter@601
   618
kpeter@601
   619
        // Pop the first element of the heap
kpeter@601
   620
        _in_arc = _candidates[0];
kpeter@601
   621
        pop_heap( _candidates.begin(), _candidates.begin() + _curr_length,
kpeter@601
   622
                  _sort_func );
kpeter@601
   623
        _curr_length = std::min(_head_length, _curr_length - 1);
kpeter@601
   624
        return true;
kpeter@601
   625
      }
kpeter@601
   626
kpeter@601
   627
    }; //class AlteringListPivotRule
kpeter@601
   628
kpeter@601
   629
  public:
kpeter@601
   630
kpeter@605
   631
    /// \brief Constructor.
kpeter@601
   632
    ///
kpeter@609
   633
    /// The constructor of the class.
kpeter@601
   634
    ///
kpeter@603
   635
    /// \param graph The digraph the algorithm runs on.
kpeter@605
   636
    NetworkSimplex(const GR& graph) :
kpeter@642
   637
      _graph(graph), _node_id(graph), _arc_id(graph),
kpeter@641
   638
      INF(std::numeric_limits<Value>::has_infinity ?
kpeter@641
   639
          std::numeric_limits<Value>::infinity() :
kpeter@641
   640
          std::numeric_limits<Value>::max())
kpeter@605
   641
    {
kpeter@640
   642
      // Check the value types
kpeter@641
   643
      LEMON_ASSERT(std::numeric_limits<Value>::is_signed,
kpeter@640
   644
        "The flow type of NetworkSimplex must be signed");
kpeter@640
   645
      LEMON_ASSERT(std::numeric_limits<Cost>::is_signed,
kpeter@640
   646
        "The cost type of NetworkSimplex must be signed");
kpeter@642
   647
        
kpeter@642
   648
      // Resize vectors
kpeter@642
   649
      _node_num = countNodes(_graph);
kpeter@642
   650
      _arc_num = countArcs(_graph);
kpeter@642
   651
      int all_node_num = _node_num + 1;
kpeter@663
   652
      int max_arc_num = _arc_num + 2 * _node_num;
kpeter@601
   653
kpeter@663
   654
      _source.resize(max_arc_num);
kpeter@663
   655
      _target.resize(max_arc_num);
kpeter@642
   656
kpeter@663
   657
      _lower.resize(_arc_num);
kpeter@663
   658
      _upper.resize(_arc_num);
kpeter@663
   659
      _cap.resize(max_arc_num);
kpeter@663
   660
      _cost.resize(max_arc_num);
kpeter@642
   661
      _supply.resize(all_node_num);
kpeter@663
   662
      _flow.resize(max_arc_num);
kpeter@642
   663
      _pi.resize(all_node_num);
kpeter@642
   664
kpeter@642
   665
      _parent.resize(all_node_num);
kpeter@642
   666
      _pred.resize(all_node_num);
kpeter@642
   667
      _forward.resize(all_node_num);
kpeter@642
   668
      _thread.resize(all_node_num);
kpeter@642
   669
      _rev_thread.resize(all_node_num);
kpeter@642
   670
      _succ_num.resize(all_node_num);
kpeter@642
   671
      _last_succ.resize(all_node_num);
kpeter@663
   672
      _state.resize(max_arc_num);
kpeter@642
   673
kpeter@642
   674
      // Copy the graph (store the arcs in a mixed order)
kpeter@642
   675
      int i = 0;
kpeter@642
   676
      for (NodeIt n(_graph); n != INVALID; ++n, ++i) {
kpeter@642
   677
        _node_id[n] = i;
kpeter@642
   678
      }
kpeter@642
   679
      int k = std::max(int(std::sqrt(double(_arc_num))), 10);
kpeter@642
   680
      i = 0;
kpeter@642
   681
      for (ArcIt a(_graph); a != INVALID; ++a) {
kpeter@642
   682
        _arc_id[a] = i;
kpeter@642
   683
        _source[i] = _node_id[_graph.source(a)];
kpeter@642
   684
        _target[i] = _node_id[_graph.target(a)];
kpeter@642
   685
        if ((i += k) >= _arc_num) i = (i % k) + 1;
kpeter@642
   686
      }
kpeter@642
   687
      
kpeter@642
   688
      // Initialize maps
kpeter@642
   689
      for (int i = 0; i != _node_num; ++i) {
kpeter@642
   690
        _supply[i] = 0;
kpeter@642
   691
      }
kpeter@642
   692
      for (int i = 0; i != _arc_num; ++i) {
kpeter@642
   693
        _lower[i] = 0;
kpeter@642
   694
        _upper[i] = INF;
kpeter@642
   695
        _cost[i] = 1;
kpeter@642
   696
      }
kpeter@642
   697
      _have_lower = false;
kpeter@642
   698
      _stype = GEQ;
kpeter@601
   699
    }
kpeter@601
   700
kpeter@609
   701
    /// \name Parameters
kpeter@609
   702
    /// The parameters of the algorithm can be specified using these
kpeter@609
   703
    /// functions.
kpeter@609
   704
kpeter@609
   705
    /// @{
kpeter@609
   706
kpeter@605
   707
    /// \brief Set the lower bounds on the arcs.
kpeter@605
   708
    ///
kpeter@605
   709
    /// This function sets the lower bounds on the arcs.
kpeter@640
   710
    /// If it is not used before calling \ref run(), the lower bounds
kpeter@640
   711
    /// will be set to zero on all arcs.
kpeter@605
   712
    ///
kpeter@605
   713
    /// \param map An arc map storing the lower bounds.
kpeter@641
   714
    /// Its \c Value type must be convertible to the \c Value type
kpeter@605
   715
    /// of the algorithm.
kpeter@605
   716
    ///
kpeter@605
   717
    /// \return <tt>(*this)</tt>
kpeter@640
   718
    template <typename LowerMap>
kpeter@640
   719
    NetworkSimplex& lowerMap(const LowerMap& map) {
kpeter@642
   720
      _have_lower = true;
kpeter@605
   721
      for (ArcIt a(_graph); a != INVALID; ++a) {
kpeter@642
   722
        _lower[_arc_id[a]] = map[a];
kpeter@605
   723
      }
kpeter@605
   724
      return *this;
kpeter@605
   725
    }
kpeter@605
   726
kpeter@605
   727
    /// \brief Set the upper bounds (capacities) on the arcs.
kpeter@605
   728
    ///
kpeter@605
   729
    /// This function sets the upper bounds (capacities) on the arcs.
kpeter@640
   730
    /// If it is not used before calling \ref run(), the upper bounds
kpeter@640
   731
    /// will be set to \ref INF on all arcs (i.e. the flow value will be
kpeter@640
   732
    /// unbounded from above on each arc).
kpeter@605
   733
    ///
kpeter@605
   734
    /// \param map An arc map storing the upper bounds.
kpeter@641
   735
    /// Its \c Value type must be convertible to the \c Value type
kpeter@605
   736
    /// of the algorithm.
kpeter@605
   737
    ///
kpeter@605
   738
    /// \return <tt>(*this)</tt>
kpeter@640
   739
    template<typename UpperMap>
kpeter@640
   740
    NetworkSimplex& upperMap(const UpperMap& map) {
kpeter@605
   741
      for (ArcIt a(_graph); a != INVALID; ++a) {
kpeter@642
   742
        _upper[_arc_id[a]] = map[a];
kpeter@605
   743
      }
kpeter@605
   744
      return *this;
kpeter@605
   745
    }
kpeter@605
   746
kpeter@605
   747
    /// \brief Set the costs of the arcs.
kpeter@605
   748
    ///
kpeter@605
   749
    /// This function sets the costs of the arcs.
kpeter@605
   750
    /// If it is not used before calling \ref run(), the costs
kpeter@605
   751
    /// will be set to \c 1 on all arcs.
kpeter@605
   752
    ///
kpeter@605
   753
    /// \param map An arc map storing the costs.
kpeter@607
   754
    /// Its \c Value type must be convertible to the \c Cost type
kpeter@605
   755
    /// of the algorithm.
kpeter@605
   756
    ///
kpeter@605
   757
    /// \return <tt>(*this)</tt>
kpeter@640
   758
    template<typename CostMap>
kpeter@640
   759
    NetworkSimplex& costMap(const CostMap& map) {
kpeter@605
   760
      for (ArcIt a(_graph); a != INVALID; ++a) {
kpeter@642
   761
        _cost[_arc_id[a]] = map[a];
kpeter@605
   762
      }
kpeter@605
   763
      return *this;
kpeter@605
   764
    }
kpeter@605
   765
kpeter@605
   766
    /// \brief Set the supply values of the nodes.
kpeter@605
   767
    ///
kpeter@605
   768
    /// This function sets the supply values of the nodes.
kpeter@605
   769
    /// If neither this function nor \ref stSupply() is used before
kpeter@605
   770
    /// calling \ref run(), the supply of each node will be set to zero.
kpeter@605
   771
    /// (It makes sense only if non-zero lower bounds are given.)
kpeter@605
   772
    ///
kpeter@605
   773
    /// \param map A node map storing the supply values.
kpeter@641
   774
    /// Its \c Value type must be convertible to the \c Value type
kpeter@605
   775
    /// of the algorithm.
kpeter@605
   776
    ///
kpeter@605
   777
    /// \return <tt>(*this)</tt>
kpeter@640
   778
    template<typename SupplyMap>
kpeter@640
   779
    NetworkSimplex& supplyMap(const SupplyMap& map) {
kpeter@605
   780
      for (NodeIt n(_graph); n != INVALID; ++n) {
kpeter@642
   781
        _supply[_node_id[n]] = map[n];
kpeter@605
   782
      }
kpeter@605
   783
      return *this;
kpeter@605
   784
    }
kpeter@605
   785
kpeter@605
   786
    /// \brief Set single source and target nodes and a supply value.
kpeter@605
   787
    ///
kpeter@605
   788
    /// This function sets a single source node and a single target node
kpeter@605
   789
    /// and the required flow value.
kpeter@605
   790
    /// If neither this function nor \ref supplyMap() is used before
kpeter@605
   791
    /// calling \ref run(), the supply of each node will be set to zero.
kpeter@605
   792
    /// (It makes sense only if non-zero lower bounds are given.)
kpeter@605
   793
    ///
kpeter@640
   794
    /// Using this function has the same effect as using \ref supplyMap()
kpeter@640
   795
    /// with such a map in which \c k is assigned to \c s, \c -k is
kpeter@640
   796
    /// assigned to \c t and all other nodes have zero supply value.
kpeter@640
   797
    ///
kpeter@605
   798
    /// \param s The source node.
kpeter@605
   799
    /// \param t The target node.
kpeter@605
   800
    /// \param k The required amount of flow from node \c s to node \c t
kpeter@605
   801
    /// (i.e. the supply of \c s and the demand of \c t).
kpeter@605
   802
    ///
kpeter@605
   803
    /// \return <tt>(*this)</tt>
kpeter@641
   804
    NetworkSimplex& stSupply(const Node& s, const Node& t, Value k) {
kpeter@642
   805
      for (int i = 0; i != _node_num; ++i) {
kpeter@642
   806
        _supply[i] = 0;
kpeter@642
   807
      }
kpeter@642
   808
      _supply[_node_id[s]] =  k;
kpeter@642
   809
      _supply[_node_id[t]] = -k;
kpeter@605
   810
      return *this;
kpeter@605
   811
    }
kpeter@609
   812
    
kpeter@640
   813
    /// \brief Set the type of the supply constraints.
kpeter@609
   814
    ///
kpeter@640
   815
    /// This function sets the type of the supply/demand constraints.
kpeter@640
   816
    /// If it is not used before calling \ref run(), the \ref GEQ supply
kpeter@609
   817
    /// type will be used.
kpeter@609
   818
    ///
kpeter@640
   819
    /// For more information see \ref SupplyType.
kpeter@609
   820
    ///
kpeter@609
   821
    /// \return <tt>(*this)</tt>
kpeter@640
   822
    NetworkSimplex& supplyType(SupplyType supply_type) {
kpeter@640
   823
      _stype = supply_type;
kpeter@609
   824
      return *this;
kpeter@609
   825
    }
kpeter@605
   826
kpeter@609
   827
    /// @}
kpeter@601
   828
kpeter@605
   829
    /// \name Execution Control
kpeter@605
   830
    /// The algorithm can be executed using \ref run().
kpeter@605
   831
kpeter@601
   832
    /// @{
kpeter@601
   833
kpeter@601
   834
    /// \brief Run the algorithm.
kpeter@601
   835
    ///
kpeter@601
   836
    /// This function runs the algorithm.
kpeter@609
   837
    /// The paramters can be specified using functions \ref lowerMap(),
kpeter@640
   838
    /// \ref upperMap(), \ref costMap(), \ref supplyMap(), \ref stSupply(), 
kpeter@642
   839
    /// \ref supplyType().
kpeter@609
   840
    /// For example,
kpeter@605
   841
    /// \code
kpeter@605
   842
    ///   NetworkSimplex<ListDigraph> ns(graph);
kpeter@640
   843
    ///   ns.lowerMap(lower).upperMap(upper).costMap(cost)
kpeter@605
   844
    ///     .supplyMap(sup).run();
kpeter@605
   845
    /// \endcode
kpeter@601
   846
    ///
kpeter@606
   847
    /// This function can be called more than once. All the parameters
kpeter@606
   848
    /// that have been given are kept for the next call, unless
kpeter@606
   849
    /// \ref reset() is called, thus only the modified parameters
kpeter@606
   850
    /// have to be set again. See \ref reset() for examples.
kpeter@642
   851
    /// However the underlying digraph must not be modified after this
kpeter@642
   852
    /// class have been constructed, since it copies and extends the graph.
kpeter@606
   853
    ///
kpeter@605
   854
    /// \param pivot_rule The pivot rule that will be used during the
kpeter@605
   855
    /// algorithm. For more information see \ref PivotRule.
kpeter@601
   856
    ///
kpeter@640
   857
    /// \return \c INFEASIBLE if no feasible flow exists,
kpeter@640
   858
    /// \n \c OPTIMAL if the problem has optimal solution
kpeter@640
   859
    /// (i.e. it is feasible and bounded), and the algorithm has found
kpeter@640
   860
    /// optimal flow and node potentials (primal and dual solutions),
kpeter@640
   861
    /// \n \c UNBOUNDED if the objective function of the problem is
kpeter@640
   862
    /// unbounded, i.e. there is a directed cycle having negative total
kpeter@640
   863
    /// cost and infinite upper bound.
kpeter@640
   864
    ///
kpeter@640
   865
    /// \see ProblemType, PivotRule
kpeter@640
   866
    ProblemType run(PivotRule pivot_rule = BLOCK_SEARCH) {
kpeter@640
   867
      if (!init()) return INFEASIBLE;
kpeter@640
   868
      return start(pivot_rule);
kpeter@601
   869
    }
kpeter@601
   870
kpeter@606
   871
    /// \brief Reset all the parameters that have been given before.
kpeter@606
   872
    ///
kpeter@606
   873
    /// This function resets all the paramaters that have been given
kpeter@609
   874
    /// before using functions \ref lowerMap(), \ref upperMap(),
kpeter@642
   875
    /// \ref costMap(), \ref supplyMap(), \ref stSupply(), \ref supplyType().
kpeter@606
   876
    ///
kpeter@606
   877
    /// It is useful for multiple run() calls. If this function is not
kpeter@606
   878
    /// used, all the parameters given before are kept for the next
kpeter@606
   879
    /// \ref run() call.
kpeter@642
   880
    /// However the underlying digraph must not be modified after this
kpeter@642
   881
    /// class have been constructed, since it copies and extends the graph.
kpeter@606
   882
    ///
kpeter@606
   883
    /// For example,
kpeter@606
   884
    /// \code
kpeter@606
   885
    ///   NetworkSimplex<ListDigraph> ns(graph);
kpeter@606
   886
    ///
kpeter@606
   887
    ///   // First run
kpeter@640
   888
    ///   ns.lowerMap(lower).upperMap(upper).costMap(cost)
kpeter@606
   889
    ///     .supplyMap(sup).run();
kpeter@606
   890
    ///
kpeter@606
   891
    ///   // Run again with modified cost map (reset() is not called,
kpeter@606
   892
    ///   // so only the cost map have to be set again)
kpeter@606
   893
    ///   cost[e] += 100;
kpeter@606
   894
    ///   ns.costMap(cost).run();
kpeter@606
   895
    ///
kpeter@606
   896
    ///   // Run again from scratch using reset()
kpeter@606
   897
    ///   // (the lower bounds will be set to zero on all arcs)
kpeter@606
   898
    ///   ns.reset();
kpeter@640
   899
    ///   ns.upperMap(capacity).costMap(cost)
kpeter@606
   900
    ///     .supplyMap(sup).run();
kpeter@606
   901
    /// \endcode
kpeter@606
   902
    ///
kpeter@606
   903
    /// \return <tt>(*this)</tt>
kpeter@606
   904
    NetworkSimplex& reset() {
kpeter@642
   905
      for (int i = 0; i != _node_num; ++i) {
kpeter@642
   906
        _supply[i] = 0;
kpeter@642
   907
      }
kpeter@642
   908
      for (int i = 0; i != _arc_num; ++i) {
kpeter@642
   909
        _lower[i] = 0;
kpeter@642
   910
        _upper[i] = INF;
kpeter@642
   911
        _cost[i] = 1;
kpeter@642
   912
      }
kpeter@642
   913
      _have_lower = false;
kpeter@640
   914
      _stype = GEQ;
kpeter@606
   915
      return *this;
kpeter@606
   916
    }
kpeter@606
   917
kpeter@601
   918
    /// @}
kpeter@601
   919
kpeter@601
   920
    /// \name Query Functions
kpeter@601
   921
    /// The results of the algorithm can be obtained using these
kpeter@601
   922
    /// functions.\n
kpeter@605
   923
    /// The \ref run() function must be called before using them.
kpeter@605
   924
kpeter@601
   925
    /// @{
kpeter@601
   926
kpeter@605
   927
    /// \brief Return the total cost of the found flow.
kpeter@605
   928
    ///
kpeter@605
   929
    /// This function returns the total cost of the found flow.
kpeter@640
   930
    /// Its complexity is O(e).
kpeter@605
   931
    ///
kpeter@605
   932
    /// \note The return type of the function can be specified as a
kpeter@605
   933
    /// template parameter. For example,
kpeter@605
   934
    /// \code
kpeter@605
   935
    ///   ns.totalCost<double>();
kpeter@605
   936
    /// \endcode
kpeter@607
   937
    /// It is useful if the total cost cannot be stored in the \c Cost
kpeter@605
   938
    /// type of the algorithm, which is the default return type of the
kpeter@605
   939
    /// function.
kpeter@605
   940
    ///
kpeter@605
   941
    /// \pre \ref run() must be called before using this function.
kpeter@642
   942
    template <typename Number>
kpeter@642
   943
    Number totalCost() const {
kpeter@642
   944
      Number c = 0;
kpeter@642
   945
      for (ArcIt a(_graph); a != INVALID; ++a) {
kpeter@642
   946
        int i = _arc_id[a];
kpeter@642
   947
        c += Number(_flow[i]) * Number(_cost[i]);
kpeter@605
   948
      }
kpeter@605
   949
      return c;
kpeter@605
   950
    }
kpeter@605
   951
kpeter@605
   952
#ifndef DOXYGEN
kpeter@607
   953
    Cost totalCost() const {
kpeter@607
   954
      return totalCost<Cost>();
kpeter@605
   955
    }
kpeter@605
   956
#endif
kpeter@605
   957
kpeter@605
   958
    /// \brief Return the flow on the given arc.
kpeter@605
   959
    ///
kpeter@605
   960
    /// This function returns the flow on the given arc.
kpeter@605
   961
    ///
kpeter@605
   962
    /// \pre \ref run() must be called before using this function.
kpeter@641
   963
    Value flow(const Arc& a) const {
kpeter@642
   964
      return _flow[_arc_id[a]];
kpeter@605
   965
    }
kpeter@605
   966
kpeter@642
   967
    /// \brief Return the flow map (the primal solution).
kpeter@601
   968
    ///
kpeter@642
   969
    /// This function copies the flow value on each arc into the given
kpeter@642
   970
    /// map. The \c Value type of the algorithm must be convertible to
kpeter@642
   971
    /// the \c Value type of the map.
kpeter@601
   972
    ///
kpeter@601
   973
    /// \pre \ref run() must be called before using this function.
kpeter@642
   974
    template <typename FlowMap>
kpeter@642
   975
    void flowMap(FlowMap &map) const {
kpeter@642
   976
      for (ArcIt a(_graph); a != INVALID; ++a) {
kpeter@642
   977
        map.set(a, _flow[_arc_id[a]]);
kpeter@642
   978
      }
kpeter@601
   979
    }
kpeter@601
   980
kpeter@605
   981
    /// \brief Return the potential (dual value) of the given node.
kpeter@605
   982
    ///
kpeter@605
   983
    /// This function returns the potential (dual value) of the
kpeter@605
   984
    /// given node.
kpeter@605
   985
    ///
kpeter@605
   986
    /// \pre \ref run() must be called before using this function.
kpeter@607
   987
    Cost potential(const Node& n) const {
kpeter@642
   988
      return _pi[_node_id[n]];
kpeter@605
   989
    }
kpeter@605
   990
kpeter@642
   991
    /// \brief Return the potential map (the dual solution).
kpeter@601
   992
    ///
kpeter@642
   993
    /// This function copies the potential (dual value) of each node
kpeter@642
   994
    /// into the given map.
kpeter@642
   995
    /// The \c Cost type of the algorithm must be convertible to the
kpeter@642
   996
    /// \c Value type of the map.
kpeter@601
   997
    ///
kpeter@601
   998
    /// \pre \ref run() must be called before using this function.
kpeter@642
   999
    template <typename PotentialMap>
kpeter@642
  1000
    void potentialMap(PotentialMap &map) const {
kpeter@642
  1001
      for (NodeIt n(_graph); n != INVALID; ++n) {
kpeter@642
  1002
        map.set(n, _pi[_node_id[n]]);
kpeter@642
  1003
      }
kpeter@601
  1004
    }
kpeter@601
  1005
kpeter@601
  1006
    /// @}
kpeter@601
  1007
kpeter@601
  1008
  private:
kpeter@601
  1009
kpeter@601
  1010
    // Initialize internal data structures
kpeter@601
  1011
    bool init() {
kpeter@605
  1012
      if (_node_num == 0) return false;
kpeter@601
  1013
kpeter@642
  1014
      // Check the sum of supply values
kpeter@642
  1015
      _sum_supply = 0;
kpeter@642
  1016
      for (int i = 0; i != _node_num; ++i) {
kpeter@642
  1017
        _sum_supply += _supply[i];
kpeter@642
  1018
      }
alpar@643
  1019
      if ( !((_stype == GEQ && _sum_supply <= 0) ||
alpar@643
  1020
             (_stype == LEQ && _sum_supply >= 0)) ) return false;
kpeter@601
  1021
kpeter@642
  1022
      // Remove non-zero lower bounds
kpeter@642
  1023
      if (_have_lower) {
kpeter@642
  1024
        for (int i = 0; i != _arc_num; ++i) {
kpeter@642
  1025
          Value c = _lower[i];
kpeter@642
  1026
          if (c >= 0) {
kpeter@642
  1027
            _cap[i] = _upper[i] < INF ? _upper[i] - c : INF;
kpeter@642
  1028
          } else {
kpeter@642
  1029
            _cap[i] = _upper[i] < INF + c ? _upper[i] - c : INF;
kpeter@642
  1030
          }
kpeter@642
  1031
          _supply[_source[i]] -= c;
kpeter@642
  1032
          _supply[_target[i]] += c;
kpeter@642
  1033
        }
kpeter@642
  1034
      } else {
kpeter@642
  1035
        for (int i = 0; i != _arc_num; ++i) {
kpeter@642
  1036
          _cap[i] = _upper[i];
kpeter@642
  1037
        }
kpeter@605
  1038
      }
kpeter@601
  1039
kpeter@609
  1040
      // Initialize artifical cost
kpeter@640
  1041
      Cost ART_COST;
kpeter@609
  1042
      if (std::numeric_limits<Cost>::is_exact) {
kpeter@663
  1043
        ART_COST = std::numeric_limits<Cost>::max() / 2 + 1;
kpeter@609
  1044
      } else {
kpeter@891
  1045
        ART_COST = 0;
kpeter@609
  1046
        for (int i = 0; i != _arc_num; ++i) {
kpeter@640
  1047
          if (_cost[i] > ART_COST) ART_COST = _cost[i];
kpeter@609
  1048
        }
kpeter@640
  1049
        ART_COST = (ART_COST + 1) * _node_num;
kpeter@609
  1050
      }
kpeter@609
  1051
kpeter@642
  1052
      // Initialize arc maps
kpeter@642
  1053
      for (int i = 0; i != _arc_num; ++i) {
kpeter@642
  1054
        _flow[i] = 0;
kpeter@642
  1055
        _state[i] = STATE_LOWER;
kpeter@642
  1056
      }
kpeter@642
  1057
      
kpeter@601
  1058
      // Set data for the artificial root node
kpeter@601
  1059
      _root = _node_num;
kpeter@601
  1060
      _parent[_root] = -1;
kpeter@601
  1061
      _pred[_root] = -1;
kpeter@601
  1062
      _thread[_root] = 0;
kpeter@604
  1063
      _rev_thread[0] = _root;
kpeter@642
  1064
      _succ_num[_root] = _node_num + 1;
kpeter@604
  1065
      _last_succ[_root] = _root - 1;
kpeter@640
  1066
      _supply[_root] = -_sum_supply;
kpeter@663
  1067
      _pi[_root] = 0;
kpeter@601
  1068
kpeter@601
  1069
      // Add artificial arcs and initialize the spanning tree data structure
kpeter@663
  1070
      if (_sum_supply == 0) {
kpeter@663
  1071
        // EQ supply constraints
kpeter@663
  1072
        _search_arc_num = _arc_num;
kpeter@663
  1073
        _all_arc_num = _arc_num + _node_num;
kpeter@663
  1074
        for (int u = 0, e = _arc_num; u != _node_num; ++u, ++e) {
kpeter@663
  1075
          _parent[u] = _root;
kpeter@663
  1076
          _pred[u] = e;
kpeter@663
  1077
          _thread[u] = u + 1;
kpeter@663
  1078
          _rev_thread[u + 1] = u;
kpeter@663
  1079
          _succ_num[u] = 1;
kpeter@663
  1080
          _last_succ[u] = u;
kpeter@663
  1081
          _cap[e] = INF;
kpeter@663
  1082
          _state[e] = STATE_TREE;
kpeter@663
  1083
          if (_supply[u] >= 0) {
kpeter@663
  1084
            _forward[u] = true;
kpeter@663
  1085
            _pi[u] = 0;
kpeter@663
  1086
            _source[e] = u;
kpeter@663
  1087
            _target[e] = _root;
kpeter@663
  1088
            _flow[e] = _supply[u];
kpeter@663
  1089
            _cost[e] = 0;
kpeter@663
  1090
          } else {
kpeter@663
  1091
            _forward[u] = false;
kpeter@663
  1092
            _pi[u] = ART_COST;
kpeter@663
  1093
            _source[e] = _root;
kpeter@663
  1094
            _target[e] = u;
kpeter@663
  1095
            _flow[e] = -_supply[u];
kpeter@663
  1096
            _cost[e] = ART_COST;
kpeter@663
  1097
          }
kpeter@601
  1098
        }
kpeter@601
  1099
      }
kpeter@663
  1100
      else if (_sum_supply > 0) {
kpeter@663
  1101
        // LEQ supply constraints
kpeter@663
  1102
        _search_arc_num = _arc_num + _node_num;
kpeter@663
  1103
        int f = _arc_num + _node_num;
kpeter@663
  1104
        for (int u = 0, e = _arc_num; u != _node_num; ++u, ++e) {
kpeter@663
  1105
          _parent[u] = _root;
kpeter@663
  1106
          _thread[u] = u + 1;
kpeter@663
  1107
          _rev_thread[u + 1] = u;
kpeter@663
  1108
          _succ_num[u] = 1;
kpeter@663
  1109
          _last_succ[u] = u;
kpeter@663
  1110
          if (_supply[u] >= 0) {
kpeter@663
  1111
            _forward[u] = true;
kpeter@663
  1112
            _pi[u] = 0;
kpeter@663
  1113
            _pred[u] = e;
kpeter@663
  1114
            _source[e] = u;
kpeter@663
  1115
            _target[e] = _root;
kpeter@663
  1116
            _cap[e] = INF;
kpeter@663
  1117
            _flow[e] = _supply[u];
kpeter@663
  1118
            _cost[e] = 0;
kpeter@663
  1119
            _state[e] = STATE_TREE;
kpeter@663
  1120
          } else {
kpeter@663
  1121
            _forward[u] = false;
kpeter@663
  1122
            _pi[u] = ART_COST;
kpeter@663
  1123
            _pred[u] = f;
kpeter@663
  1124
            _source[f] = _root;
kpeter@663
  1125
            _target[f] = u;
kpeter@663
  1126
            _cap[f] = INF;
kpeter@663
  1127
            _flow[f] = -_supply[u];
kpeter@663
  1128
            _cost[f] = ART_COST;
kpeter@663
  1129
            _state[f] = STATE_TREE;
kpeter@663
  1130
            _source[e] = u;
kpeter@663
  1131
            _target[e] = _root;
kpeter@663
  1132
            _cap[e] = INF;
kpeter@663
  1133
            _flow[e] = 0;
kpeter@663
  1134
            _cost[e] = 0;
kpeter@663
  1135
            _state[e] = STATE_LOWER;
kpeter@663
  1136
            ++f;
kpeter@663
  1137
          }
kpeter@663
  1138
        }
kpeter@663
  1139
        _all_arc_num = f;
kpeter@663
  1140
      }
kpeter@663
  1141
      else {
kpeter@663
  1142
        // GEQ supply constraints
kpeter@663
  1143
        _search_arc_num = _arc_num + _node_num;
kpeter@663
  1144
        int f = _arc_num + _node_num;
kpeter@663
  1145
        for (int u = 0, e = _arc_num; u != _node_num; ++u, ++e) {
kpeter@663
  1146
          _parent[u] = _root;
kpeter@663
  1147
          _thread[u] = u + 1;
kpeter@663
  1148
          _rev_thread[u + 1] = u;
kpeter@663
  1149
          _succ_num[u] = 1;
kpeter@663
  1150
          _last_succ[u] = u;
kpeter@663
  1151
          if (_supply[u] <= 0) {
kpeter@663
  1152
            _forward[u] = false;
kpeter@663
  1153
            _pi[u] = 0;
kpeter@663
  1154
            _pred[u] = e;
kpeter@663
  1155
            _source[e] = _root;
kpeter@663
  1156
            _target[e] = u;
kpeter@663
  1157
            _cap[e] = INF;
kpeter@663
  1158
            _flow[e] = -_supply[u];
kpeter@663
  1159
            _cost[e] = 0;
kpeter@663
  1160
            _state[e] = STATE_TREE;
kpeter@663
  1161
          } else {
kpeter@663
  1162
            _forward[u] = true;
kpeter@663
  1163
            _pi[u] = -ART_COST;
kpeter@663
  1164
            _pred[u] = f;
kpeter@663
  1165
            _source[f] = u;
kpeter@663
  1166
            _target[f] = _root;
kpeter@663
  1167
            _cap[f] = INF;
kpeter@663
  1168
            _flow[f] = _supply[u];
kpeter@663
  1169
            _state[f] = STATE_TREE;
kpeter@663
  1170
            _cost[f] = ART_COST;
kpeter@663
  1171
            _source[e] = _root;
kpeter@663
  1172
            _target[e] = u;
kpeter@663
  1173
            _cap[e] = INF;
kpeter@663
  1174
            _flow[e] = 0;
kpeter@663
  1175
            _cost[e] = 0;
kpeter@663
  1176
            _state[e] = STATE_LOWER;
kpeter@663
  1177
            ++f;
kpeter@663
  1178
          }
kpeter@663
  1179
        }
kpeter@663
  1180
        _all_arc_num = f;
kpeter@663
  1181
      }
kpeter@601
  1182
kpeter@601
  1183
      return true;
kpeter@601
  1184
    }
kpeter@601
  1185
kpeter@601
  1186
    // Find the join node
kpeter@601
  1187
    void findJoinNode() {
kpeter@603
  1188
      int u = _source[in_arc];
kpeter@603
  1189
      int v = _target[in_arc];
kpeter@601
  1190
      while (u != v) {
kpeter@604
  1191
        if (_succ_num[u] < _succ_num[v]) {
kpeter@604
  1192
          u = _parent[u];
kpeter@604
  1193
        } else {
kpeter@604
  1194
          v = _parent[v];
kpeter@604
  1195
        }
kpeter@601
  1196
      }
kpeter@601
  1197
      join = u;
kpeter@601
  1198
    }
kpeter@601
  1199
kpeter@601
  1200
    // Find the leaving arc of the cycle and returns true if the
kpeter@601
  1201
    // leaving arc is not the same as the entering arc
kpeter@601
  1202
    bool findLeavingArc() {
kpeter@601
  1203
      // Initialize first and second nodes according to the direction
kpeter@601
  1204
      // of the cycle
kpeter@603
  1205
      if (_state[in_arc] == STATE_LOWER) {
kpeter@603
  1206
        first  = _source[in_arc];
kpeter@603
  1207
        second = _target[in_arc];
kpeter@601
  1208
      } else {
kpeter@603
  1209
        first  = _target[in_arc];
kpeter@603
  1210
        second = _source[in_arc];
kpeter@601
  1211
      }
kpeter@603
  1212
      delta = _cap[in_arc];
kpeter@601
  1213
      int result = 0;
kpeter@641
  1214
      Value d;
kpeter@601
  1215
      int e;
kpeter@601
  1216
kpeter@601
  1217
      // Search the cycle along the path form the first node to the root
kpeter@601
  1218
      for (int u = first; u != join; u = _parent[u]) {
kpeter@601
  1219
        e = _pred[u];
kpeter@640
  1220
        d = _forward[u] ?
kpeter@640
  1221
          _flow[e] : (_cap[e] == INF ? INF : _cap[e] - _flow[e]);
kpeter@601
  1222
        if (d < delta) {
kpeter@601
  1223
          delta = d;
kpeter@601
  1224
          u_out = u;
kpeter@601
  1225
          result = 1;
kpeter@601
  1226
        }
kpeter@601
  1227
      }
kpeter@601
  1228
      // Search the cycle along the path form the second node to the root
kpeter@601
  1229
      for (int u = second; u != join; u = _parent[u]) {
kpeter@601
  1230
        e = _pred[u];
kpeter@640
  1231
        d = _forward[u] ? 
kpeter@640
  1232
          (_cap[e] == INF ? INF : _cap[e] - _flow[e]) : _flow[e];
kpeter@601
  1233
        if (d <= delta) {
kpeter@601
  1234
          delta = d;
kpeter@601
  1235
          u_out = u;
kpeter@601
  1236
          result = 2;
kpeter@601
  1237
        }
kpeter@601
  1238
      }
kpeter@601
  1239
kpeter@601
  1240
      if (result == 1) {
kpeter@601
  1241
        u_in = first;
kpeter@601
  1242
        v_in = second;
kpeter@601
  1243
      } else {
kpeter@601
  1244
        u_in = second;
kpeter@601
  1245
        v_in = first;
kpeter@601
  1246
      }
kpeter@601
  1247
      return result != 0;
kpeter@601
  1248
    }
kpeter@601
  1249
kpeter@601
  1250
    // Change _flow and _state vectors
kpeter@601
  1251
    void changeFlow(bool change) {
kpeter@601
  1252
      // Augment along the cycle
kpeter@601
  1253
      if (delta > 0) {
kpeter@641
  1254
        Value val = _state[in_arc] * delta;
kpeter@603
  1255
        _flow[in_arc] += val;
kpeter@603
  1256
        for (int u = _source[in_arc]; u != join; u = _parent[u]) {
kpeter@601
  1257
          _flow[_pred[u]] += _forward[u] ? -val : val;
kpeter@601
  1258
        }
kpeter@603
  1259
        for (int u = _target[in_arc]; u != join; u = _parent[u]) {
kpeter@601
  1260
          _flow[_pred[u]] += _forward[u] ? val : -val;
kpeter@601
  1261
        }
kpeter@601
  1262
      }
kpeter@601
  1263
      // Update the state of the entering and leaving arcs
kpeter@601
  1264
      if (change) {
kpeter@603
  1265
        _state[in_arc] = STATE_TREE;
kpeter@601
  1266
        _state[_pred[u_out]] =
kpeter@601
  1267
          (_flow[_pred[u_out]] == 0) ? STATE_LOWER : STATE_UPPER;
kpeter@601
  1268
      } else {
kpeter@603
  1269
        _state[in_arc] = -_state[in_arc];
kpeter@601
  1270
      }
kpeter@601
  1271
    }
kpeter@601
  1272
kpeter@604
  1273
    // Update the tree structure
kpeter@604
  1274
    void updateTreeStructure() {
kpeter@604
  1275
      int u, w;
kpeter@604
  1276
      int old_rev_thread = _rev_thread[u_out];
kpeter@604
  1277
      int old_succ_num = _succ_num[u_out];
kpeter@604
  1278
      int old_last_succ = _last_succ[u_out];
kpeter@601
  1279
      v_out = _parent[u_out];
kpeter@601
  1280
kpeter@604
  1281
      u = _last_succ[u_in];  // the last successor of u_in
kpeter@604
  1282
      right = _thread[u];    // the node after it
kpeter@604
  1283
kpeter@604
  1284
      // Handle the case when old_rev_thread equals to v_in
kpeter@604
  1285
      // (it also means that join and v_out coincide)
kpeter@604
  1286
      if (old_rev_thread == v_in) {
kpeter@604
  1287
        last = _thread[_last_succ[u_out]];
kpeter@604
  1288
      } else {
kpeter@604
  1289
        last = _thread[v_in];
kpeter@601
  1290
      }
kpeter@601
  1291
kpeter@604
  1292
      // Update _thread and _parent along the stem nodes (i.e. the nodes
kpeter@604
  1293
      // between u_in and u_out, whose parent have to be changed)
kpeter@601
  1294
      _thread[v_in] = stem = u_in;
kpeter@604
  1295
      _dirty_revs.clear();
kpeter@604
  1296
      _dirty_revs.push_back(v_in);
kpeter@601
  1297
      par_stem = v_in;
kpeter@601
  1298
      while (stem != u_out) {
kpeter@604
  1299
        // Insert the next stem node into the thread list
kpeter@604
  1300
        new_stem = _parent[stem];
kpeter@604
  1301
        _thread[u] = new_stem;
kpeter@604
  1302
        _dirty_revs.push_back(u);
kpeter@601
  1303
kpeter@604
  1304
        // Remove the subtree of stem from the thread list
kpeter@604
  1305
        w = _rev_thread[stem];
kpeter@604
  1306
        _thread[w] = right;
kpeter@604
  1307
        _rev_thread[right] = w;
kpeter@601
  1308
kpeter@604
  1309
        // Change the parent node and shift stem nodes
kpeter@601
  1310
        _parent[stem] = par_stem;
kpeter@601
  1311
        par_stem = stem;
kpeter@601
  1312
        stem = new_stem;
kpeter@601
  1313
kpeter@604
  1314
        // Update u and right
kpeter@604
  1315
        u = _last_succ[stem] == _last_succ[par_stem] ?
kpeter@604
  1316
          _rev_thread[par_stem] : _last_succ[stem];
kpeter@601
  1317
        right = _thread[u];
kpeter@601
  1318
      }
kpeter@601
  1319
      _parent[u_out] = par_stem;
kpeter@601
  1320
      _thread[u] = last;
kpeter@604
  1321
      _rev_thread[last] = u;
kpeter@604
  1322
      _last_succ[u_out] = u;
kpeter@601
  1323
kpeter@604
  1324
      // Remove the subtree of u_out from the thread list except for
kpeter@604
  1325
      // the case when old_rev_thread equals to v_in
kpeter@604
  1326
      // (it also means that join and v_out coincide)
kpeter@604
  1327
      if (old_rev_thread != v_in) {
kpeter@604
  1328
        _thread[old_rev_thread] = right;
kpeter@604
  1329
        _rev_thread[right] = old_rev_thread;
kpeter@604
  1330
      }
kpeter@604
  1331
kpeter@604
  1332
      // Update _rev_thread using the new _thread values
kpeter@604
  1333
      for (int i = 0; i < int(_dirty_revs.size()); ++i) {
kpeter@604
  1334
        u = _dirty_revs[i];
kpeter@604
  1335
        _rev_thread[_thread[u]] = u;
kpeter@604
  1336
      }
kpeter@604
  1337
kpeter@604
  1338
      // Update _pred, _forward, _last_succ and _succ_num for the
kpeter@604
  1339
      // stem nodes from u_out to u_in
kpeter@604
  1340
      int tmp_sc = 0, tmp_ls = _last_succ[u_out];
kpeter@604
  1341
      u = u_out;
kpeter@604
  1342
      while (u != u_in) {
kpeter@604
  1343
        w = _parent[u];
kpeter@604
  1344
        _pred[u] = _pred[w];
kpeter@604
  1345
        _forward[u] = !_forward[w];
kpeter@604
  1346
        tmp_sc += _succ_num[u] - _succ_num[w];
kpeter@604
  1347
        _succ_num[u] = tmp_sc;
kpeter@604
  1348
        _last_succ[w] = tmp_ls;
kpeter@604
  1349
        u = w;
kpeter@604
  1350
      }
kpeter@604
  1351
      _pred[u_in] = in_arc;
kpeter@604
  1352
      _forward[u_in] = (u_in == _source[in_arc]);
kpeter@604
  1353
      _succ_num[u_in] = old_succ_num;
kpeter@604
  1354
kpeter@604
  1355
      // Set limits for updating _last_succ form v_in and v_out
kpeter@604
  1356
      // towards the root
kpeter@604
  1357
      int up_limit_in = -1;
kpeter@604
  1358
      int up_limit_out = -1;
kpeter@604
  1359
      if (_last_succ[join] == v_in) {
kpeter@604
  1360
        up_limit_out = join;
kpeter@601
  1361
      } else {
kpeter@604
  1362
        up_limit_in = join;
kpeter@604
  1363
      }
kpeter@604
  1364
kpeter@604
  1365
      // Update _last_succ from v_in towards the root
kpeter@604
  1366
      for (u = v_in; u != up_limit_in && _last_succ[u] == v_in;
kpeter@604
  1367
           u = _parent[u]) {
kpeter@604
  1368
        _last_succ[u] = _last_succ[u_out];
kpeter@604
  1369
      }
kpeter@604
  1370
      // Update _last_succ from v_out towards the root
kpeter@604
  1371
      if (join != old_rev_thread && v_in != old_rev_thread) {
kpeter@604
  1372
        for (u = v_out; u != up_limit_out && _last_succ[u] == old_last_succ;
kpeter@604
  1373
             u = _parent[u]) {
kpeter@604
  1374
          _last_succ[u] = old_rev_thread;
kpeter@604
  1375
        }
kpeter@604
  1376
      } else {
kpeter@604
  1377
        for (u = v_out; u != up_limit_out && _last_succ[u] == old_last_succ;
kpeter@604
  1378
             u = _parent[u]) {
kpeter@604
  1379
          _last_succ[u] = _last_succ[u_out];
kpeter@604
  1380
        }
kpeter@604
  1381
      }
kpeter@604
  1382
kpeter@604
  1383
      // Update _succ_num from v_in to join
kpeter@604
  1384
      for (u = v_in; u != join; u = _parent[u]) {
kpeter@604
  1385
        _succ_num[u] += old_succ_num;
kpeter@604
  1386
      }
kpeter@604
  1387
      // Update _succ_num from v_out to join
kpeter@604
  1388
      for (u = v_out; u != join; u = _parent[u]) {
kpeter@604
  1389
        _succ_num[u] -= old_succ_num;
kpeter@601
  1390
      }
kpeter@601
  1391
    }
kpeter@601
  1392
kpeter@604
  1393
    // Update potentials
kpeter@604
  1394
    void updatePotential() {
kpeter@607
  1395
      Cost sigma = _forward[u_in] ?
kpeter@601
  1396
        _pi[v_in] - _pi[u_in] - _cost[_pred[u_in]] :
kpeter@601
  1397
        _pi[v_in] - _pi[u_in] + _cost[_pred[u_in]];
kpeter@608
  1398
      // Update potentials in the subtree, which has been moved
kpeter@608
  1399
      int end = _thread[_last_succ[u_in]];
kpeter@608
  1400
      for (int u = u_in; u != end; u = _thread[u]) {
kpeter@608
  1401
        _pi[u] += sigma;
kpeter@601
  1402
      }
kpeter@601
  1403
    }
kpeter@601
  1404
kpeter@601
  1405
    // Execute the algorithm
kpeter@640
  1406
    ProblemType start(PivotRule pivot_rule) {
kpeter@601
  1407
      // Select the pivot rule implementation
kpeter@601
  1408
      switch (pivot_rule) {
kpeter@605
  1409
        case FIRST_ELIGIBLE:
kpeter@601
  1410
          return start<FirstEligiblePivotRule>();
kpeter@605
  1411
        case BEST_ELIGIBLE:
kpeter@601
  1412
          return start<BestEligiblePivotRule>();
kpeter@605
  1413
        case BLOCK_SEARCH:
kpeter@601
  1414
          return start<BlockSearchPivotRule>();
kpeter@605
  1415
        case CANDIDATE_LIST:
kpeter@601
  1416
          return start<CandidateListPivotRule>();
kpeter@605
  1417
        case ALTERING_LIST:
kpeter@601
  1418
          return start<AlteringListPivotRule>();
kpeter@601
  1419
      }
kpeter@640
  1420
      return INFEASIBLE; // avoid warning
kpeter@601
  1421
    }
kpeter@601
  1422
kpeter@605
  1423
    template <typename PivotRuleImpl>
kpeter@640
  1424
    ProblemType start() {
kpeter@605
  1425
      PivotRuleImpl pivot(*this);
kpeter@601
  1426
kpeter@605
  1427
      // Execute the Network Simplex algorithm
kpeter@601
  1428
      while (pivot.findEnteringArc()) {
kpeter@601
  1429
        findJoinNode();
kpeter@601
  1430
        bool change = findLeavingArc();
kpeter@640
  1431
        if (delta >= INF) return UNBOUNDED;
kpeter@601
  1432
        changeFlow(change);
kpeter@601
  1433
        if (change) {
kpeter@604
  1434
          updateTreeStructure();
kpeter@604
  1435
          updatePotential();
kpeter@601
  1436
        }
kpeter@601
  1437
      }
kpeter@640
  1438
      
kpeter@640
  1439
      // Check feasibility
kpeter@663
  1440
      for (int e = _search_arc_num; e != _all_arc_num; ++e) {
kpeter@663
  1441
        if (_flow[e] != 0) return INFEASIBLE;
kpeter@640
  1442
      }
kpeter@601
  1443
kpeter@642
  1444
      // Transform the solution and the supply map to the original form
kpeter@642
  1445
      if (_have_lower) {
kpeter@601
  1446
        for (int i = 0; i != _arc_num; ++i) {
kpeter@642
  1447
          Value c = _lower[i];
kpeter@642
  1448
          if (c != 0) {
kpeter@642
  1449
            _flow[i] += c;
kpeter@642
  1450
            _supply[_source[i]] += c;
kpeter@642
  1451
            _supply[_target[i]] -= c;
kpeter@642
  1452
          }
kpeter@601
  1453
        }
kpeter@601
  1454
      }
kpeter@663
  1455
      
kpeter@663
  1456
      // Shift potentials to meet the requirements of the GEQ/LEQ type
kpeter@663
  1457
      // optimality conditions
kpeter@663
  1458
      if (_sum_supply == 0) {
kpeter@663
  1459
        if (_stype == GEQ) {
kpeter@891
  1460
          Cost max_pot = -std::numeric_limits<Cost>::max();
kpeter@663
  1461
          for (int i = 0; i != _node_num; ++i) {
kpeter@663
  1462
            if (_pi[i] > max_pot) max_pot = _pi[i];
kpeter@663
  1463
          }
kpeter@663
  1464
          if (max_pot > 0) {
kpeter@663
  1465
            for (int i = 0; i != _node_num; ++i)
kpeter@663
  1466
              _pi[i] -= max_pot;
kpeter@663
  1467
          }
kpeter@663
  1468
        } else {
kpeter@663
  1469
          Cost min_pot = std::numeric_limits<Cost>::max();
kpeter@663
  1470
          for (int i = 0; i != _node_num; ++i) {
kpeter@663
  1471
            if (_pi[i] < min_pot) min_pot = _pi[i];
kpeter@663
  1472
          }
kpeter@663
  1473
          if (min_pot < 0) {
kpeter@663
  1474
            for (int i = 0; i != _node_num; ++i)
kpeter@663
  1475
              _pi[i] -= min_pot;
kpeter@663
  1476
          }
kpeter@663
  1477
        }
kpeter@663
  1478
      }
kpeter@601
  1479
kpeter@640
  1480
      return OPTIMAL;
kpeter@601
  1481
    }
kpeter@601
  1482
kpeter@601
  1483
  }; //class NetworkSimplex
kpeter@601
  1484
kpeter@601
  1485
  ///@}
kpeter@601
  1486
kpeter@601
  1487
} //namespace lemon
kpeter@601
  1488
kpeter@601
  1489
#endif //LEMON_NETWORK_SIMPLEX_H