COIN-OR::LEMON - Graph Library

Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • lemon/network_simplex.h

    r710 r777  
    162162    TEMPLATE_DIGRAPH_TYPEDEFS(GR);
    163163
    164     typedef std::vector<Arc> ArcVector;
    165     typedef std::vector<Node> NodeVector;
    166164    typedef std::vector<int> IntVector;
    167165    typedef std::vector<bool> BoolVector;
     
    365363        Cost c, min = 0;
    366364        int cnt = _block_size;
    367         int e, min_arc = _next_arc;
     365        int e;
    368366        for (e = _next_arc; e < _search_arc_num; ++e) {
    369367          c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
    370368          if (c < min) {
    371369            min = c;
    372             min_arc = e;
     370            _in_arc = e;
    373371          }
    374372          if (--cnt == 0) {
    375             if (min < 0) break;
     373            if (min < 0) goto search_end;
    376374            cnt = _block_size;
    377375          }
    378376        }
    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             }
     377        for (e = 0; e < _next_arc; ++e) {
     378          c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
     379          if (c < min) {
     380            min = c;
     381            _in_arc = e;
     382          }
     383          if (--cnt == 0) {
     384            if (min < 0) goto search_end;
     385            cnt = _block_size;
    390386          }
    391387        }
    392388        if (min >= 0) return false;
    393         _in_arc = min_arc;
     389
     390      search_end:
    394391        _next_arc = e;
    395392        return true;
     
    429426      {
    430427        // The main parameters of the pivot rule
    431         const double LIST_LENGTH_FACTOR = 1.0;
     428        const double LIST_LENGTH_FACTOR = 0.25;
    432429        const int MIN_LIST_LENGTH = 10;
    433430        const double MINOR_LIMIT_FACTOR = 0.1;
     
    446443      bool findEnteringArc() {
    447444        Cost min, c;
    448         int e, min_arc = _next_arc;
     445        int e;
    449446        if (_curr_length > 0 && _minor_count < _minor_limit) {
    450447          // Minor iteration: select the best eligible arc from the
     
    457454            if (c < min) {
    458455              min = c;
    459               min_arc = e;
     456              _in_arc = e;
    460457            }
    461             if (c >= 0) {
     458            else if (c >= 0) {
    462459              _candidates[i--] = _candidates[--_curr_length];
    463460            }
    464461          }
    465           if (min < 0) {
    466             _in_arc = min_arc;
    467             return true;
    468           }
     462          if (min < 0) return true;
    469463        }
    470464
     
    478472            if (c < min) {
    479473              min = c;
    480               min_arc = e;
     474              _in_arc = e;
    481475            }
    482             if (_curr_length == _list_length) break;
    483           }
    484         }
    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;
     476            if (_curr_length == _list_length) goto search_end;
     477          }
     478        }
     479        for (e = 0; e < _next_arc; ++e) {
     480          c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
     481          if (c < 0) {
     482            _candidates[_curr_length++] = e;
     483            if (c < min) {
     484              min = c;
     485              _in_arc = e;
    495486            }
     487            if (_curr_length == _list_length) goto search_end;
    496488          }
    497489        }
    498490        if (_curr_length == 0) return false;
     491     
     492      search_end:       
    499493        _minor_count = 1;
    500         _in_arc = min_arc;
    501494        _next_arc = e;
    502495        return true;
     
    550543      {
    551544        // The main parameters of the pivot rule
    552         const double BLOCK_SIZE_FACTOR = 1.5;
     545        const double BLOCK_SIZE_FACTOR = 1.0;
    553546        const int MIN_BLOCK_SIZE = 10;
    554547        const double HEAD_LENGTH_FACTOR = 0.1;
     
    579572        // Extend the list
    580573        int cnt = _block_size;
    581         int last_arc = 0;
    582574        int limit = _head_length;
    583575
    584         for (int e = _next_arc; e < _search_arc_num; ++e) {
     576        for (e = _next_arc; e < _search_arc_num; ++e) {
    585577          _cand_cost[e] = _state[e] *
    586578            (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
    587579          if (_cand_cost[e] < 0) {
    588580            _candidates[_curr_length++] = e;
    589             last_arc = e;
    590581          }
    591582          if (--cnt == 0) {
    592             if (_curr_length > limit) break;
     583            if (_curr_length > limit) goto search_end;
    593584            limit = 0;
    594585            cnt = _block_size;
    595586          }
    596587        }
    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             }
     588        for (e = 0; e < _next_arc; ++e) {
     589          _cand_cost[e] = _state[e] *
     590            (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
     591          if (_cand_cost[e] < 0) {
     592            _candidates[_curr_length++] = e;
     593          }
     594          if (--cnt == 0) {
     595            if (_curr_length > limit) goto search_end;
     596            limit = 0;
     597            cnt = _block_size;
    610598          }
    611599        }
    612600        if (_curr_length == 0) return false;
    613         _next_arc = last_arc + 1;
     601       
     602      search_end:
    614603
    615604        // Make heap of the candidate list (approximating a partial sort)
     
    619608        // Pop the first element of the heap
    620609        _in_arc = _candidates[0];
     610        _next_arc = e;
    621611        pop_heap( _candidates.begin(), _candidates.begin() + _curr_length,
    622612                  _sort_func );
     
    634624    ///
    635625    /// \param graph The digraph the algorithm runs on.
    636     NetworkSimplex(const GR& graph) :
     626    /// \param arc_mixing Indicate if the arcs have to be stored in a
     627    /// mixed order in the internal data structure.
     628    /// In special cases, it could lead to better overall performance,
     629    /// but it is usually slower. Therefore it is disabled by default.
     630    NetworkSimplex(const GR& graph, bool arc_mixing = false) :
    637631      _graph(graph), _node_id(graph), _arc_id(graph),
    638632      INF(std::numeric_limits<Value>::has_infinity ?
     
    672666      _state.resize(max_arc_num);
    673667
    674       // Copy the graph (store the arcs in a mixed order)
     668      // Copy the graph
    675669      int i = 0;
    676670      for (NodeIt n(_graph); n != INVALID; ++n, ++i) {
    677671        _node_id[n] = i;
    678672      }
    679       int k = std::max(int(std::sqrt(double(_arc_num))), 10);
    680       i = 0;
    681       for (ArcIt a(_graph); a != INVALID; ++a) {
    682         _arc_id[a] = i;
    683         _source[i] = _node_id[_graph.source(a)];
    684         _target[i] = _node_id[_graph.target(a)];
    685         if ((i += k) >= _arc_num) i = (i % k) + 1;
     673      if (arc_mixing) {
     674        // Store the arcs in a mixed order
     675        int k = std::max(int(std::sqrt(double(_arc_num))), 10);
     676        int i = 0, j = 0;
     677        for (ArcIt a(_graph); a != INVALID; ++a) {
     678          _arc_id[a] = i;
     679          _source[i] = _node_id[_graph.source(a)];
     680          _target[i] = _node_id[_graph.target(a)];
     681          if ((i += k) >= _arc_num) i = ++j;
     682        }
     683      } else {
     684        // Store the arcs in the original order
     685        int i = 0;
     686        for (ArcIt a(_graph); a != INVALID; ++a, ++i) {
     687          _arc_id[a] = i;
     688          _source[i] = _node_id[_graph.source(a)];
     689          _target[i] = _node_id[_graph.target(a)];
     690        }
    686691      }
    687692     
    688       // Initialize maps
    689       for (int i = 0; i != _node_num; ++i) {
    690         _supply[i] = 0;
    691       }
    692       for (int i = 0; i != _arc_num; ++i) {
    693         _lower[i] = 0;
    694         _upper[i] = INF;
    695         _cost[i] = 1;
    696       }
    697       _have_lower = false;
    698       _stype = GEQ;
     693      // Reset parameters
     694      reset();
    699695    }
    700696
     
    769765    /// If neither this function nor \ref stSupply() is used before
    770766    /// calling \ref run(), the supply of each node will be set to zero.
    771     /// (It makes sense only if non-zero lower bounds are given.)
    772767    ///
    773768    /// \param map A node map storing the supply values.
     
    790785    /// If neither this function nor \ref supplyMap() is used before
    791786    /// calling \ref run(), the supply of each node will be set to zero.
    792     /// (It makes sense only if non-zero lower bounds are given.)
    793787    ///
    794788    /// Using this function has the same effect as using \ref supplyMap()
Note: See TracChangeset for help on using the changeset viewer.