Skip to content

Commit 818150e

Browse files
committed
More indeterminism fixes
1 parent bda0f1b commit 818150e

File tree

4 files changed

+45
-6
lines changed

4 files changed

+45
-6
lines changed

changelog.in

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,18 @@ using memory addresses for determining the order of variables in
8181
some propagators which in turn affected which propagator might
8282
record failure first and hence influenced the branching decisions.
8383

84+
[ENTRY]
85+
Module: int
86+
What: bug
87+
Rank: major
88+
[DESCRIPTION]
89+
For the combination of binpacking and linear constraints with
90+
shared variable selection branching (that is, AFC, Action, and
91+
CHB) the behavior of Gecode was indeterminstic. The indeterminism
92+
was based on using memory addresses for determining the order of
93+
variables which in turn affected which propagator might record
94+
failure first and hence influenced the branching decisions.
95+
8496
[ENTRY]
8597
Module: example
8698
What: new

gecode/int/bin-packing/propagate.hpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,8 +80,7 @@ namespace Gecode { namespace Int { namespace BinPacking {
8080
/// For sorting according to size
8181
forceinline bool
8282
operator <(const Item& i, const Item& j) {
83-
return ((i.size() > j.size()) ||
84-
((i.size() == j.size()) && (i.bin() < j.bin())));
83+
return i.size() > j.size();
8584
}
8685

8786

gecode/int/linear.hh

100644100755
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1339,6 +1339,8 @@ namespace Gecode { namespace Int { namespace Linear {
13391339
int a;
13401340
/// View
13411341
View x;
1342+
/// Original position in array (for sorting into canonical order)
1343+
int p;
13421344
};
13431345

13441346
/** \brief Estimate lower and upper bounds

gecode/int/linear/post.hpp

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -65,14 +65,25 @@ namespace Gecode { namespace Int { namespace Linear {
6565

6666
/// Sort linear terms by view
6767
template<class View>
68-
class TermLess {
68+
class TermByView {
6969
public:
7070
forceinline bool
7171
operator ()(const Term<View>& a, const Term<View>& b) {
7272
return a.x < b.x;
7373
}
7474
};
7575

76+
/// Sort linear terms by coefficient size and original position
77+
template<class View>
78+
class TermBySizePos {
79+
public:
80+
forceinline bool
81+
operator ()(const Term<View>& a, const Term<View>& b) {
82+
assert((a.a > 0) && (b.a > 0));
83+
return (a.a > b.a) || ((a.a == b.a) && (a.p < b.p));
84+
}
85+
};
86+
7687
/// Compute the greatest common divisor of \a a and \a b
7788
inline int
7889
gcd(int a, int b) {
@@ -116,28 +127,34 @@ namespace Gecode { namespace Int { namespace Linear {
116127
Term<View>* &t_p, int &n_p,
117128
Term<View>* &t_n, int &n_n,
118129
int& g) {
130+
// Number terms by position
131+
for (int i=0; i<n; i++)
132+
t[i].p = i;
133+
119134
/*
120135
* Join coefficients for aliased variables:
121136
*
122137
*/
123138
{
124139
// Group same variables
125-
TermLess<View> tl;
126-
Support::quicksort<Term<View>,TermLess<View> >(t,n,tl);
140+
TermByView<View> tl;
141+
Support::quicksort<Term<View>,TermByView<View>>(t,n,tl);
127142

128143
// Join adjacent variables
129144
int i = 0;
130145
int j = 0;
131146
while (i < n) {
132147
Limits::check(t[i].a,"Int::linear");
133148
long long int a = t[i].a;
149+
int p = t[i].p;
134150
View x = t[i].x;
135151
while ((++i < n) && (t[i].x == x)) {
136152
a += t[i].a;
153+
p = std::min(p,t[i].p);
137154
Limits::check(a,"Int::linear");
138155
}
139156
if (a != 0) {
140-
t[j].a = static_cast<int>(a); t[j].x = x; j++;
157+
t[j].a = static_cast<int>(a); t[j].x = x; t[j].p = p; j++;
141158
}
142159
}
143160
n = j;
@@ -170,6 +187,15 @@ namespace Gecode { namespace Int { namespace Linear {
170187
for (int i=0; i<n_n; i++)
171188
t_n[i].a = -t_n[i].a;
172189

190+
/*
191+
* Sort terms into canonical order (to avoid indeterminstic order)
192+
*/
193+
{
194+
TermBySizePos<View> tl;
195+
Support::quicksort<Term<View>,TermBySizePos<View>>(t_p,n_p,tl);
196+
Support::quicksort<Term<View>,TermBySizePos<View>>(t_n,n_n,tl);
197+
}
198+
173199
/*
174200
* Compute greatest common divisor
175201
*

0 commit comments

Comments
 (0)