lemon/network_simplex.h
author Peter Kovacs <kpeter@inf.elte.hu>
Tue, 15 Mar 2011 19:32:21 +0100
changeset 936 ddd3c0d3d9bf
parent 921 140c953ad5d1
parent 919 e0cef67fe565
child 984 fcb6ad1e67d0
child 1003 16f55008c863
permissions -rw-r--r--
Implement the scaling Price Refinement heuristic in CostScaling (#417)
instead of Early Termination.

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