Variable Types
Minion’s input language is purposefully designed to align with Minion’s internals. Unlike most other constraint solvers, Minion does not add extra variables or decompose large complex constraints into smaller parts. This design provides complete control over how problem representation within Minion but requires a solid understanding how Minion works to achieve the best results.
One of the most immediately confusing features of Minion is its variable types. Rather than try to provide a “one-size-fits-all” variable implementation, Minion provides four distinct ones; BOOL,
DISCRETE, BOUND and SPARSEBOUND. All variables have a finite domain of integers. First we shall provide a brief discussion of both what these variables are, and a brief
discussion of why their advantages and disadvantages.
BOOLVariables with domain \(\{0,1\}\). Uses special optimised data structure.
DISCRETEVariables whose domain is a range of integers. Memory usage and the worst-case performance of most operations is O(domain size). Allows any subset of the domain to be represented.
BOUNDVariable whose domain is a range of integers. Memory usage and the worst-case performance of all operations is O(1). During search, the domain can only be reduced by changing one of the bounds.
SPARSEBOUNDVariable whose domain is an arbitrary range of integers. Otherwise identical to BOUND.
It might seem that a SPARSEDISCRETE variable implementation, which is missing from the discussion, would be beneficial. However, this turns out not to be practical in most cases. This turns out not to be useful in practice.
Technically, there is a 5th type of variable – CONSTANT. Integer constants can be given wherever a variable can be used. These are represented internally as a special type of variable whose domain is a single value.
When you want a DISCRETE variable with domain that is not a complete range of integers, the extra values can be removed using the w-inintervalset constraint (discussed later, in the constraints).
Some of the differences between the variable types only effect performance, whereas some others can impact search size.
In any problem, changing a
BOOLvariable to aDISCRETE,BOUNDorSPARSEBOUNDvariable with domain \(\{0,1\}\) will not change the size of the resulting search.BOOLshould always be fastest, followed byDISCRETE,BOUNDandSPARSEBOUND.A
BOUNDvariable will in general produce a search which explores nodes faster, but may have more search nodes, than aDISCRETEvariable.Using
SPARSEBOUNDorBOUNDvariables with a unary constraint imposing the sparse domain should produce identical searches, except theSPARSEBOUNDwill be faster if the domain is very sparse.
As a general guideline, always use BOOL for Boolean domains,
DISCRETE for domains up to 1000 elements, and then BOUND.
With DISCRETE domains, use the w-inintervalset constraint to limit the
domain. When to use SPARSEBOUND over BOUND is harder, but
usually the choice is clear, as either the domain will be a range, or a very sparse list, like \(\{1,100,1000,10000\}\).