Small changes in min. cost flow algorithms.
authorkpeter
Thu, 13 Sep 2007 22:06:54 +0000
changeset 2471ed70b226cc48
parent 2470 46818ce27a60
child 2472 fb60f631790b
Small changes in min. cost flow algorithms.
lemon/capacity_scaling.h
lemon/network_simplex.h
     1.1 --- a/lemon/capacity_scaling.h	Thu Sep 13 22:05:32 2007 +0000
     1.2 +++ b/lemon/capacity_scaling.h	Thu Sep 13 22:06:54 2007 +0000
     1.3 @@ -31,6 +31,10 @@
     1.4  
     1.5  #define WITH_SCALING
     1.6  
     1.7 +#ifdef WITH_SCALING
     1.8 +#define SCALING_FACTOR	  2
     1.9 +#endif
    1.10 +
    1.11  //#define _DEBUG_ITER_
    1.12  
    1.13  namespace lemon {
    1.14 @@ -542,7 +546,8 @@
    1.15  	if (supply[n] < -max_dem) max_dem = -supply[n];
    1.16        }
    1.17        if (max_dem < max_sup) max_sup = max_dem;
    1.18 -      for (delta = 1; 2 * delta < max_sup; delta *= 2) ;
    1.19 +      for ( delta = 1; SCALING_FACTOR * delta < max_sup;
    1.20 +	    delta *= SCALING_FACTOR ) ;
    1.21  #endif
    1.22        return true;
    1.23      }
    1.24 @@ -559,8 +564,8 @@
    1.25  
    1.26        // Processing capacity scaling phases
    1.27        ResNode s, t;
    1.28 -      for ( ; delta >= 1; delta = delta < 4 && delta > 1 ?
    1.29 -				  1 : delta / 4 )
    1.30 +      for ( ; delta >= 1; delta = delta < SCALING_FACTOR && delta > 1 ?
    1.31 +				  1 : delta / SCALING_FACTOR )
    1.32        {
    1.33  	// Saturating edges not satisfying the optimality condition
    1.34  	Capacity r;
     2.1 --- a/lemon/network_simplex.h	Thu Sep 13 22:05:32 2007 +0000
     2.2 +++ b/lemon/network_simplex.h	Thu Sep 13 22:06:54 2007 +0000
     2.3 @@ -47,29 +47,22 @@
     2.4  #define UPPER	-1
     2.5  
     2.6  #ifdef EDGE_BLOCK_PIVOT
     2.7 -  /// \brief Number of blocks for the "Edge Block" pivot rule.
     2.8 -  #define BLOCK_NUM		100
     2.9 +  #include <cmath>
    2.10    /// \brief Lower bound for the size of blocks.
    2.11    #define MIN_BLOCK_SIZE	10
    2.12  #endif
    2.13  
    2.14  #ifdef CANDIDATE_LIST_PIVOT
    2.15 -  #include <list>
    2.16 -  /// \brief The maximum length of the edge list for the
    2.17 -  /// "Candidate List" pivot rule.
    2.18 -  #define LIST_LENGTH		100
    2.19 -  /// \brief The maximum number of minor iterations between two major
    2.20 -  /// itarations.
    2.21 -  #define MINOR_LIMIT		10
    2.22 +  #include <vector>
    2.23 +  #define LIST_LENGTH_DIV           50
    2.24 +  #define MINOR_LIMIT_DIV           200
    2.25  #endif
    2.26  
    2.27  #ifdef SORTED_LIST_PIVOT
    2.28 -  #include <deque>
    2.29 +  #include <vector>
    2.30    #include <algorithm>
    2.31 -  /// \brief The maximum length of the edge list for the
    2.32 -  /// "Sorted List" pivot rule.
    2.33 -  #define LIST_LENGTH		500
    2.34 -  #define LOWER_DIV		3
    2.35 +  #define LIST_LENGTH_DIV       100
    2.36 +  #define LOWER_DIV		4
    2.37  #endif
    2.38  
    2.39  namespace lemon {
    2.40 @@ -223,14 +216,24 @@
    2.41  #ifdef CANDIDATE_LIST_PIVOT
    2.42      /// \brief The list of candidate edges for the "Candidate List"
    2.43      /// pivot rule.
    2.44 -    std::list<Edge> candidates;
    2.45 +    std::vector<Edge> candidates;
    2.46 +    /// \brief The maximum length of the edge list for the
    2.47 +    /// "Candidate List" pivot rule.
    2.48 +    int list_length;
    2.49 +    /// \brief The maximum number of minor iterations between two major
    2.50 +    /// itarations.
    2.51 +    int minor_limit;
    2.52      /// \brief The number of minor iterations.
    2.53      int minor_count;
    2.54  #endif
    2.55  #ifdef SORTED_LIST_PIVOT
    2.56      /// \brief The list of candidate edges for the "Sorted List"
    2.57      /// pivot rule.
    2.58 -    std::deque<Edge> candidates;
    2.59 +    std::vector<Edge> candidates;
    2.60 +    /// \brief The maximum length of the edge list for the
    2.61 +    /// "Sorted List" pivot rule.
    2.62 +    int list_length;
    2.63 +    int list_index;
    2.64  #endif
    2.65  
    2.66      // Root node of the starting spanning tree.
    2.67 @@ -517,11 +520,21 @@
    2.68  #ifdef EDGE_BLOCK_PIVOT
    2.69        // Initializing block_size for the edge block pivot rule
    2.70        int edge_num = countEdges(graph);
    2.71 -      block_size = edge_num >= BLOCK_NUM * MIN_BLOCK_SIZE ?
    2.72 -		   edge_num / BLOCK_NUM : MIN_BLOCK_SIZE;
    2.73 +      block_size = 2 * int(sqrt(countEdges(graph)));
    2.74 +      if (block_size < MIN_BLOCK_SIZE) block_size = MIN_BLOCK_SIZE;
    2.75 +//      block_size = edge_num >= BLOCK_NUM * MIN_BLOCK_SIZE ?
    2.76 +//                   edge_num / BLOCK_NUM : MIN_BLOCK_SIZE;
    2.77  #endif
    2.78  #ifdef CANDIDATE_LIST_PIVOT
    2.79 +      int edge_num = countEdges(graph);
    2.80        minor_count = 0;
    2.81 +      list_length = edge_num / LIST_LENGTH_DIV;
    2.82 +      minor_limit = edge_num / MINOR_LIMIT_DIV;
    2.83 +#endif
    2.84 +#ifdef SORTED_LIST_PIVOT
    2.85 +      int edge_num = countEdges(graph);
    2.86 +      list_index = 0;
    2.87 +      list_length = edge_num / LIST_LENGTH_DIV;
    2.88  #endif
    2.89  
    2.90        return sum == 0;
    2.91 @@ -602,34 +615,18 @@
    2.92  #endif
    2.93  
    2.94  #ifdef CANDIDATE_LIST_PIVOT
    2.95 -    /// \brief Functor class for removing non-eligible edges from the
    2.96 -    /// candidate list.
    2.97 -    class RemoveFunc
    2.98 -    {
    2.99 -    private:
   2.100 -      const IntEdgeMap &st;
   2.101 -      const ReducedCostMap &rc;
   2.102 -    public:
   2.103 -      RemoveFunc(const IntEdgeMap &_st, const ReducedCostMap &_rc) :
   2.104 -	st(_st), rc(_rc) {}
   2.105 -      bool operator()(const Edge &e) {
   2.106 -	return st[e] * rc[e] >= 0;
   2.107 -      }
   2.108 -    };
   2.109 -
   2.110      /// \brief Finds entering edge according to the "Candidate List"
   2.111      /// pivot rule.
   2.112      bool findEnteringEdge() {
   2.113 -      static RemoveFunc remove_func(state, red_cost);
   2.114 -      typedef typename std::list<Edge>::iterator ListIt;
   2.115 +      typedef typename std::vector<Edge>::iterator ListIt;
   2.116  
   2.117 -      candidates.remove_if(remove_func);
   2.118 -      if (minor_count >= MINOR_LIMIT || candidates.size() == 0) {
   2.119 +      if (minor_count >= minor_limit || candidates.size() == 0) {
   2.120  	// Major iteration
   2.121 +	candidates.clear();
   2.122  	for (EdgeIt e(graph); e != INVALID; ++e) {
   2.123  	  if (state[e] * red_cost[e] < 0) {
   2.124  	    candidates.push_back(e);
   2.125 -	    if (candidates.size() == LIST_LENGTH) break;
   2.126 +	    if (candidates.size() == list_length) break;
   2.127  	  }
   2.128  	}
   2.129  	if (candidates.size() == 0) return false;
   2.130 @@ -638,10 +635,12 @@
   2.131        // Minor iteration
   2.132        ++minor_count;
   2.133        Cost min = 0;
   2.134 -      for (ListIt it = candidates.begin(); it != candidates.end(); ++it) {
   2.135 -	if (state[*it] * red_cost[*it] < min) {
   2.136 -	  min = state[*it] * red_cost[*it];
   2.137 -	  in_edge = *it;
   2.138 +      Edge e;
   2.139 +      for (int i = 0; i < candidates.size(); ++i) {
   2.140 +        e = candidates[i];
   2.141 +	if (state[e] * red_cost[e] < min) {
   2.142 +	  min = state[e] * red_cost[e];
   2.143 +	  in_edge = e;
   2.144  	}
   2.145        }
   2.146        return true;
   2.147 @@ -670,25 +669,25 @@
   2.148        static SortFunc sort_func(state, red_cost);
   2.149  
   2.150        // Minor iteration
   2.151 -      while (candidates.size() > 0) {
   2.152 -	in_edge = candidates.front();
   2.153 -	candidates.pop_front();
   2.154 +      while (list_index < candidates.size()) {
   2.155 +	in_edge = candidates[list_index++];
   2.156  	if (state[in_edge] * red_cost[in_edge] < 0) return true;
   2.157        }
   2.158  
   2.159        // Major iteration
   2.160 +      candidates.clear();
   2.161        Cost curr, min = 0;
   2.162        for (EdgeIt e(graph); e != INVALID; ++e) {
   2.163  	if ((curr = state[e] * red_cost[e]) < min / LOWER_DIV) {
   2.164  	  candidates.push_back(e);
   2.165  	  if (curr < min) min = curr;
   2.166 -	  if (candidates.size() == LIST_LENGTH) break;
   2.167 +	  if (candidates.size() == list_length) break;
   2.168  	}
   2.169        }
   2.170        if (candidates.size() == 0) return false;
   2.171        sort(candidates.begin(), candidates.end(), sort_func);
   2.172 -      in_edge = candidates.front();
   2.173 -      candidates.pop_front();
   2.174 +      in_edge = candidates[0];
   2.175 +      list_index = 1;
   2.176        return true;
   2.177      }
   2.178  #endif