COIN-OR::LEMON - Graph Library

Ticket #435: 435-fcb6ad1e67d0.patch

File 435-fcb6ad1e67d0.patch, 4.1 KB (added by Peter Kovacs, 13 years ago)
  • lemon/network_simplex.h

    # HG changeset patch
    # User Peter Kovacs <kpeter@inf.elte.hu>
    # Date 1327951305 -3600
    # Node ID fcb6ad1e67d066f8960c43cf1c51bd763f46a306
    # Parent  48e17328c1551cb8196973d6056a04e40e5d624a
    Improve the Altering List pivot rule for NetworkSimplex (#435)
    Much less candidate arcs are preserved from an iteration to the
    next one and partial_sort() is used instead of heap operations.
    
    diff --git a/lemon/network_simplex.h b/lemon/network_simplex.h
    a b  
    122122    /// Enum type containing constants for selecting the pivot rule for
    123123    /// the \ref run() function.
    124124    ///
    125     /// \ref NetworkSimplex provides five different pivot rule
    126     /// implementations that significantly affect the running time
     125    /// \ref NetworkSimplex provides five different implementations for
     126    /// the pivot strategy that significantly affects the running time
    127127    /// of the algorithm.
    128     /// By default, \ref BLOCK_SEARCH "Block Search" is used, which
    129     /// turend out to be the most efficient and the most robust on various
    130     /// test inputs.
    131     /// However, another pivot rule can be selected using the \ref run()
    132     /// function with the proper parameter.
     128    /// According to experimental tests conducted on various problem
     129    /// instances, \ref BLOCK_SEARCH "Block Search" and
     130    /// \ref ALTERING_LIST "Altering Candidate List" rules turned out
     131    /// to be the most efficient.
     132    /// Since \ref BLOCK_SEARCH "Block Search" is a simpler strategy that
     133    /// seemed to be slightly more robust, it is used by default.
     134    /// However, another pivot rule can easily be selected using the
     135    /// \ref run() function with the proper parameter.
    133136    enum PivotRule {
    134137
    135138      /// The \e First \e Eligible pivot rule.
     
    155158
    156159      /// The \e Altering \e Candidate \e List pivot rule.
    157160      /// It is a modified version of the Candidate List method.
    158       /// It keeps only the several best eligible arcs from the former
     161      /// It keeps only a few of the best eligible arcs from the former
    159162      /// candidate list and extends this list in every iteration.
    160163      ALTERING_LIST
    161164    };
     
    538541      public:
    539542        SortFunc(const CostVector &map) : _map(map) {}
    540543        bool operator()(int left, int right) {
    541           return _map[left] > _map[right];
     544          return _map[left] < _map[right];
    542545        }
    543546      };
    544547
     
    556559        // The main parameters of the pivot rule
    557560        const double BLOCK_SIZE_FACTOR = 1.0;
    558561        const int MIN_BLOCK_SIZE = 10;
    559         const double HEAD_LENGTH_FACTOR = 0.1;
     562        const double HEAD_LENGTH_FACTOR = 0.01;
    560563        const int MIN_HEAD_LENGTH = 3;
    561564
    562565        _block_size = std::max( int(BLOCK_SIZE_FACTOR *
     
    600603          }
    601604        }
    602605        for (e = 0; e != _next_arc; ++e) {
    603           _cand_cost[e] = _state[e] *
    604             (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
    605           if (_cand_cost[e] < 0) {
     606          c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
     607          if (c < 0) {
     608            _cand_cost[e] = c;
    606609            _candidates[_curr_length++] = e;
    607610          }
    608611          if (--cnt == 0) {
     
    615618
    616619      search_end:
    617620
    618         // Make heap of the candidate list (approximating a partial sort)
    619         make_heap( _candidates.begin(), _candidates.begin() + _curr_length,
    620                    _sort_func );
     621        // Perform partial sort operation on the candidate list
     622        int new_length = std::min(_head_length + 1, _curr_length);
     623        std::partial_sort(_candidates.begin(), _candidates.begin() + new_length,
     624                          _candidates.begin() + _curr_length, _sort_func);
    621625
    622         // Pop the first element of the heap
     626        // Select the entering arc and remove it from the list
    623627        _in_arc = _candidates[0];
    624628        _next_arc = e;
    625         pop_heap( _candidates.begin(), _candidates.begin() + _curr_length,
    626                   _sort_func );
    627         _curr_length = std::min(_head_length, _curr_length - 1);
     629        _candidates[0] = _candidates[new_length - 1];
     630        _curr_length = new_length - 1;
    628631        return true;
    629632      }
    630633