[Lemon-commits] Peter Kovacs: Small improvements in NS pivot rul...

Lemon HG hg at lemon.cs.elte.hu
Sat Sep 26 07:28:59 CEST 2009


details:   http://lemon.cs.elte.hu/hg/lemon/rev/cab85bd7859b
changeset: 780:cab85bd7859b
user:      Peter Kovacs <kpeter [at] inf.elte.hu>
date:      Wed Jul 01 16:34:01 2009 +0200
description:
	Small improvements in NS pivot rules (#298)

diffstat:

 lemon/network_simplex.h |  102 +++++++++++++++++++++++---------------------------
 1 files changed, 47 insertions(+), 55 deletions(-)

diffs (200 lines):

diff --git a/lemon/network_simplex.h b/lemon/network_simplex.h
--- a/lemon/network_simplex.h
+++ b/lemon/network_simplex.h
@@ -364,33 +364,32 @@
       bool findEnteringArc() {
         Cost c, min = 0;
         int cnt = _block_size;
-        int e, min_arc = _next_arc;
+        int e;
         for (e = _next_arc; e < _search_arc_num; ++e) {
           c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
           if (c < min) {
             min = c;
-            min_arc = e;
+            _in_arc = e;
           }
           if (--cnt == 0) {
-            if (min < 0) break;
+            if (min < 0) goto search_end;
             cnt = _block_size;
           }
         }
-        if (min == 0 || cnt > 0) {
-          for (e = 0; e < _next_arc; ++e) {
-            c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
-            if (c < min) {
-              min = c;
-              min_arc = e;
-            }
-            if (--cnt == 0) {
-              if (min < 0) break;
-              cnt = _block_size;
-            }
+        for (e = 0; e < _next_arc; ++e) {
+          c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
+          if (c < min) {
+            min = c;
+            _in_arc = e;
+          }
+          if (--cnt == 0) {
+            if (min < 0) goto search_end;
+            cnt = _block_size;
           }
         }
         if (min >= 0) return false;
-        _in_arc = min_arc;
+
+      search_end:
         _next_arc = e;
         return true;
       }
@@ -428,7 +427,7 @@
         _next_arc(0)
       {
         // The main parameters of the pivot rule
-        const double LIST_LENGTH_FACTOR = 1.0;
+        const double LIST_LENGTH_FACTOR = 0.25;
         const int MIN_LIST_LENGTH = 10;
         const double MINOR_LIMIT_FACTOR = 0.1;
         const int MIN_MINOR_LIMIT = 3;
@@ -445,7 +444,7 @@
       /// Find next entering arc
       bool findEnteringArc() {
         Cost min, c;
-        int e, min_arc = _next_arc;
+        int e;
         if (_curr_length > 0 && _minor_count < _minor_limit) {
           // Minor iteration: select the best eligible arc from the
           // current candidate list
@@ -456,16 +455,13 @@
             c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
             if (c < min) {
               min = c;
-              min_arc = e;
+              _in_arc = e;
             }
-            if (c >= 0) {
+            else if (c >= 0) {
               _candidates[i--] = _candidates[--_curr_length];
             }
           }
-          if (min < 0) {
-            _in_arc = min_arc;
-            return true;
-          }
+          if (min < 0) return true;
         }
 
         // Major iteration: build a new candidate list
@@ -477,27 +473,26 @@
             _candidates[_curr_length++] = e;
             if (c < min) {
               min = c;
-              min_arc = e;
+              _in_arc = e;
             }
-            if (_curr_length == _list_length) break;
+            if (_curr_length == _list_length) goto search_end;
           }
         }
-        if (_curr_length < _list_length) {
-          for (e = 0; e < _next_arc; ++e) {
-            c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
-            if (c < 0) {
-              _candidates[_curr_length++] = e;
-              if (c < min) {
-                min = c;
-                min_arc = e;
-              }
-              if (_curr_length == _list_length) break;
+        for (e = 0; e < _next_arc; ++e) {
+          c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
+          if (c < 0) {
+            _candidates[_curr_length++] = e;
+            if (c < min) {
+              min = c;
+              _in_arc = e;
             }
+            if (_curr_length == _list_length) goto search_end;
           }
         }
         if (_curr_length == 0) return false;
+      
+      search_end:        
         _minor_count = 1;
-        _in_arc = min_arc;
         _next_arc = e;
         return true;
       }
@@ -549,7 +544,7 @@
         _next_arc(0), _cand_cost(ns._search_arc_num), _sort_func(_cand_cost)
       {
         // The main parameters of the pivot rule
-        const double BLOCK_SIZE_FACTOR = 1.5;
+        const double BLOCK_SIZE_FACTOR = 1.0;
         const int MIN_BLOCK_SIZE = 10;
         const double HEAD_LENGTH_FACTOR = 0.1;
         const int MIN_HEAD_LENGTH = 3;
@@ -578,39 +573,35 @@
 
         // Extend the list
         int cnt = _block_size;
-        int last_arc = 0;
         int limit = _head_length;
 
-        for (int e = _next_arc; e < _search_arc_num; ++e) {
+        for (e = _next_arc; e < _search_arc_num; ++e) {
           _cand_cost[e] = _state[e] *
             (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
           if (_cand_cost[e] < 0) {
             _candidates[_curr_length++] = e;
-            last_arc = e;
           }
           if (--cnt == 0) {
-            if (_curr_length > limit) break;
+            if (_curr_length > limit) goto search_end;
             limit = 0;
             cnt = _block_size;
           }
         }
-        if (_curr_length <= limit) {
-          for (int e = 0; e < _next_arc; ++e) {
-            _cand_cost[e] = _state[e] *
-              (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
-            if (_cand_cost[e] < 0) {
-              _candidates[_curr_length++] = e;
-              last_arc = e;
-            }
-            if (--cnt == 0) {
-              if (_curr_length > limit) break;
-              limit = 0;
-              cnt = _block_size;
-            }
+        for (e = 0; e < _next_arc; ++e) {
+          _cand_cost[e] = _state[e] *
+            (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
+          if (_cand_cost[e] < 0) {
+            _candidates[_curr_length++] = e;
+          }
+          if (--cnt == 0) {
+            if (_curr_length > limit) goto search_end;
+            limit = 0;
+            cnt = _block_size;
           }
         }
         if (_curr_length == 0) return false;
-        _next_arc = last_arc + 1;
+        
+      search_end:
 
         // Make heap of the candidate list (approximating a partial sort)
         make_heap( _candidates.begin(), _candidates.begin() + _curr_length,
@@ -618,6 +609,7 @@
 
         // Pop the first element of the heap
         _in_arc = _candidates[0];
+        _next_arc = e;
         pop_heap( _candidates.begin(), _candidates.begin() + _curr_length,
                   _sort_func );
         _curr_length = std::min(_head_length, _curr_length - 1);



More information about the Lemon-commits mailing list