[Lemon-commits] kpeter: r3524 - lemon/trunk/lemon
Lemon SVN
svn at lemon.cs.elte.hu
Thu Jun 4 03:19:07 CEST 2009
Author: kpeter
Date: Thu Jun 4 03:19:06 2009
New Revision: 3524
Modified:
lemon/trunk/lemon/network_simplex.h
Log:
Various improvements for NS pivot rules
Modified: lemon/trunk/lemon/network_simplex.h
==============================================================================
--- lemon/trunk/lemon/network_simplex.h (original)
+++ lemon/trunk/lemon/network_simplex.h Thu Jun 4 03:19:06 2009
@@ -241,10 +241,10 @@
BlockSearchPivotRule(NetworkSimplex &ns) :
_edge(ns._edge), _source(ns._source), _target(ns._target),
_cost(ns._cost), _state(ns._state), _pi(ns._pi),
- _in_edge(ns._in_edge), _edge_num(ns._edge_num + ns._node_num), _next_edge(0)
+ _in_edge(ns._in_edge), _edge_num(ns._edge_num), _next_edge(0)
{
// The main parameters of the pivot rule
- const double BLOCK_SIZE_FACTOR = 2.0;
+ const double BLOCK_SIZE_FACTOR = 0.5;
const int MIN_BLOCK_SIZE = 10;
_block_size = std::max( int(BLOCK_SIZE_FACTOR * sqrt(_edge_num)),
@@ -255,33 +255,32 @@
bool findEnteringEdge() {
Cost c, min = 0;
int cnt = _block_size;
- int e, min_edge = _next_edge;
+ int e;
for (e = _next_edge; e < _edge_num; ++e) {
c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
if (c < min) {
min = c;
- min_edge = e;
+ _in_edge = 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_edge; ++e) {
- c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
- if (c < min) {
- min = c;
- min_edge = e;
- }
- if (--cnt == 0) {
- if (min < 0) break;
- cnt = _block_size;
- }
+ for (e = 0; e < _next_edge; ++e) {
+ c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
+ if (c < min) {
+ min = c;
+ _in_edge = e;
+ }
+ if (--cnt == 0) {
+ if (min < 0) goto search_end;
+ cnt = _block_size;
}
}
if (min >= 0) return false;
- _in_edge = min_edge;
+
+ search_end:
_next_edge = e;
return true;
}
@@ -325,7 +324,7 @@
_in_edge(ns._in_edge), _edge_num(ns._edge_num), _next_edge(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;
@@ -341,7 +340,7 @@
/// Find next entering edge
bool findEnteringEdge() {
Cost min, c;
- int e, min_edge = _next_edge;
+ int e;
if (_curr_length > 0 && _minor_count < _minor_limit) {
// Minor iteration: select the best eligible edge from the
// current candidate list
@@ -352,16 +351,13 @@
c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
if (c < min) {
min = c;
- min_edge = e;
+ _in_edge = e;
}
- if (c >= 0) {
+ else if (c >= 0) {
_candidates[i--] = _candidates[--_curr_length];
}
}
- if (min < 0) {
- _in_edge = min_edge;
- return true;
- }
+ if (min < 0) return true;
}
// Major iteration: build a new candidate list
@@ -373,27 +369,26 @@
_candidates[_curr_length++] = e;
if (c < min) {
min = c;
- min_edge = e;
+ _in_edge = 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_edge; ++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_edge = e;
- }
- if (_curr_length == _list_length) break;
+ for (e = 0; e < _next_edge; ++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_edge = e;
}
+ if (_curr_length == _list_length) goto search_end;
}
}
if (_curr_length == 0) return false;
+
+ search_end:
_minor_count = 1;
- _in_edge = min_edge;
_next_edge = e;
return true;
}
@@ -451,7 +446,7 @@
_next_edge(0), _cand_cost(ns._edge_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;
@@ -479,39 +474,35 @@
// Extend the list
int cnt = _block_size;
- int last_edge = 0;
int limit = _head_length;
- for (int e = _next_edge; e < _edge_num; ++e) {
+ for (e = _next_edge; e < _edge_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_edge = 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_edge; ++e) {
- _cand_cost[e] = _state[e] *
- (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
- if (_cand_cost[e] < 0) {
- _candidates[_curr_length++] = e;
- last_edge = e;
- }
- if (--cnt == 0) {
- if (_curr_length > limit) break;
- limit = 0;
- cnt = _block_size;
- }
+ for (e = 0; e < _next_edge; ++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_edge = last_edge + 1;
+
+ search_end:
// Make heap of the candidate list (approximating a partial sort)
make_heap( _candidates.begin(), _candidates.begin() + _curr_length,
@@ -519,6 +510,7 @@
// Pop the first element of the heap
_in_edge = _candidates[0];
+ _next_edge = e;
pop_heap( _candidates.begin(), _candidates.begin() + _curr_length,
_sort_func );
_curr_length = std::min(_head_length, _curr_length - 1);
@@ -931,12 +923,10 @@
_supply[_root] = 0;
_pi[_root] = 0;
- // Store the edges in a mixed order
- int k = std::max(int(sqrt(_edge_num)), 10);
+ // Store the edges
int i = 0;
for (EdgeIt e(_orig_graph); e != INVALID; ++e) {
- _edge[i] = e;
- if ((i += k) >= _edge_num) i = (i % k) + 1;
+ _edge[i++] = e;
}
// Initialize edge maps
@@ -961,7 +951,7 @@
}
// Add artificial edges and initialize the spanning tree data structure
- Cost max_cost = std::numeric_limits<Cost>::max() / 4;
+ Cost max_cost = std::numeric_limits<Cost>::max() / 2 + 1;
Capacity max_cap = std::numeric_limits<Capacity>::max();
for (int u = 0, e = _edge_num; u != _node_num; ++u, ++e) {
_parent[u] = _root;
More information about the Lemon-commits
mailing list