You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
allow to model as many constraints as possible, and have sets like CountAtLeast (at least n values in an array x equal to y) or with parametrised types Count{MOI.GreaterThan}: this might create a real explosion in terms of new MOI-level sets to create, and all of these sets would be user-visible (i.e. it would be hard for a user to learn how to use the CP functionalities)
don't allow sets like CountAtLeast at all, unless where they really make sense (like circuit, a nontrivial constraint): there would be fewer sets (which is good for the user), but we may miss some optimisation for the solvers, as this would entail creating a few more variables and constraints than strictly required (as far as I know, preprocessing in CP is far from what can be achieved for MIP)
do a mix: don't show too many sets for the user (no user-facing CountAtLeast), but propose some kind of generic reformulation engine based on bridges: when a better construct is available for the solver at hand, replace the set of constraints count(x .== y) <= n by the best construct for this solver. Bridges are made to work in reverse, though, but the principle is similar, as not all solvers support terser constructs. The major drawbacks of this solution are that such an engine would not be trivial to implement, and that model-building times will suffer (although CP models usually do not have as many constraints as MIP models)
in some cases, functions can be used instead of constraints, like counting: if count(x .== 1) can be a function (MOI.AbstractScalarFunction), then atleast can be expressed as count(x .== 1)-in-GreaterThan(4).
another compromise would be to have this kind of rewriting dealt with at the level of the CP-solver wrapper, but that would probably mean a lot of code duplication.
My opinion would be to always add sets that make sense to the user: things like Circuit, but not like CountAtLeast. This way, the user could write models quite easily. Probably the solvers cannot be used to their fullest, but at least the user can model anything. I thought there was a discussion to create a preprocessing engine for JuMP, but I can't find it back.
The text was updated successfully, but these errors were encountered:
For instance,
atleast
can be easily implemented in terms ofcount
and a>=
constraint, as proposed for CPLEX: https://www.ibm.com/support/knowledgecenter/SSSA5P_12.5.1/ilog.odms.studio.help/OPL_Studio/oplmigration/topics/opl_mig_prev_3x4x_3xCP_constr_atleast.html.Some solvers propose the
atleast
constraint directly, like Gecode: https://www.gecode.org/doc/6.2.0/reference/group__TaskModelMiniModelIntAlias.html#ga4ebc48aabe7b8ce01d0b07caad5e88cc. It is also available directly fromcount
withIntRelType
: https://github.com/Gecode/gecode/blob/027c57889d66dd26ad8e1a419c2cda22ab0cf305/gecode/int/count.cppHowever, Gecode has different propagators for these cases: https://github.com/Gecode/gecode/tree/027c57889d66dd26ad8e1a419c2cda22ab0cf305/gecode/int/count
The same situation appears for more complex constraints, like
circuit
: OR-Tools and Gecode have specific propagators, CPLEX no more allows to input this constraint directly: https://www.ibm.com/support/knowledgecenter/SSSA5P_12.5.1/ilog.odms.studio.help/OPL_Studio/oplmigration/topics/opl_mig_prev_3x4x_3xCP_constr_circuit.html. The major difference is that it is not as straightforward to implement acircuit constraint
with other constraints.Here is the choice to make:
CountAtLeast
(at leastn
values in an arrayx
equal toy
) or with parametrised typesCount{MOI.GreaterThan}
: this might create a real explosion in terms of new MOI-level sets to create, and all of these sets would be user-visible (i.e. it would be hard for a user to learn how to use the CP functionalities)CountAtLeast
at all, unless where they really make sense (likecircuit
, a nontrivial constraint): there would be fewer sets (which is good for the user), but we may miss some optimisation for the solvers, as this would entail creating a few more variables and constraints than strictly required (as far as I know, preprocessing in CP is far from what can be achieved for MIP)CountAtLeast
), but propose some kind of generic reformulation engine based on bridges: when a better construct is available for the solver at hand, replace the set of constraintscount(x .== y) <= n
by the best construct for this solver. Bridges are made to work in reverse, though, but the principle is similar, as not all solvers support terser constructs. The major drawbacks of this solution are that such an engine would not be trivial to implement, and that model-building times will suffer (although CP models usually do not have as many constraints as MIP models)count(x .== 1)
can be a function (MOI.AbstractScalarFunction
), thenatleast
can be expressed ascount(x .== 1)
-in-GreaterThan(4)
.My opinion would be to always add sets that make sense to the user: things like
Circuit
, but not likeCountAtLeast
. This way, the user could write models quite easily. Probably the solvers cannot be used to their fullest, but at least the user can model anything. I thought there was a discussion to create a preprocessing engine for JuMP, but I can't find it back.The text was updated successfully, but these errors were encountered: