Skip to content

Optimize checking of unsupported values in CouplesBitSetTable #1161

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

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import org.chocosolver.solver.constraints.extension.Tuples;
import org.chocosolver.solver.variables.IntVar;

import java.util.Arrays;
import java.util.BitSet;

/**
Expand Down Expand Up @@ -79,23 +80,80 @@ public boolean checkCouple(int x, int y) {
return table[0][x - offsets[0]].get(y - offsets[1]);
}

private int lastVar;
private IntVar lastV;
private int lastLB;
private int lastUB;
private BitSet[] lastTable;
private int lastOffset;
private int lastO;
private int[] lastIndex;
private int indexOffset;

/**
* Optimized check that reuses cached data to determine if `val` is unsupported.
*/
private boolean checkUnsupportedValueOptimized(int val) {
BitSet tableForVal = lastTable[val - lastOffset];
int i = lastLB;

while (i <= lastUB) {
if (tableForVal.get(i - lastO)) {
return false;
}
int idx = i + indexOffset;
if (lastIndex[idx] == -1) {
i = lastV.nextValue(i);
lastIndex[idx] = i + indexOffset;
} else {
i = lastIndex[idx] - indexOffset;
}
}

return true;
}

/**
* checks if var=val has no support within the domain of v
* @param var a variable index
* @param val a value for var
* @param v a variable
* @return true iff there exists no support for v where var = val
*
*
* Uses caching to speed up repeated queries on the same variable.
*/
public boolean checkUnsupportedValue(int var, int val, IntVar v) {
int UB = v.getUB();
BitSet _table = table[var][val - offsets[var]];
int o = offsets[1 - var];
for (int i = v.getLB(); i <= UB; i = v.nextValue(i)) {
if (_table.get(i - o)) {
return false;
if (var == lastVar && v == lastV) {
return checkUnsupportedValueOptimized(val);
} else {
// Cache current state
lastVar = var;
lastV = v;
lastLB = v.getLB();
lastUB = v.getUB();
lastTable = table[var];
lastOffset = offsets[var];
lastO = offsets[1 - var];

BitSet tableForVal = lastTable[val - lastOffset];
indexOffset = -lastLB;
int indexSize = lastUB - lastLB + 1;
// Ensure lastIndex is large enough
if (lastIndex == null || lastIndex.length < indexSize) {
lastIndex = new int[indexSize];
}
Arrays.fill(lastIndex, -1);

// Perform full scan
for (int i = lastLB; i <= lastUB; i = v.nextValue(i)) {
if (tableForVal.get(i - lastO)) {
return false;
}
}

return true;
}
return true;
}

@Override
Expand Down
Loading