Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 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
2 changes: 1 addition & 1 deletion parsers/src/test/resources/flatzinc/hard_instances.csv
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#year,name,solutions,best,nodes,fails
2020,skill_allocation+mzn_1m_1.fzn,1,2,6196,6195
2020,stable-goods-solution+s-d6.fzn,13,6264,146933,146908
2018,rotating-workforce+ex1479.fzn,1,_,125855,125753
2018,rotating-workforce+ex1479.fzn,1,_,125773,125671
2016,tpp+6_3_20_1.fzn,65,131,2813024,2812895
2012,still-life-wastage+still-life+09.fzn,5,43,109471,109462
2012,still-life-wastage+still-life+10.fzn,7,54,164574,164561
Expand Down
6 changes: 3 additions & 3 deletions parsers/src/test/resources/xcsp/instances.csv
Original file line number Diff line number Diff line change
Expand Up @@ -74,9 +74,9 @@ basics;Ramsey-12.xml.lzma;54;2;57445;33115
basics;Rcpsp-j30-01-01_c18.xml.lzma;7;43;199;162
basics;Rlfap-graph-04-opt_c18.xml.lzma;10;394;2651;1656
basics;RoomMate-sr0050-int.xml.lzma;1;_;2;0
basics;SocialGolfers-4-3-4-cp.xml.lzma;1;_;249;177
basics;SocialGolfers-4-3-4-cp.xml.lzma;1;_;227;161
#basics;Sonet-s2ring02.xml.lzma;9;14;815744;621835
basics;SportsScheduling-08.xml.lzma;1;_;210;168
basics;SportsScheduling-08.xml.lzma;1;_;181;150
basics;SteelMillSlab-m1-simple_c18.xml.lzma;4;0;221;180
basics;SteelMillSlab-m2-simple_c18.xml.lzma;2;0;228;196
basics;SteelMillSlab-m2s-mini-simple_c18.xml.lzma;1;0;127;50
Expand All @@ -99,6 +99,6 @@ basics;testObjective1.xml.lzma;2;11;8;5
basics;testPrimitive.xml.lzma;1;_;3;1
#basics;TestSchedulingM18-t30m10r3-15.xml.lzma;93;4149;3450;2650
basics;Tpp-3-3-20-1.xml.lzma;9;126;273;217
basics;TravelingTournament-a3-galaxy04_c18.xml.lzma;6;416;3765;3425
basics;TravelingTournament-a3-galaxy04_c18.xml.lzma;6;416;3693;3378
basics;Warehouse-opl.xml.lzma;19;383;130;90
basics;Zebra.xml.lzma;1;_;9;2
Original file line number Diff line number Diff line change
Expand Up @@ -1779,14 +1779,51 @@ default Constraint element(IntVar value, IntVar[] table, IntVar index, int offse
* Creates a global cardinality constraint (GCC):
* Each value values[i] should be taken by exactly occurrences[i] variables of vars.
* <br/>
* This constraint does not ensure any well-defined level of consistency, yet.
* Uses {@link GlobalCardinality#defaultConsistency()} (see
* {@link #globalCardinality(IntVar[], int[], IntVar[], boolean, String)}) — {@code "BC"}
* unless overridden via the {@value GlobalCardinality#CONSISTENCY_PROPERTY} system property.
*
* @param vars collection of variables
* @param values collection of constrained values
* @param occurrences collection of cardinality variables
* @param closed restricts domains of vars to values if set to true
*/
default Constraint globalCardinality(IntVar[] vars, int[] values, IntVar[] occurrences, boolean closed) {
return globalCardinality(vars, values, occurrences, closed,
GlobalCardinality.defaultConsistency().name());
}

/**
* Creates a global cardinality constraint (GCC):
* Each value values[i] should be taken by exactly occurrences[i] variables of vars.
*
* @param vars collection of variables
* @param values collection of constrained values
* @param occurrences collection of cardinality variables
* @param closed restricts domains of vars to values if set to true
* @param consistency consistency level, among {"DEFAULT", "BC", "AC"}
* <p>
* <b>DEFAULT</b>:
* <br/>
* Fast filtering, without any well-defined level of consistency.
* <p>
* <b>BC</b>:
* <br/>
* Bound-consistency, based on:
* C.-G. Quimper, P. van Beek, A. Lopez-Ortiz, A. Golynski, and S.B. Sadjad.
* "An efficient bounds consistency algorithm for the global cardinality
* constraint." CP-2003.
* Posted in addition to the {@code "DEFAULT"} filtering.
* <p>
* <b>AC</b>:
* <br/>
* Arc-consistency, based on:
* J.-C. Regin. "Generalized Arc Consistency for Global Cardinality
* Constraint." AAAI-96.
* Posted in addition to the {@code "DEFAULT"} filtering.
*/
default Constraint globalCardinality(IntVar[] vars, int[] values, IntVar[] occurrences,
boolean closed, String consistency) {
if (ref().getSolver().isLCG()) {
if (ref().getSettings().warnUser()) {
ref().getSolver().log().white().println("Warning: globalCardinality constraint is decomposed (due to LCG).");
Expand Down Expand Up @@ -1827,10 +1864,10 @@ default Constraint globalCardinality(IntVar[] vars, int[] values, IntVar[] occur
v2[i] = toAdd.get(i - values.length);
cards[i] = vars[0].getModel().intVar(0);
}
return new GlobalCardinality(vars, v2, cards);
return new GlobalCardinality(vars, v2, cards, consistency);
}
}
return new GlobalCardinality(vars, values, occurrences);
return new GlobalCardinality(vars, values, occurrences, consistency);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,74 @@
*/
public class GlobalCardinality extends Constraint {

/**
* Consistency level enforced by the propagator(s) posted for a {@link GlobalCardinality}
* constraint.
*/
public enum Consistency {
/**
* Fast filtering (see {@link PropFastGCC}), without any well-defined consistency level
* guarantee.
*/
DEFAULT,
/**
* Bound-consistency (see {@link PropGccBC}), following:
* C.-G. Quimper, P. van Beek, A. Lopez-Ortiz, A. Golynski, and S.B. Sadjad.
* "An efficient bounds consistency algorithm for the global cardinality constraint."
* CP-2003.
*/
BC,
/**
* Arc-consistency (see {@link PropGccAC}), following:
* J.-C. Regin. "Generalized Arc Consistency for Global Cardinality Constraint." AAAI-96.
*/
AC
}

/**
* System property used to override the default {@link Consistency} level, e.g.
* {@code -Dchoco.gcc.consistency=AC}. See {@link #defaultConsistency()}.
*/
public static final String CONSISTENCY_PROPERTY = "choco.gcc.consistency";

/**
* Returns the {@link Consistency} level used when none is explicitly specified, e.g. by
* {@link #GlobalCardinality(IntVar[], int[], IntVar[])} or by
* {@link org.chocosolver.solver.constraints.IIntConstraintFactory#globalCardinality(IntVar[], int[], IntVar[], boolean)}.
* <p>
* Defaults to {@link Consistency#BC}, which matches or beats {@link Consistency#AC} on
* solution quality while being cheaper to propagate, and both markedly outperform
* {@link Consistency#DEFAULT} on tightly-constrained instances.
* <p>
* Can be overridden via the {@value #CONSISTENCY_PROPERTY} system property (e.g. to
* benchmark alternative filtering levels without changing calling code).
*
* @return the default consistency level
* @throws IllegalArgumentException if the {@value #CONSISTENCY_PROPERTY} property is set to
* a value that is not a valid {@link Consistency} name
*/
public static Consistency defaultConsistency() {
return Consistency.valueOf(System.getProperty(CONSISTENCY_PROPERTY, Consistency.BC.name()));
}

/**
* Creates a global cardinality constraint using the {@linkplain #defaultConsistency() default
* consistency level}.
*
* @param vars collection of variables
* @param values collection of constrained values
* @param cards collection of cardinality variables
*/
public GlobalCardinality(IntVar[] vars, int[] values, IntVar[] cards) {
super(ConstraintsName.GCC, createProp(vars, values, cards));
this(vars, values, cards, defaultConsistency().name());
}

public GlobalCardinality(IntVar[] vars, int[] values, IntVar[] cards, String consistency) {
super(ConstraintsName.GCC, createProp(vars, values, cards, Consistency.valueOf(consistency)));
}

private static Propagator<IntVar> createProp(IntVar[] vars, int[] values, IntVar[] cards) {
private static Propagator<IntVar>[] createProp(IntVar[] vars, int[] values, IntVar[] cards,
Consistency consistency) {
assert values.length == cards.length;
TIntIntHashMap map = new TIntIntHashMap();
int idx = 0;
Expand All @@ -41,7 +104,18 @@ private static Propagator<IntVar> createProp(IntVar[] vars, int[] values, IntVar
throw new UnsupportedOperationException("ERROR: multiple occurrences of value: " + v);
}
}
return new PropFastGCC(vars, values, map, cards);
PropFastGCC fast = new PropFastGCC(vars, values, map, cards);
switch (consistency) {
case BC:
//noinspection unchecked
return new Propagator[]{fast, new PropGccBC(vars, values, cards)};
case AC:
//noinspection unchecked
return new Propagator[]{fast, new PropGccAC(vars, values, cards)};
default:
//noinspection unchecked
return new Propagator[]{fast};
}
}

public static Constraint reformulate(IntVar[] vars, IntVar[] card, Model model) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
/*
* This file is part of choco-solver, http://choco-solver.org/
* Copyright (c) 1999, IMT Atlantique.
* SPDX-License-Identifier: BSD-3-Clause.
* See LICENSE file in the project root for full license information.
*/
package org.chocosolver.solver.constraints.nary.globalcardinality;

import org.chocosolver.solver.constraints.Propagator;
import org.chocosolver.solver.constraints.PropagatorPriority;
import org.chocosolver.solver.constraints.nary.globalcardinality.algo.AlgoGccAC;
import org.chocosolver.solver.exception.ContradictionException;
import org.chocosolver.solver.variables.IntVar;
import org.chocosolver.util.ESat;
import org.chocosolver.util.tools.ArrayUtils;

import java.util.Arrays;

/**
* Arc-consistency propagator for the Global Cardinality Constraint (GCC), based on:
* J.-C. Regin. "Generalized Arc Consistency for Global Cardinality Constraint." AAAI-96.
* <p>
* Meant to be posted alongside {@link PropFastGCC}, which is left in charge of tightening the
* bounds of the cardinality variables and of the soundness/completeness of the constraint; this
* propagator only brings arc-consistency on the decision variables.
*
* @author Charles Prud'homme
*/
public class PropGccAC extends Propagator<IntVar> {

//***********************************************************************************
// VARIABLES
//***********************************************************************************

private final int n;
private final int n2;
private final int[] values;
private final AlgoGccAC filter;

//***********************************************************************************
// CONSTRUCTORS
//***********************************************************************************

/**
* @param decvars array of decision variables
* @param restrictedValues array of restricted values
* @param valueCardinalities array of cardinality variables, one per restricted value
*/
public PropGccAC(IntVar[] decvars, int[] restrictedValues, IntVar[] valueCardinalities) {
super(ArrayUtils.append(decvars, valueCardinalities), PropagatorPriority.QUADRATIC, false);
this.values = restrictedValues;
this.n = decvars.length;
this.n2 = values.length;
this.filter = new AlgoGccAC(this);
filter.reset(decvars);
}

//***********************************************************************************
// PROPAGATION
//***********************************************************************************

@Override
public void propagate(int evtmask) throws ContradictionException {
int gMin = Integer.MAX_VALUE;
int gMax = Integer.MIN_VALUE;
for (int i = 0; i < n; i++) {
gMin = Math.min(gMin, vars[i].getLB());
gMax = Math.max(gMax, vars[i].getUB());
}
for (int v : values) {
gMin = Math.min(gMin, v);
gMax = Math.max(gMax, v);
}
int range = gMax - gMin + 1;
int[] minOcc = new int[range];
int[] maxOcc = new int[range];
// values out of the restricted list are unconstrained: [0, n]
Arrays.fill(maxOcc, n);
for (int i = 0; i < n2; i++) {
IntVar card = vars[n + i];
int idx = values[i] - gMin;
minOcc[idx] = card.getLB();
maxOcc[idx] = card.getUB();
}
filter.filter(minOcc, maxOcc, gMin);
}

//***********************************************************************************
// INFO
//***********************************************************************************

@Override
public ESat isEntailed() {
return ESat.TRUE; // redundant propagator, PropFastGCC already checks correctness
}

@Override
public String toString() {
StringBuilder st = new StringBuilder();
st.append("PropGccAC_(");
int i = 0;
for (; i < Math.min(4, vars.length); i++) {
st.append(vars[i].getName()).append(", ");
}
if (i < vars.length - 2) {
st.append("...,");
}
st.append(vars[vars.length - 1].getName()).append(")");
return st.toString();
}

}
Loading
Loading