Skip to content

Commit

Permalink
More indeterminism fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
chschulte committed Apr 8, 2019
1 parent bda0f1b commit 818150e
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 6 deletions.
12 changes: 12 additions & 0 deletions changelog.in
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,18 @@ using memory addresses for determining the order of variables in
some propagators which in turn affected which propagator might
record failure first and hence influenced the branching decisions.

[ENTRY]
Module: int
What: bug
Rank: major
[DESCRIPTION]
For the combination of binpacking and linear constraints with
shared variable selection branching (that is, AFC, Action, and
CHB) the behavior of Gecode was indeterminstic. The indeterminism
was based on using memory addresses for determining the order of
variables which in turn affected which propagator might record
failure first and hence influenced the branching decisions.

[ENTRY]
Module: example
What: new
Expand Down
3 changes: 1 addition & 2 deletions gecode/int/bin-packing/propagate.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -80,8 +80,7 @@ namespace Gecode { namespace Int { namespace BinPacking {
/// For sorting according to size
forceinline bool
operator <(const Item& i, const Item& j) {
return ((i.size() > j.size()) ||
((i.size() == j.size()) && (i.bin() < j.bin())));
return i.size() > j.size();
}


Expand Down
2 changes: 2 additions & 0 deletions gecode/int/linear.hh
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -1339,6 +1339,8 @@ namespace Gecode { namespace Int { namespace Linear {
int a;
/// View
View x;
/// Original position in array (for sorting into canonical order)
int p;
};

/** \brief Estimate lower and upper bounds
Expand Down
34 changes: 30 additions & 4 deletions gecode/int/linear/post.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,14 +65,25 @@ namespace Gecode { namespace Int { namespace Linear {

/// Sort linear terms by view
template<class View>
class TermLess {
class TermByView {
public:
forceinline bool
operator ()(const Term<View>& a, const Term<View>& b) {
return a.x < b.x;
}
};

/// Sort linear terms by coefficient size and original position
template<class View>
class TermBySizePos {
public:
forceinline bool
operator ()(const Term<View>& a, const Term<View>& b) {
assert((a.a > 0) && (b.a > 0));
return (a.a > b.a) || ((a.a == b.a) && (a.p < b.p));
}
};

/// Compute the greatest common divisor of \a a and \a b
inline int
gcd(int a, int b) {
Expand Down Expand Up @@ -116,28 +127,34 @@ namespace Gecode { namespace Int { namespace Linear {
Term<View>* &t_p, int &n_p,
Term<View>* &t_n, int &n_n,
int& g) {
// Number terms by position
for (int i=0; i<n; i++)
t[i].p = i;

/*
* Join coefficients for aliased variables:
*
*/
{
// Group same variables
TermLess<View> tl;
Support::quicksort<Term<View>,TermLess<View> >(t,n,tl);
TermByView<View> tl;
Support::quicksort<Term<View>,TermByView<View>>(t,n,tl);

// Join adjacent variables
int i = 0;
int j = 0;
while (i < n) {
Limits::check(t[i].a,"Int::linear");
long long int a = t[i].a;
int p = t[i].p;
View x = t[i].x;
while ((++i < n) && (t[i].x == x)) {
a += t[i].a;
p = std::min(p,t[i].p);
Limits::check(a,"Int::linear");
}
if (a != 0) {
t[j].a = static_cast<int>(a); t[j].x = x; j++;
t[j].a = static_cast<int>(a); t[j].x = x; t[j].p = p; j++;
}
}
n = j;
Expand Down Expand Up @@ -170,6 +187,15 @@ namespace Gecode { namespace Int { namespace Linear {
for (int i=0; i<n_n; i++)
t_n[i].a = -t_n[i].a;

/*
* Sort terms into canonical order (to avoid indeterminstic order)
*/
{
TermBySizePos<View> tl;
Support::quicksort<Term<View>,TermBySizePos<View>>(t_p,n_p,tl);
Support::quicksort<Term<View>,TermBySizePos<View>>(t_n,n_n,tl);
}

/*
* Compute greatest common divisor
*
Expand Down

0 comments on commit 818150e

Please sign in to comment.