public static Constraint global_cardinality(IntVar[] VARS, int[] VALUES, IntVar[] OCCURRENCES, boolean CLOSED) {
assert VALUES.length == OCCURRENCES.length;
if (!CLOSED) {
return new GlobalCardinality(VARS, VALUES, OCCURRENCES);
} else {
TIntArrayList toAdd = new TIntArrayList();
TIntSet givenValues = new TIntHashSet();
for (int i : VALUES) {
assert !givenValues.contains(i);
givenValues.add(i);
}
for (IntVar var : VARS) {
int ub = var.getUB();
for (int k = var.getLB(); k <= ub; k = var.nextValue(k)) {
if (!givenValues.contains(k)) {
if (!toAdd.contains(k)) {
toAdd.add(k);
}
}
}
}
if (toAdd.size() > 0) {
int n2 = VALUES.length + toAdd.size();
int[] values = new int[n2];
IntVar[] cards = new IntVar[n2];
System.arraycopy(VALUES, 0, values, 0, VALUES.length);
System.arraycopy(OCCURRENCES, 0, cards, 0, VALUES.length);
for (int i = VALUES.length; i < n2; i++) {
values[i] = toAdd.get(i - VALUES.length);
cards[i] = VariableFactory.fixed(0, VARS[0].getSolver());
}
return new GlobalCardinality(VARS, values, cards);
} else {
return new GlobalCardinality(VARS, VALUES, OCCURRENCES);