COIN-OR::LEMON - Graph Library

Ticket #298: 298-ns-impr-7408cac25b1e.patch

File 298-ns-impr-7408cac25b1e.patch, 7.3 KB (added by Peter Kovacs, 11 years ago)
  • lemon/network_simplex.h

    # HG changeset patch
    # User Peter Kovacs <kpeter@inf.elte.hu>
    # Date 1245086988 -7200
    # Node ID 7408cac25b1e064e4300cc63a08f5de21f012df1
    # Parent  257e91516e09d8d6be58236c587e3e0199770412
    Small implementation improvements in NS (#298)
    
    diff --git a/lemon/network_simplex.h b/lemon/network_simplex.h
    a b  
    364364      bool findEnteringArc() {
    365365        Cost c, min = 0;
    366366        int cnt = _block_size;
    367         int e, min_arc = _next_arc;
     367        int e;
    368368        for (e = _next_arc; e < _search_arc_num; ++e) {
    369369          c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
    370370          if (c < min) {
    371371            min = c;
    372             min_arc = e;
     372            _in_arc = e;
    373373          }
    374374          if (--cnt == 0) {
    375             if (min < 0) break;
     375            if (min < 0) goto search_end;
    376376            cnt = _block_size;
    377377          }
    378378        }
    379         if (min == 0 || cnt > 0) {
    380           for (e = 0; e < _next_arc; ++e) {
    381             c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
    382             if (c < min) {
    383               min = c;
    384               min_arc = e;
    385             }
    386             if (--cnt == 0) {
    387               if (min < 0) break;
    388               cnt = _block_size;
    389             }
     379        for (e = 0; e < _next_arc; ++e) {
     380          c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
     381          if (c < min) {
     382            min = c;
     383            _in_arc = e;
     384          }
     385          if (--cnt == 0) {
     386            if (min < 0) goto search_end;
     387            cnt = _block_size;
    390388          }
    391389        }
    392390        if (min >= 0) return false;
    393         _in_arc = min_arc;
     391
     392      search_end:
    394393        _next_arc = e;
    395394        return true;
    396395      }
     
    428427        _next_arc(0)
    429428      {
    430429        // The main parameters of the pivot rule
    431         const double LIST_LENGTH_FACTOR = 1.0;
     430        const double LIST_LENGTH_FACTOR = 0.25;
    432431        const int MIN_LIST_LENGTH = 10;
    433432        const double MINOR_LIMIT_FACTOR = 0.1;
    434433        const int MIN_MINOR_LIMIT = 3;
     
    445444      /// Find next entering arc
    446445      bool findEnteringArc() {
    447446        Cost min, c;
    448         int e, min_arc = _next_arc;
     447        int e;
    449448        if (_curr_length > 0 && _minor_count < _minor_limit) {
    450449          // Minor iteration: select the best eligible arc from the
    451450          // current candidate list
     
    456455            c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
    457456            if (c < min) {
    458457              min = c;
    459               min_arc = e;
     458              _in_arc = e;
    460459            }
    461             if (c >= 0) {
     460            else if (c >= 0) {
    462461              _candidates[i--] = _candidates[--_curr_length];
    463462            }
    464463          }
    465           if (min < 0) {
    466             _in_arc = min_arc;
    467             return true;
    468           }
     464          if (min < 0) return true;
    469465        }
    470466
    471467        // Major iteration: build a new candidate list
     
    477473            _candidates[_curr_length++] = e;
    478474            if (c < min) {
    479475              min = c;
    480               min_arc = e;
     476              _in_arc = e;
    481477            }
    482             if (_curr_length == _list_length) break;
     478            if (_curr_length == _list_length) goto search_end;
    483479          }
    484480        }
    485         if (_curr_length < _list_length) {
    486           for (e = 0; e < _next_arc; ++e) {
    487             c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
    488             if (c < 0) {
    489               _candidates[_curr_length++] = e;
    490               if (c < min) {
    491                 min = c;
    492                 min_arc = e;
    493               }
    494               if (_curr_length == _list_length) break;
     481        for (e = 0; e < _next_arc; ++e) {
     482          c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
     483          if (c < 0) {
     484            _candidates[_curr_length++] = e;
     485            if (c < min) {
     486              min = c;
     487              _in_arc = e;
    495488            }
     489            if (_curr_length == _list_length) goto search_end;
    496490          }
    497491        }
    498492        if (_curr_length == 0) return false;
     493     
     494      search_end:       
    499495        _minor_count = 1;
    500         _in_arc = min_arc;
    501496        _next_arc = e;
    502497        return true;
    503498      }
     
    549544        _next_arc(0), _cand_cost(ns._search_arc_num), _sort_func(_cand_cost)
    550545      {
    551546        // The main parameters of the pivot rule
    552         const double BLOCK_SIZE_FACTOR = 1.5;
     547        const double BLOCK_SIZE_FACTOR = 1.0;
    553548        const int MIN_BLOCK_SIZE = 10;
    554549        const double HEAD_LENGTH_FACTOR = 0.1;
    555550        const int MIN_HEAD_LENGTH = 3;
     
    578573
    579574        // Extend the list
    580575        int cnt = _block_size;
    581         int last_arc = 0;
    582576        int limit = _head_length;
    583577
    584         for (int e = _next_arc; e < _search_arc_num; ++e) {
     578        for (e = _next_arc; e < _search_arc_num; ++e) {
    585579          _cand_cost[e] = _state[e] *
    586580            (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
    587581          if (_cand_cost[e] < 0) {
    588582            _candidates[_curr_length++] = e;
    589             last_arc = e;
    590583          }
    591584          if (--cnt == 0) {
    592             if (_curr_length > limit) break;
     585            if (_curr_length > limit) goto search_end;
    593586            limit = 0;
    594587            cnt = _block_size;
    595588          }
    596589        }
    597         if (_curr_length <= limit) {
    598           for (int e = 0; e < _next_arc; ++e) {
    599             _cand_cost[e] = _state[e] *
    600               (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
    601             if (_cand_cost[e] < 0) {
    602               _candidates[_curr_length++] = e;
    603               last_arc = e;
    604             }
    605             if (--cnt == 0) {
    606               if (_curr_length > limit) break;
    607               limit = 0;
    608               cnt = _block_size;
    609             }
     590        for (e = 0; e < _next_arc; ++e) {
     591          _cand_cost[e] = _state[e] *
     592            (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
     593          if (_cand_cost[e] < 0) {
     594            _candidates[_curr_length++] = e;
     595          }
     596          if (--cnt == 0) {
     597            if (_curr_length > limit) goto search_end;
     598            limit = 0;
     599            cnt = _block_size;
    610600          }
    611601        }
    612602        if (_curr_length == 0) return false;
    613         _next_arc = last_arc + 1;
     603       
     604      search_end:
    614605
    615606        // Make heap of the candidate list (approximating a partial sort)
    616607        make_heap( _candidates.begin(), _candidates.begin() + _curr_length,
     
    618609
    619610        // Pop the first element of the heap
    620611        _in_arc = _candidates[0];
     612        _next_arc = e;
    621613        pop_heap( _candidates.begin(), _candidates.begin() + _curr_length,
    622614                  _sort_func );
    623615        _curr_length = std::min(_head_length, _curr_length - 1);
     
    671663      _last_succ.resize(all_node_num);
    672664      _state.resize(max_arc_num);
    673665
    674       // Copy the graph (store the arcs in a mixed order)
     666      // Copy the graph
    675667      int i = 0;
    676668      for (NodeIt n(_graph); n != INVALID; ++n, ++i) {
    677669        _node_id[n] = i;
    678670      }
    679       int k = std::max(int(std::sqrt(double(_arc_num))), 10);
    680671      i = 0;
    681       for (ArcIt a(_graph); a != INVALID; ++a) {
     672      for (ArcIt a(_graph); a != INVALID; ++a, ++i) {
    682673        _arc_id[a] = i;
    683674        _source[i] = _node_id[_graph.source(a)];
    684675        _target[i] = _node_id[_graph.target(a)];
    685         if ((i += k) >= _arc_num) i = (i % k) + 1;
    686676      }
    687677     
    688678      // Initialize maps