Skip to content

Commit

Permalink
Fix error in affine view detection
Browse files Browse the repository at this point in the history
  • Loading branch information
cprudhom committed Oct 12, 2023
1 parent 87cf1e5 commit fd3f1e9
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 37 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2582,7 +2582,7 @@ default Constraint tree(IntVar[] succs, IntVar nbTrees, int offset) {
* Get the list of values in the domains of vars
*
* @param vars an array of integer variables
* @return the list of values in the domains of vars
* @return the array of values in the domains of vars
*/
default int[] getDomainUnion(IntVar... vars) {
int m = vars[0].getLB(), M = vars[0].getUB(), j, k;
Expand Down Expand Up @@ -2640,7 +2640,8 @@ static Object[] variableUniqueness(Object[]... vars) {
for (int i = 0; i < allvars.size(); i++) {
for (int j = i + 1; j < allvars.size(); j++) {
if (allvars.get(i).equals(allvars.get(j))) {
allvars.set(j, IntAffineView.make(allvars.get(i), 1, 0));
// force the view to be created, no call to ref().intView() here !
allvars.set(j, new IntAffineView<>(allvars.get(i), 1, 0));
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,18 @@ default IntVar intView(int a, IntVar var, int b) {
}
}
}
return IntAffineView.make(var, a, b);
if (var instanceof IntAffineView) {
IntAffineView<?> view = (IntAffineView<?>) var;
int av = (view.p ? 1 : -1) * view.a * a;
int bv = view.a * b + view.b;
if (av == 1 && bv == 0) {
return view.getVariable();
}else{
return intView(av, view.getVariable(), bv);
}
} else {
return new IntAffineView<>(var, a, b);
}
} else {
int lb, ub;
if (a > 0) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,30 +34,21 @@
*/
public final class IntAffineView<I extends IntVar> extends IntView<I> {

final boolean p; // positive
final int a;
final int b;


public static IntAffineView<IntVar> make(IntVar var, int a, int b) {
if (var instanceof IntAffineView) {
IntAffineView<?> view = (IntAffineView<?>) var;
return new IntAffineView<>(view.getVariable(), view.p & (a >= 0), view.a * Math.abs(a), view.a * b + view.b);
} else {
return new IntAffineView<>(var, a >= 0, Math.abs(a), b);
}
}
public final boolean p; // positive
public final int a;
public final int b;

/**
* <i>y</i> is an affine view of <i>x</i>: <i>y = (-1)a*x + b</i>.
* <i>y</i> is an affine view of <i>x</i>: <i>y = a*x + b</i>.
*
* @param var a integer variable
* @param a a coefficient
* @param b a constant
*/
private IntAffineView(final I var, boolean p, int a, int b) {
super((p ? "" : "-") + a + ".(" + var.getName() + ") + " + b, var);
assert a > 0;
this.p = p;
this.a = a;
public IntAffineView(final I var, int a, int b) {
super(a + ".(" + var.getName() + ") + " + b, var);
this.p = a >= 0;
this.a = Math.abs(a);
this.b = b;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ public Object[][] configurations() {
public void testNextValue(int a, int b, int... domain) {
Model model = new Model();
IntVar x = model.intVar("x", domain);
IntVar y = IntAffineView.make(x, a, b);
IntVar y = new IntAffineView<>(x, a, b);

int[] values = Arrays.stream(domain).map(i -> (a * i) + b).sorted().toArray();

Expand All @@ -78,20 +78,11 @@ public void testNextValue(int a, int b, int... domain) {
Assert.assertEquals(y.nextValue(values[2]), Integer.MAX_VALUE);
}

@Test(groups = "1s")
public void testNextValue2() {
Model model = new Model();
IntVar x = model.intVar("x", 2, 9);
IntVar y = IntAffineView.make(x, 5, 7);


}

@Test(groups = "1s", dataProvider = "configurations")
public void testPreviousValue(int a, int b, int... domain) {
Model model = new Model();
IntVar x = model.intVar("x", domain);
IntVar y = IntAffineView.make(x, a, b);
IntVar y = new IntAffineView<>(x, a, b);

int[] values = Arrays.stream(domain).map(i -> a * i + b).sorted().toArray();

Expand All @@ -108,7 +99,7 @@ public void testPreviousValue(int a, int b, int... domain) {
public void testNextValueOut(int a, int b, int... domain) {
Model model = new Model();
IntVar x = model.intVar("x", domain);
IntVar y = IntAffineView.make(x, a, b);
IntVar y = new IntAffineView<>(x, a, b);

int[] values = Arrays.stream(domain).map(i -> (a * i) + b).sorted().toArray();
BitSet valuesOut = new BitSet();
Expand All @@ -129,7 +120,7 @@ public void testNextValueOut(int a, int b, int... domain) {
public void testPreviousValueOut(int a, int b, int... domain) {
Model model = new Model();
IntVar x = model.intVar("x", domain);
IntVar y = IntAffineView.make(x, a, b);
IntVar y = new IntAffineView<>(x, a, b);

int[] values = Arrays.stream(domain).map(i -> (a * i) + b).sorted().toArray();
BitSet valuesOut = new BitSet();
Expand All @@ -151,7 +142,7 @@ public void testPreviousValueOut(int a, int b, int... domain) {
public void testValueIterator(int a, int b, int... domain) {
Model model = new Model();
IntVar x = model.intVar("x", domain);
IntVar y = IntAffineView.make(x, a, b);
IntVar y = new IntAffineView<>(x, a, b);

int[] values = Arrays.stream(domain).map(i -> a * i + b).sorted().toArray();

Expand All @@ -178,7 +169,7 @@ public void testValueIterator(int a, int b, int... domain) {
public void testRangeIterator(int a, int b, int... domain) {
Model model = new Model();
IntVar x = model.intVar("x", domain);
IntVar y = IntAffineView.make(x, a, b);
IntVar y = new IntAffineView<>(x, a, b);

int[] values = Arrays.stream(domain).map(i -> a * i + b).sorted().toArray();

Expand Down

0 comments on commit fd3f1e9

Please sign in to comment.