# HG changeset patch # User Peter Kovacs # Date 1300208397 -3600 # Node ID fe283caf641470961f027f6958297bff545d83d8 # Parent 773dd96ecdd83703782b1276654ac122d474e8cc Minor improvements in CostScaling (#417) diff -r 773dd96ecdd8 -r fe283caf6414 lemon/cost_scaling.h --- a/lemon/cost_scaling.h Thu Mar 17 09:02:51 2011 +0100 +++ b/lemon/cost_scaling.h Tue Mar 15 17:59:57 2011 +0100 @@ -575,18 +575,25 @@ return *this; } - /// \brief Reset all the parameters that have been given before. + /// \brief Reset the internal data structures and all the parameters + /// that have been given before. /// - /// This function resets all the paramaters that have been given - /// before using functions \ref lowerMap(), \ref upperMap(), - /// \ref costMap(), \ref supplyMap(), \ref stSupply(). + /// This function resets the internal data structures and all the + /// paramaters that have been given before using functions \ref lowerMap(), + /// \ref upperMap(), \ref costMap(), \ref supplyMap(), \ref stSupply(). /// - /// It is useful for multiple run() calls. If this function is not - /// used, all the parameters given before are kept for the next - /// \ref run() call. - /// However, the underlying digraph must not be modified after this - /// class have been constructed, since it copies and extends the graph. + /// It is useful for multiple \ref run() calls. By default, all the given + /// parameters are kept for the next \ref run() call, unless + /// \ref resetParams() or \ref reset() is used. + /// If the underlying digraph was also modified after the construction + /// of the class or the last \ref reset() call, then the \ref reset() + /// function must be used, otherwise \ref resetParams() is sufficient. + /// + /// See \ref resetParams() for examples. + /// /// \return (*this) + /// + /// \see resetParams(), run() CostScaling& reset() { // Resize vectors _node_num = countNodes(_graph); @@ -890,14 +897,6 @@ } } - return OPTIMAL; - } - - // Execute the algorithm and transform the results - void start(Method method) { - // Maximum path length for partial augment - const int MAX_PATH_LENGTH = 4; - // Initialize data structures for buckets _max_rank = _alpha * _res_node_num; _buckets.resize(_max_rank); @@ -905,7 +904,13 @@ _bucket_prev.resize(_res_node_num + 1); _rank.resize(_res_node_num + 1); - // Execute the algorithm + return OPTIMAL; + } + + // Execute the algorithm and transform the results + void start(Method method) { + const int MAX_PARTIAL_PATH_LENGTH = 4; + switch (method) { case PUSH: startPush(); @@ -914,7 +919,7 @@ startAugment(_res_node_num - 1); break; case PARTIAL_AUGMENT: - startAugment(MAX_PATH_LENGTH); + startAugment(MAX_PARTIAL_PATH_LENGTH); break; } @@ -951,13 +956,15 @@ int last_out = _first_out[u+1]; LargeCost pi_u = _pi[u]; for (int a = _first_out[u]; a != last_out; ++a) { - int v = _target[a]; - if (_res_cap[a] > 0 && _cost[a] + pi_u - _pi[v] < 0) { - Value delta = _res_cap[a]; - _excess[u] -= delta; - _excess[v] += delta; - _res_cap[a] = 0; - _res_cap[_reverse[a]] += delta; + Value delta = _res_cap[a]; + if (delta > 0) { + int v = _target[a]; + if (_cost[a] + pi_u - _pi[v] < 0) { + _excess[u] -= delta; + _excess[v] += delta; + _res_cap[a] = 0; + _res_cap[_reverse[a]] += delta; + } } } } @@ -1001,25 +1008,27 @@ // Global potential update heuristic void globalUpdate() { - int bucket_end = _root + 1; + const int bucket_end = _root + 1; // Initialize buckets for (int r = 0; r != _max_rank; ++r) { _buckets[r] = bucket_end; } Value total_excess = 0; + int b0 = bucket_end; for (int i = 0; i != _res_node_num; ++i) { if (_excess[i] < 0) { _rank[i] = 0; - _bucket_next[i] = _buckets[0]; - _bucket_prev[_buckets[0]] = i; - _buckets[0] = i; + _bucket_next[i] = b0; + _bucket_prev[b0] = i; + b0 = i; } else { total_excess += _excess[i]; _rank[i] = _max_rank; } } if (total_excess == 0) return; + _buckets[0] = b0; // Search the buckets int r = 0; @@ -1041,8 +1050,9 @@ // Compute the new rank of v LargeCost nrc = (_cost[ra] + _pi[v] - pi_u) / _epsilon; int new_rank_v = old_rank_v; - if (nrc < LargeCost(_max_rank)) - new_rank_v = r + 1 + int(nrc); + if (nrc < LargeCost(_max_rank)) { + new_rank_v = r + 1 + static_cast(nrc); + } // Change the rank of v if (new_rank_v < old_rank_v) { @@ -1054,14 +1064,16 @@ if (_buckets[old_rank_v] == v) { _buckets[old_rank_v] = _bucket_next[v]; } else { - _bucket_next[_bucket_prev[v]] = _bucket_next[v]; - _bucket_prev[_bucket_next[v]] = _bucket_prev[v]; + int pv = _bucket_prev[v], nv = _bucket_next[v]; + _bucket_next[pv] = nv; + _bucket_prev[nv] = pv; } } - // Insert v to its new bucket - _bucket_next[v] = _buckets[new_rank_v]; - _bucket_prev[_buckets[new_rank_v]] = v; + // Insert v into its new bucket + int nv = _buckets[new_rank_v]; + _bucket_next[v] = nv; + _bucket_prev[nv] = v; _buckets[new_rank_v] = v; } }