Incorporate Background feedback from Peter
This commit is contained in:
parent
b5ff72e95f
commit
3687260209
@ -45,7 +45,7 @@
|
||||
\newacronym[see={[Glossary:]{gls-mip}}]{mip}{MIP\glsadd{gls-mip}}{Mixed Integer
|
||||
Programming}
|
||||
|
||||
\newacronym{np-comp}{NP-complete}{Nondeterministic Polynomial-time complete}
|
||||
\newacronym{np}{NP}{Nondeterministic Polynomial-time}
|
||||
|
||||
\newacronym[see={[Glossary:]{gls-opl}}]{opl}{OPL\glsadd{gls-opl}}{The
|
||||
Optimisation Programming Language}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -29,10 +29,10 @@ the modelling of \gls{cop}, where a \gls{csp} is augmented with a
|
||||
\gls{objective} \(z\). In this case the goal is to find a solution that
|
||||
satisfies all \constraints{} while minimising (or maximising) \(z\).
|
||||
|
||||
Although a constraint model does not contain any instructions to find a suitable
|
||||
solution, these models can generally be given to a dedicated solving program, or
|
||||
\solver{} for short, that can find a solution that fits the requirements of the
|
||||
model.
|
||||
Although a constraint model does not contain any instructions on how to find a
|
||||
suitable solution, these models can generally be given to a dedicated solving
|
||||
program, or \solver{} for short, that can find a solution that fits the
|
||||
requirements of the model.
|
||||
|
||||
\begin{example}%
|
||||
\label{ex:back-knapsack}
|
||||
@ -178,16 +178,17 @@ format. In \minizinc\ these items are not constrained to occur in any particular
|
||||
order. We will briefly discuss the most important model items. For a detailed
|
||||
overview of the structure of \minizinc\ models you can consult the full
|
||||
syntactic structure of \minizinc\ 2.5.5 in \cref{ch:minizinc-grammar}.
|
||||
Nethercote et al.\ and Mariott et al.\ offer a detailed discussion of the
|
||||
Nethercote et al.\ and Marriott et al.\ offer a detailed discussion of the
|
||||
\minizinc\ and \zinc\ language, its predecessor, respectively
|
||||
\autocite*{nethercote-2007-minizinc,marriott-2008-zinc}.
|
||||
|
||||
Values in \minizinc\ are declared in the form \mzninline{@\(T\)@: @\(I\)@ =
|
||||
@\(E\)@;}. \(T\) is the type of the declared value, \(I\) is a new identifier
|
||||
used to reference the declared value, and, optionally, the modeller can
|
||||
functionally define the value using an expression \(E\). The identifier used in
|
||||
a top-level value definition must be unique. Two declarations with the same
|
||||
identifier will result in an error during the flattening process.
|
||||
Values in \minizinc\ are declared in the form \mzninline{@\(T\)@: @\(I\)@;} or
|
||||
\mzninline{@\(T\)@: @\(I\)@ = @\(E\)@;}. \(T\) is the type of the declared
|
||||
value, \(I\) is a new identifier used to reference the declared value, and,
|
||||
optionally, the modeller can functionally define the value using an expression
|
||||
\(E\). The identifier used in a top-level value definition must be unique. Two
|
||||
declarations with the same identifier will result in an error during the
|
||||
flattening process.
|
||||
|
||||
The main types used in \minizinc\ are Boolean, integer, floating point numbers,
|
||||
sets of integers, and (user-defined) enumerated types. These types can be used
|
||||
@ -206,16 +207,14 @@ type expression. These expressions constrain a declaration, not just to a
|
||||
certain type, but also to a set of value. This set of values is generally
|
||||
referred to as the \gls{domain} of a \variable{}. In \minizinc\ any expression
|
||||
that has a set type can be used as a type expression. For example, the following
|
||||
two declarations
|
||||
two declarations declare two integer \variables{} that can take the values from
|
||||
three to five and one, three, and five respectively.
|
||||
|
||||
\begin{mzn}
|
||||
var 3..5: x;
|
||||
var {1,3,5}: y;
|
||||
\end{mzn}
|
||||
|
||||
declare two integer \variables{} that can take the values from three to five and
|
||||
one, three, and five respectively.
|
||||
|
||||
If the declaration includes an expression to functionally define the value, then
|
||||
the identifier can be used as a name for this expression. If, however, the type
|
||||
of the declaration is given as a type expression, then this places an implicit
|
||||
@ -235,7 +234,9 @@ solver to do one of three actions: to find an assignment to the \variables{}
|
||||
that satisfies the constraints, \mzninline{solve satisfy;}, to find an
|
||||
assignment to the \variables{} that satisfies the constraints and minimises the
|
||||
value of a \variable{}, \mzninline{solve minimize x;}, or similarly maximises
|
||||
the value of a \variable{}, \mzninline{solve maximize x;}.
|
||||
the value of a \variable{}, \mzninline{solve maximize x;}. If the model does not
|
||||
contain a goal item, then it then the problem is assumed to be a satisfaction
|
||||
problem.
|
||||
|
||||
\jip{TODO:\@ add some information about search in \minizinc{}. It's probably
|
||||
pretty relevant.}
|
||||
@ -261,7 +262,7 @@ to function calls. A solver can then provide its own implementation for these
|
||||
functions. It is assumed that the implementation of the functions in the
|
||||
\solver{} libraries will ultimately be rewritten into fully relational call.
|
||||
When a relational constraint is directly supported by a solver the function
|
||||
should be declared within an expression body. Any call to such function is
|
||||
should be declared within an expression body. Any call to such a function is
|
||||
directly placed in the flattened model.
|
||||
|
||||
\subsection{MiniZinc Expressions}%
|
||||
@ -273,10 +274,7 @@ read, but are transformed to fit the structure best suited to the chosen
|
||||
\solver{}. We will now briefly discuss the most important \minizinc\ expressions
|
||||
and the general methods employed when flattening them. A detailed overview of
|
||||
the full syntactic structure of the \minizinc\ expressions in \minizinc\ 2.5.5
|
||||
can be found in \cref{sec:mzn-grammar-expressions}. Nethercote et al.\ and
|
||||
Mariott et al.\ offer a detailed discussion of the expression language of
|
||||
\minizinc\ and its predecessor \zinc\ respectively
|
||||
\autocite*{nethercote-2007-minizinc,marriott-2008-zinc}.
|
||||
can be found in \cref{sec:mzn-grammar-expressions}.
|
||||
|
||||
\Glspl{global} are the basic building blocks in the \minizinc\ language. These
|
||||
expressions capture common (complex) relations between \variables{}.
|
||||
@ -340,7 +338,7 @@ expressions. You could, for example, force that the absolute value of
|
||||
\mzninline{a} is bigger than \mzninline{b} using the constraint
|
||||
|
||||
\begin{mzn}
|
||||
constraint if b >= 0 then a > b else b < a endif;
|
||||
constraint if a >= 0 then a > b else b < a endif;
|
||||
\end{mzn}
|
||||
|
||||
In \minizinc\ the result of a \gls{conditional} expression is, however, not
|
||||
@ -373,7 +371,7 @@ modellers to provide a custom index set.
|
||||
|
||||
Like the previous expressions, the selector \mzninline{i} can be both a
|
||||
\parameter{} or a \variable{}. If the expression is a \gls{variable}, then the
|
||||
expression is flattened as being an \mzninline{element} function. Otherwise, the
|
||||
expression is flattened to be an \mzninline{element} function. Otherwise, the
|
||||
flattening will replace the \gls{array} access expression by the element
|
||||
referenced by expression.
|
||||
|
||||
@ -394,11 +392,11 @@ parts:
|
||||
when the filtering condition succeeds.
|
||||
\end{description}
|
||||
|
||||
The following example composes an \gls{array} that contains the doubled even
|
||||
The following example composes an \gls{array} that contains the tripled even
|
||||
values of an \gls{array} \mzninline{x}.
|
||||
|
||||
\begin{mzn}
|
||||
[ xi * 2 | xi in x where x mod 2 == 0]
|
||||
[ xi * 3 | xi in x where x mod 2 == 0]
|
||||
\end{mzn}
|
||||
|
||||
The evaluated expression will be added to the new array. This means that the
|
||||
@ -418,32 +416,32 @@ resulting definition. There are three main purposes for \glspl{let}:
|
||||
\begin{enumerate}
|
||||
\item To name an intermediate expression, so it can be used multiple times or
|
||||
to simplify the expression. For example, the constraint
|
||||
|
||||
%
|
||||
\begin{mzn}
|
||||
constraint let { var int: tmp = x div 2; } in tmp mod 2 == 0 \/ tmp = 0;
|
||||
constraint let { var int: tmp = x div 2; } in tmp mod 2 == 0 \/ tmp = 1;
|
||||
\end{mzn}
|
||||
|
||||
constrains that half of \mzninline{x} is even or zero.
|
||||
%
|
||||
constrains that half of \mzninline{x} is even or one.
|
||||
|
||||
\item To introduce a scoped \variable{}. For example, the constraint
|
||||
|
||||
%
|
||||
\begin{mzn}
|
||||
let {var -2..2: slack;} in x + slack = y;
|
||||
constraint let {var -2..2: slack;} in x + slack = y;
|
||||
\end{mzn}
|
||||
|
||||
%
|
||||
constrains that \mzninline{x} and \mzninline{y} are at most two apart.
|
||||
|
||||
\item To constrain the resulting expression. For example, the following
|
||||
function
|
||||
|
||||
%
|
||||
\begin{mzn}
|
||||
function var int: int_times(var int: x, var int: y) =
|
||||
let {
|
||||
let {
|
||||
var int: z;
|
||||
constraint pred_int_times(x, y, z);
|
||||
} in z;
|
||||
\end{mzn}
|
||||
|
||||
%
|
||||
returns a new \variable{} \mzninline{z} that is constrained to be the
|
||||
multiplication of \mzninline{x} and \mzninline{y} by the relational
|
||||
multiplication constraint \mzninline{pred_int_times}.
|
||||
@ -486,14 +484,17 @@ corresponding constraint \mzninline{c(...)} holds.
|
||||
reified variables it can set to \mzninline{true}.
|
||||
\end{example}
|
||||
|
||||
We say that the same expression can be used in \emph{root context} as well as in
|
||||
a \emph{reified context}. In \minizinc{}, almost all expressions can be used in
|
||||
both contexts.
|
||||
When an expression occurs in a position where it can be globally enforced, we
|
||||
say it occurs in \emph{root context}. Contrarily, an expression that occurs in a
|
||||
\emph{non-root context} will be reified during the flattening process. In
|
||||
\minizinc{}, almost all expressions can be used in both contexts.
|
||||
|
||||
\subsection{Handling Undefined Expressions}%
|
||||
\label{subsec:back-mzn-partial}
|
||||
|
||||
Some expressions in the \cmls\ do not always have a well-defined result.
|
||||
Some expressions in the \cmls\ do not always have a well-defined result. Part of
|
||||
the semantics of a \cmls{} is the choice as to how to treat these partial
|
||||
functions.
|
||||
|
||||
\begin{example}\label{ex:back-undef}
|
||||
Consider, for example, the following ``complex constraint''
|
||||
@ -512,8 +513,7 @@ Some expressions in the \cmls\ do not always have a well-defined result.
|
||||
the constraint should be trivially true.
|
||||
\end{example}
|
||||
|
||||
Part of the semantics of a \cmls{} is the choice as to how to treat these
|
||||
partial functions. Examples of such expressions in \minizinc\ are:
|
||||
Other examples of \minizinc{} expressions that result in partial functions are:
|
||||
|
||||
\begin{itemize}
|
||||
\item Division (or modulus) when the divisor is zero:
|
||||
@ -522,12 +522,6 @@ partial functions. Examples of such expressions in \minizinc\ are:
|
||||
x div 0 = @??@
|
||||
\end{mzn}
|
||||
|
||||
\item Array access when the index is outside the given index set:
|
||||
|
||||
\begin{mzn}
|
||||
array1d(1..3, [1,2,3])[0] = @??@
|
||||
\end{mzn}
|
||||
|
||||
\item Finding the minimum or maximum or an empty set:
|
||||
|
||||
\begin{mzn}
|
||||
@ -595,8 +589,7 @@ For example, one might deal with a zero divisor using a disjunction:
|
||||
|
||||
In this case we expect the undefinedness of the division to be contained within
|
||||
the second part of the disjunction. This corresponds to ``relational''
|
||||
semantics. \jip{TODO:\@ This also corresponds to Kleene semantics, maybe I
|
||||
should use a different example}
|
||||
semantics.
|
||||
|
||||
Frisch and Stuckey also show that different \solvers{} often employ different
|
||||
semantics \autocite*{frisch-2009-undefinedness}. It is therefore important that,
|
||||
@ -642,7 +635,7 @@ targets and their input language.
|
||||
|
||||
When given a \gls{csp}, one might wonder what the best way is to find a solution
|
||||
to the problem. The simplest solution would be to apply ``brute force'': try
|
||||
every value in the \gls{domain} all \variables{}. It will not surprise the
|
||||
every value in the \gls{domain} of all \variables{}. It will not surprise the
|
||||
reader that this is an inefficient approach. Given, for example, the constraint
|
||||
|
||||
\begin{mzn}
|
||||
@ -650,22 +643,22 @@ reader that this is an inefficient approach. Given, for example, the constraint
|
||||
\end{mzn}
|
||||
|
||||
It is clear that when the value \mzninline{a} is known, then the value of
|
||||
\mzninline{b} can be deduced. \gls{cp} is the idea solving \glspl{csp} by
|
||||
\mzninline{b} can be deduced. \gls{cp} is the idea of solving \glspl{csp} by
|
||||
performing an intelligent search by inferring which values are still feasible
|
||||
for each \variable{} \autocite{rossi-2006-cp}.
|
||||
|
||||
To find a solution to a given \gls{csp}, a \gls{cp} \solver{} will perform a
|
||||
depth first search. At each node, the \solver{} will try and eliminate any
|
||||
depth first search. At each node, the \solver{} will try to eliminate any
|
||||
impossible value using a process called \gls{propagation}. For each
|
||||
\constraint{} the \solver{} has a chosen algorithm called a \gls{propagator}.
|
||||
Triggered by changes in the \glspl{domain} of its \variables{}, the
|
||||
\gls{propagator} will analyse and prune the any values that are proven to be
|
||||
\gls{propagator} will analyse and prune any values that are proven to be
|
||||
inconsistent.
|
||||
|
||||
In the best case scenario, \gls{propagation} will eliminate all impossible value
|
||||
and all \variables{} have been fixed to a single value. In this case we have
|
||||
arrived at a solution. Often, \gls{propagation} alone will not be enough to find
|
||||
a solution to the problem. Instead, when no more \glspl{propagator} are
|
||||
In the best case scenario, \gls{propagation} will eliminate all impossible
|
||||
values and all \variables{} have been fixed to a single value. In this case we
|
||||
have arrived at a solution. Often, \gls{propagation} alone will not be enough to
|
||||
find a solution to the problem. Instead, when no more \glspl{propagator} are
|
||||
triggered (we have reached a \gls{fixpoint}), the \solver{} has to make a search
|
||||
decision. It will fix a \variable{} to a value or add a new \constraint{}. This
|
||||
search decision is an assumption made by the \solver{} in the hope of finding a
|
||||
@ -673,12 +666,12 @@ solution. If no solution is found using the search decision, then it needs to
|
||||
try making the opposite decision: excluding the chosen value or adding the
|
||||
opposite constraint.
|
||||
|
||||
Note that the important difference between values \gls{propagation} and making
|
||||
search decisions is that value excluded by a \gls{propagator} are guaranteed to
|
||||
not occur in any solution, but values excluded by a search heuristic are merely
|
||||
removed locally and might still be part of a solution. A \gls{cp} \solver{} is
|
||||
only able to prove that the problem is unsatisfiable by exploring the full
|
||||
search space.
|
||||
Note that the important difference between values excluded by \gls{propagation}
|
||||
and making search decisions is that value excluded by a \gls{propagator} are
|
||||
guaranteed to not occur in any solution, but values excluded by a search
|
||||
heuristic are merely removed locally and might still be part of a solution. A
|
||||
\gls{cp} \solver{} is only able to prove that the problem is unsatisfiable by
|
||||
exploring the full search space.
|
||||
|
||||
\Gls{propagation} is not only used when starting the search, but also after
|
||||
making each search decision. This means that some \gls{propagation} depends on
|
||||
@ -718,17 +711,19 @@ constraints otherwise.
|
||||
|
||||
\begin{mzn}
|
||||
int: n;
|
||||
array [1..n] of var 1..n: q;
|
||||
set of int: ROW = 1..n;
|
||||
set of int: COL = 1..n;
|
||||
array [ROW] of var COL: q;
|
||||
|
||||
constraint all_different(q);
|
||||
constraint all_different([q[i] + i | i in 1..n]);
|
||||
constraint all_different([q[i] - i | i in 1..n]);
|
||||
constraint all_different([q[i] + i | i in ROW]);
|
||||
constraint all_different([q[i] - i | i in ROW]);
|
||||
\end{mzn}
|
||||
|
||||
Since we know that there can only be one queen per column, the decision in the
|
||||
model left to make is, for every queen, where in the column the piece is
|
||||
placed. The \constraints{} in the model the remaining rules of the problem: no
|
||||
two queen can be placed in the same row, no two queen can be place in the same
|
||||
Since we know that there can only be one queen per row, the decision in the
|
||||
model left to make is, for every queen, where in the row the piece is placed.
|
||||
The \constraints{} in the model the remaining rules of the problem: no two
|
||||
queen can be placed in the same row, no two queen can be place in the same
|
||||
upward diagonal, and no two queens can be place in the same downward diagonal.
|
||||
This model can be directly used in most \gls{cp} \solvers{}, since integer
|
||||
\variables{} and an \mzninline{all_different} \gls{propagator} are common.
|
||||
@ -753,8 +748,8 @@ propagating a constraint and the amount of search that is otherwise required.
|
||||
The golden standard for a \gls{propagator} is to be \gls{domain-con}, meaning
|
||||
that all values left in the \glspl{domain} of its \variables{} there is at least
|
||||
one possible variable assignment that satisfies the constraint. Designing an
|
||||
algorithm that reaches this level of consistency is, however, an easy task and
|
||||
might require high complexity. Instead, it can sometimes be better to use a
|
||||
algorithm that reaches this level of consistency is, however, not an easy task
|
||||
and might require high complexity. Instead, it can sometimes be better to use a
|
||||
propagator with a lower level of consistency. Although it might not eliminate
|
||||
all possible values of the domain, searching the values that are not eliminated
|
||||
might take less time than achieving \gls{domain-con}.
|
||||
@ -762,10 +757,11 @@ might take less time than achieving \gls{domain-con}.
|
||||
This is, for example, the case for integer linear constraints:
|
||||
\[ \sum_{i} c_{i} x_{i} = d\] where \(c_{i}\) and \(d\) are integer
|
||||
\parameters{} and \(x_{i}\) are integer \variable{}. For these constraints, no
|
||||
realistic \gls{domain-con} \gls{propagator} exists. Instead, \solvers{}
|
||||
generally use a \gls{bounds-con} \gls{propagator}, which guarantee only that the
|
||||
minimum and maximum values in the \glspl{domain} of the \variables{} are used in
|
||||
at least one possible assignment that satisfies the constraint.
|
||||
realistic \gls{domain-con} \gls{propagator} exists because the problem is
|
||||
\gls{np}-hard \autocite{choi-2006-fin-cons}. Instead, \solvers{} generally use a
|
||||
\gls{bounds-con} \gls{propagator}, which guarantee only that the minimum and
|
||||
maximum values in the \glspl{domain} of the \variables{} are used in at least
|
||||
one possible assignment that satisfies the constraint.
|
||||
|
||||
Thus far, we have only considered \glspl{csp}. \gls{cp} solving can, however,
|
||||
also be used to solve optimisation problems using a method called \gls{bnb}. The
|
||||
@ -782,8 +778,8 @@ better solutions than the current incumbent solution.
|
||||
|
||||
\gls{cp} solvers like Chuffed \autocite{chuffed-2021-chuffed}, Choco
|
||||
\autocite{prudhomme-2016-choco}, \gls{gecode} \autocite{gecode-2021-gecode}, and
|
||||
OR-Tools \autocite{perron-2021-ortools} have long been one of the leading method
|
||||
to solve \minizinc\ instances.
|
||||
OR-Tools \autocite{perron-2021-ortools} have long been one of the leading
|
||||
methods to solve \minizinc\ instances.
|
||||
|
||||
\subsection{Mathematical Programming}%
|
||||
\label{subsec:back-mip}
|
||||
@ -794,14 +790,14 @@ One of the oldest techniques to solve optimisation problems is the use of
|
||||
\gls{lp} \autocite{schrijver-1998-mip}. A linear program describes a problem
|
||||
using a set of linear equations over continuous variables. In general, a linear
|
||||
program can be expressed in the form:
|
||||
|
||||
%
|
||||
\begin{align*}
|
||||
\text{maximise} \hspace{2em} & \sum_{j=1}^{V} c_{j} x_{j} & \\
|
||||
\text{subject to} \hspace{2em} & l_{i} \leq \sum_{j=0}^{V} a_{ij} x_{j} \leq u_{i} & \forall_{i=1}^{C} \\
|
||||
& x_{i} \in \mathbb{R} & \forall_{i=1}^{V}
|
||||
\end{align*}
|
||||
|
||||
where \(V\) and \(C\) represent the number of variables and number of
|
||||
%
|
||||
\noindent{}where \(V\) and \(C\) represent the number of variables and number of
|
||||
constraints respectively. The vector \(c\) holds the coefficients of the
|
||||
objective function and the matrix \(a\) holds the coefficients for the
|
||||
constraints. The vectors \(l\) and \(u\) respectively contain the lower and
|
||||
@ -809,10 +805,13 @@ upper bounds of the constraints. Finally, the \variables{} of the linear program
|
||||
held in the \(x\) vector.
|
||||
|
||||
For problems that are in the form of a linear program, there are proven methods
|
||||
to find the optimal solution. The most prominent method, the simplex method, can
|
||||
find the optimal solution of a linear program in polynomial time.
|
||||
to find the optimal solution. In 1947 Dantzig introduced the simplex method,
|
||||
that can find the optimal solution of a linear program in worst-case exponential
|
||||
time. It was questioned whether the same problem could be solved in worst-case
|
||||
polynomial time, until Khachiyan proved this possible when he introduced the
|
||||
first of the so-called \emph{interior point} methods.
|
||||
|
||||
The same method provides the foundation for a harder problem. In \gls{lp} our
|
||||
These methods provide the foundation for a harder problem. In \gls{lp} our
|
||||
variables must be continuous. If we require that one or more take a discrete
|
||||
value (\(x_{i} \in \mathbb{N}\)), then the problem suddenly becomes much harder.
|
||||
The problem is referred to as \gls{mip} (or Integer Programming if \textbf{all}
|
||||
@ -845,15 +844,15 @@ Over the years \gls{lp} and \gls{mip} \solvers{} have developed immensely.
|
||||
often worthwhile to encode problem as a mixed integer program to find a
|
||||
solution.
|
||||
|
||||
\glspl{csp} can be often be encoded as mixed integer programs. This does,
|
||||
however, come with its challenges. Most \constraints{} in a \minizinc\ model are
|
||||
not linear equations. The translation of a single \constraint{} can introduce
|
||||
many linear \constraints{} and even new \variables{}. For example, when a
|
||||
\constraint{} reasons about the value that a variable will take, to encode it we
|
||||
will need to introduce \glspl{indicator-var}. The \glspl{indicator-var}
|
||||
\(y_{i}\) for a \variable{} \(x\) take the value 1 if \(x = i\) and 0 otherwise.
|
||||
\constraints{} reasoning about the value of \(x\) can then be rewritten as
|
||||
linear \constraints{} using the \variables{} \(y_{i}\).
|
||||
To solve a \gls{csp}, it can be encoded as a mixed integer program. This
|
||||
does, however, come with its challenges. Most \constraints{} in a \minizinc\
|
||||
model are not linear equations. The translation of a single \constraint{} can
|
||||
introduce many linear \constraints{} and even new \variables{}. For example,
|
||||
when a \constraint{} reasons about the value that a variable will take, to
|
||||
encode it we will need to introduce \glspl{indicator-var}. The
|
||||
\glspl{indicator-var} \(y_{i}\) for a \variable{} \(x\) take the value 1 if
|
||||
\(x = i\) and 0 otherwise. \constraints{} reasoning about the value of \(x\) can
|
||||
then be rewritten as linear \constraints{} using the \variables{} \(y_{i}\).
|
||||
|
||||
\begin{example}
|
||||
Let us again consider the N-Queens problem from \cref{ex:back-nqueens}. The
|
||||
@ -878,7 +877,7 @@ linear \constraints{} using the \variables{} \(y_{i}\).
|
||||
The \cref{line:back-mip-channel} is used to connect the \(q\) and \(y\)
|
||||
\variables{} and make sure that their values correspond.
|
||||
\Cref{line:back-mip-row} ensures that only one queen is placed in the same
|
||||
row. Finally, \cref{line:back-mip-diag1,line:back-mip-diag2} constrain all
|
||||
column. Finally, \cref{line:back-mip-diag1,line:back-mip-diag2} constrain all
|
||||
diagonals to contain only one queen.
|
||||
\end{example}
|
||||
|
||||
@ -887,26 +886,26 @@ linear \constraints{} using the \variables{} \(y_{i}\).
|
||||
\glsreset{sat}
|
||||
\glsreset{maxsat}
|
||||
|
||||
\gls{sat} was the first problem to be proven to be \gls{np-comp}
|
||||
\gls{sat} was the first problem to be proven to be \gls{np}-complete
|
||||
\autocite{cook-1971-sat}. The problem asks if there is an assignment for the
|
||||
variables of a given Boolean formula, such that the formula is satisfied. This
|
||||
problem can be seen as a restriction of the general \gls{csp} where \variables{}
|
||||
can only be of a Boolean type.
|
||||
|
||||
There is a field of research dedicated to solving \gls{sat} problems. In this
|
||||
field a \gls{sat} problem is generally standardised to be in \gls{cnf}. A
|
||||
\gls{cnf} is formulated in terms of Boolean literals. These are variables \(x\)
|
||||
or their negations \(\neg x\). These literals are then used in a conjunction of
|
||||
disjunctive clauses: a Boolean formula in the form
|
||||
\(\forall_{i \in P} \exists_{b \in C_{i}} b\). To solve the \gls{sat} problem,
|
||||
the \solver{} has to find an assignment for the \variables{} where at least one
|
||||
literal is true in every clause.
|
||||
There is a field of research dedicated to solving \gls{sat} problems
|
||||
\autocite{biere-2021-sat}. In this field a \gls{sat} problem is generally
|
||||
standardised to be in \gls{cnf}. A \gls{cnf} is formulated in terms of Boolean
|
||||
literals. These are variables \(x\) or their negations \(\neg x\). These
|
||||
literals are then used in a conjunction of disjunctive clauses: a Boolean
|
||||
formula in the form \(\forall_{i \in P} \exists_{b \in C_{i}} b\). To solve the
|
||||
\gls{sat} problem, the \solver{} has to find an assignment for the \variables{}
|
||||
where at least one literal is true in every clause.
|
||||
|
||||
Even though the problem is proven to be hard to solve, a lot of progress has
|
||||
been made towards solving even the biggest the most complex \gls{sat} problems
|
||||
\autocite{biere-2021-sat}. Modern day \gls{sat} solvers, like Kissat
|
||||
\autocite{biere-2021-kissat} and Clasp \autocite{gebser-2012-clasp}, can solve
|
||||
instances of the problem with thousands of \variables{} and clauses.
|
||||
been made towards solving even the biggest the most complex \gls{sat} problems.
|
||||
Modern day \gls{sat} solvers, like Kissat \autocite{biere-2021-kissat} and Clasp
|
||||
\autocite{gebser-2012-clasp}, can solve instances of the problem with thousands
|
||||
of \variables{} and clauses.
|
||||
|
||||
Many real world problems modelled in \cmls\ directly correspond to \gls{sat}.
|
||||
However, even problems that contain \variables{} with types other than Boolean
|
||||
@ -932,7 +931,7 @@ efficient way to solve the problem.
|
||||
The encoding of the problem uses a Boolean \variable{} for every position of
|
||||
the chess board. Each \variable{} represents if a queen will be located on
|
||||
this position or not. \Cref{line:back-sat-at-least} forces that a queen is
|
||||
placed on every column of the chess board.
|
||||
placed on every row of the chess board.
|
||||
\Cref{line:back-sat-row,line:back-sat-col} ensure that only one queens is
|
||||
place in each row and column respectively.
|
||||
\Cref{line:back-sat-diag1,line:back-sat-diag2} similarly constrain each
|
||||
@ -1147,8 +1146,8 @@ the solver. Take, for example, the following \gls{opl} search definition:
|
||||
|
||||
This search strategy will ensure that we first try and find a solution where the
|
||||
\variable{} \mzninline{x} takes a value smaller than \mzninline{y}, if it does
|
||||
not find a solution, then it will try finding a solution where the oposite is
|
||||
true. This search specification, like many other imaginable, cannot be enforce
|
||||
not find a solution, then it will try finding a solution where the opposite is
|
||||
true. This search specification, like many others imaginable, cannot be enforced
|
||||
using \minizinc\ \gls{search-heuristic} \glspl{annotation}.
|
||||
|
||||
To support \gls{opl}'s dedicated search language, the language is tightly
|
||||
@ -1175,7 +1174,7 @@ variable types that are contained in \minizinc{}, \gls{essence} also contains:
|
||||
Since sets, multi-sets, and functions can be defined on any other type, these
|
||||
types can be arbitrary nested and the modeller can define, for example, a
|
||||
\variable{} that is a sets of sets of integers. Partitions can be defined for
|
||||
finite types. These types in \gls{essence} are restricted to Boolean,
|
||||
finite types. The base types in \gls{essence} are restricted to Boolean,
|
||||
enumerated types, or a restricted set of integers.
|
||||
|
||||
\begin{example}
|
||||
@ -1246,15 +1245,17 @@ the targeted solver.
|
||||
\label{sec:back-term}
|
||||
\glsreset{trs}
|
||||
|
||||
At the heart of the flattening process lies a \gls{trs}. A \gls{trs}
|
||||
\autocite{baader-1998-term-rewriting} describes a computational model the full
|
||||
process can be described as the application of rules
|
||||
\(l \rightarrow r_{1}, \ldots r_{n}\), that replace a \gls{term} \(l\) with one
|
||||
or more \glspl{term} \(r_{1}, \ldots r_{n}\). A \gls{term} is an expression with
|
||||
nested sub-expressions consisting of \emph{function} and \emph{constant}
|
||||
symbols. An example of a term is \(F(0 + 1,F(1,0))\), where \(F\) and \(+\) are
|
||||
function symbols and \(0\) and \(1\) are constant symbols. In a term rewriting
|
||||
rule, a term can also contain a \emph{term variable} which captures a term
|
||||
At the heart of the flattening process, the process as described in
|
||||
\cref{sec:back-minizinc} that translates a \minizinc{} instance into solver
|
||||
level \flatzinc{}, lies a \gls{trs}. A \gls{trs} describes a computational model
|
||||
the full process can be described as the application of rules
|
||||
\(l \rightarrow r_{1}, \ldots, r_{n}\), that replace a \gls{term} \(l\) with one
|
||||
or more \glspl{term} \(r_{1}, \ldots, r_{n}\)
|
||||
\autocite{baader-1998-term-rewriting}. A \gls{term} is an expression with nested
|
||||
sub-expressions consisting of \emph{function} and \emph{constant} symbols. An
|
||||
example of a term is \(F(0 + 1,F(1,0))\), where \(F\) and \(+\) are function
|
||||
symbols and \(0\) and \(1\) are constant symbols. In a term rewriting rule, a
|
||||
term can also contain a \emph{term variable} which captures a term
|
||||
sub-expression.
|
||||
|
||||
\begin{example}
|
||||
@ -1323,9 +1324,10 @@ symbol might be replaced or equated with a constant symbol, but, different from
|
||||
\cmls{}, this is not a requirement. A variable can remain a name in the solution
|
||||
of a constraint logic program. This means that the solution of a constraint
|
||||
logic program can be a relationship between different variables. In cases where
|
||||
an instantiated solution is required, a special \mzninline{labeling} constraint
|
||||
can be used to force a variable to take a constant value. Similarly, there is a
|
||||
\mzninline{minimize} that can be used to find the optimal value for a variable.
|
||||
an instantiated solution is required, a special \mzninline{labeling}
|
||||
\constraint{} can be used to force a variable to take a constant value.
|
||||
Similarly, there is a \mzninline{minimize} \constraint{} that can be used to
|
||||
find the optimal value for a variable.
|
||||
|
||||
The evaluation of a constraint logic program rewrites the list of constraints,
|
||||
called the goal, in the order given by the programmer. The rewriting of the
|
||||
@ -1534,17 +1536,17 @@ happens in one of two ways:
|
||||
|
||||
\begin{itemize}
|
||||
|
||||
\item For Boolean expressions in a reified context, the new \variable{} is
|
||||
\item For Boolean expressions in a non-root context, the new \variable{} is
|
||||
inserted by the flattening process itself. To constrain this
|
||||
\variable{}, the flattener will then add a new reified constraint. This
|
||||
constraint contains a call a variation of the call that would have been
|
||||
generated for the expression in root context. The name of the function
|
||||
is appended with \mzninline{_reif} and an extra Boolean \variable{}
|
||||
argument is added to the call. The definition of this constraint should
|
||||
implement the reification of the original expression: setting the
|
||||
additional argument to \mzninline{true} if the constraint is satisfied,
|
||||
and \mzninline{false} otherwise. For example, the constraint in
|
||||
\minizinc{}
|
||||
\variable{}, the flattener will then add the \gls{reification} of the
|
||||
constraint. This constraint contains a call a variation of the call that
|
||||
would have been generated for the expression in root context. The name
|
||||
of the function is appended with \mzninline{_reif} and an extra Boolean
|
||||
\variable{} argument is added to the call. The definition of this
|
||||
constraint should implement the reification of the original expression:
|
||||
setting the additional argument to \mzninline{true} if the constraint is
|
||||
satisfied, and \mzninline{false} otherwise. For example, the constraint
|
||||
in \minizinc{}
|
||||
|
||||
\begin{mzn}
|
||||
constraint b \/ this_call(x, y);
|
||||
@ -1763,9 +1765,8 @@ they directly received the equivalent linear \constraint{}:
|
||||
constraint int_lin_le([1,2,-1], [x,y,z], 0)
|
||||
\end{mzn}
|
||||
|
||||
Since many solvers support linear constraints, it is often an
|
||||
additional burden to have intermediate values that have to be given a value in
|
||||
the solution.
|
||||
Since many solvers support linear constraints, it is often an additional burden
|
||||
to have intermediate values that have to be given a value in the solution.
|
||||
|
||||
This can be resolved using the \gls{aggregation} of constraints. When we
|
||||
aggregate constraints we collect multiple \minizinc\ expressions, that would
|
||||
@ -1840,22 +1841,24 @@ the \glspl{domain} of \variables{} used by other delayed \constraints{}.
|
||||
\label{subsec:back-fzn-optimisation}
|
||||
|
||||
After the compiler is done flattening the \minizinc\ instance, it enters the
|
||||
optimisation phase. This phase occurs at the same stage as the solver input
|
||||
language. Depending on the targeted \solver{}, the \minizinc\ flattener might
|
||||
still understand the meaning of certain constraints. In these cases,
|
||||
\gls{propagation} methods (as discussed in \cref{subsec:back-cp}) can be used to
|
||||
optimisation phase. This phase occurs at the level at which the targeted
|
||||
\solver{} operates. Depending on this \solver{}, the \minizinc\ flattener might
|
||||
still understand the meaning of certain \constraints{}. In these cases,
|
||||
\gls{propagation} methods, as discussed in \cref{subsec:back-cp}, can be used to
|
||||
eliminate values from variable \glspl{domain} and simplify \constraints{}.
|
||||
|
||||
In the current implementation the main focus of the flattener is to propagate
|
||||
Boolean constraint. The flattener try and reduce the number of Boolean variables
|
||||
and try and reduce the number of literals in clauses or logical and constraints.
|
||||
The additional propagation might fix the reification of a constraint. If this
|
||||
constraint is not yet rewritten, then the \solver{} will know to use a direct
|
||||
constraint instead of a reified version.
|
||||
Boolean \constraints{}. The flattener tries to reduce the number of Boolean
|
||||
\variables{} and tries to reduce the number of literals in clauses and
|
||||
conjunctions. The additional propagation might fix the result of the
|
||||
\gls{reification} of a constraint. If this constraint is not yet rewritten, then
|
||||
the \solver{} will know to use a direct constraint instead of a reified version.
|
||||
|
||||
Even more important than the Boolean constraints, are equality \constraints{}.
|
||||
The flattening is in the unique position to \gls{unify} \variables{} when they
|
||||
are found to be equal. Since they both have to take the same value, only a
|
||||
single \variable{} is required in the \flatzinc\ model to represent them both.
|
||||
Whenever any (recognisable) equality constraint is found during the optimisation
|
||||
phase, it is removed and the two \variables{} are unified.
|
||||
Even more important than the Boolean \constraints{}, are equality
|
||||
\constraints{}. The flattening is in the unique position to \gls{unify}
|
||||
\variables{} when they are found to be equal. Since they both have to take the
|
||||
same value, only a single \variable{} is required in the \flatzinc\ model to
|
||||
represent them both. Whenever any (recognisable) equality constraint is found
|
||||
during the optimisation phase, it is removed and the two \variables{} are
|
||||
unified. Once initialised, it is not always possible for \solvers{} to
|
||||
\gls{unify} \variables{} internally.
|
||||
|
Reference in New Issue
Block a user