Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

use square when possible and stronger filtering #1054

Closed
wants to merge 11 commits into from
Closed
Original file line number Diff line number Diff line change
Expand Up @@ -736,7 +736,9 @@ default Constraint mod(IntVar X, IntVar Y, IntVar Z) {
*/
@SuppressWarnings("SuspiciousNameCombination")
default Constraint times(IntVar X, IntVar Y, IntVar Z) {
if (Y.isInstantiated()) {
if (X == Y) {
return square(Z, X);
} else if (Y.isInstantiated()) {
return times(X, Y.getValue(), Z);
} else if (X.isInstantiated()) {
return times(Y, X.getValue(), Z);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,6 @@ protected void updateLowerBoundofX() throws ContradictionException {

protected void updateUpperBoundofX() throws ContradictionException {
vars[0].updateUpperBound(Math.max(sqr(vars[1].getLB()), sqr(vars[1].getUB())), this);

}

protected boolean updateHolesinX() throws ContradictionException {
Expand Down Expand Up @@ -158,16 +157,31 @@ protected boolean updateHolesinX() throws ContradictionException {
}

protected boolean updateLowerBoundofY() throws ContradictionException {
return vars[1].updateLowerBound(-ceil_sqrt(vars[0].getUB()), this);
if (vars[1].getLB() >= 0) {
return vars[1].updateLowerBound(ceil_sqrt(vars[0].getLB()), this);
} else {
return vars[1].updateLowerBound(-floor_sqrt(vars[0].getUB()), this);
}
}

protected boolean updateUpperBoundofY() throws ContradictionException {
return vars[1].updateUpperBound(floor_sqrt(vars[0].getUB()), this);
}
ArthurGodet marked this conversation as resolved.
Show resolved Hide resolved

protected boolean updateHolesinY() throws ContradictionException {
// remove intervals to deal with consecutive value removal and upper bound modification
if (bothEnum) {
if (vars[0].isInstantiatedTo(0)) {
return vars[1].instantiateTo(0, this);
}
ArthurGodet marked this conversation as resolved.
Show resolved Hide resolved
boolean impact = false;
// remove interval around 0 based on X LB
if (vars[1].hasEnumeratedDomain()) {
int val = ceil_sqrt(vars[0].getLB()) - 1;
if (val >= 0) {
impact = vars[1].removeInterval(-val, val, this);
}
}
// remove values based on X holes
if (bothEnum && hasHoles(vars[0])) {
int ub = vars[1].getUB();
vrms.clear();
vrms.setOffset(vars[1].getLB());
Expand All @@ -176,24 +190,12 @@ protected boolean updateHolesinY() throws ContradictionException {
vrms.add(value);
}
}
return vars[1].removeValues(vrms, this);
} else if (vars[1].hasEnumeratedDomain()) {
int lb = vars[1].getLB();
int ub = vars[1].getUB();
while (!vars[0].contains(sqr(lb))) {
lb = vars[1].nextValue(lb);
if (lb > ub) break;
}
boolean filter = vars[1].updateLowerBound(lb, this);

while (!vars[0].contains(sqr(ub))) {
ub = vars[1].nextValue(ub);
if (ub < lb) break;
}
return filter | vars[1].updateUpperBound(ub, this);
impact |= vars[1].removeValues(vrms, this);
}
return false;
return impact;
}


private boolean hasHoles(IntVar var) {
return (var.getUB() - var.getLB() + 1) > var.getDomainSize();
}
}
Loading