diff --git a/assets/bibliography/references.bib b/assets/bibliography/references.bib index 66c9d37..3bb1a8c 100644 --- a/assets/bibliography/references.bib +++ b/assets/bibliography/references.bib @@ -1,31 +1,36 @@ - -@book{marriott_programming_1998, - location = {Cambridge, Mass}, - title = {Programming with constraints: an introduction}, - isbn = {978-0-262-13341-8}, - shorttitle = {Programming with constraints}, - pagetotal = {467}, - publisher = {{MIT} Press}, - author = {Marriott, Kim and Stuckey, Peter J.}, - date = {1998}, - keywords = {Constraint programming (Computer science), Logic programming}, +@article{freuder-1997-holygrail, + author = {Eugene C. Freuder}, + title = {In Pursuit of the Holy Grail}, + journal = {Constraints An Int. J.}, + volume = 2, + number = 1, + pages = {57--61}, + year = 1997, + url = {https://doi.org/10.1023/A:1009749006768}, + doi = {10.1023/A:1009749006768}, + timestamp = {Fri, 13 Mar 2020 10:58:24 +0100}, + biburl = {https://dblp.org/rec/journals/constraints/Freuder97.bib}, + bibsource = {dblp computer science bibliography, https://dblp.org} } -@incollection{hooker_solver-independent_2018, - location = {Cham}, - title = {Solver-Independent Large Neighbourhood Search}, - volume = {11008}, - rights = {All rights reserved}, - isbn = {978-3-319-98333-2 978-3-319-98334-9}, - url = {http://link.springer.com/10.1007/978-3-319-98334-9_6}, - pages = {81--98}, - booktitle = {Principles and Practice of Constraint Programming}, - publisher = {Springer International Publishing}, - author = {Dekker, Jip J. and de la Banda, Maria Garcia and Schutt, Andreas and Stuckey, Peter J. and Tack, Guido}, - editor = {Hooker, John}, - urldate = {2020-12-22}, - date = {2018}, - langid = {english}, - doi = {10.1007/978-3-319-98334-9_6}, - note = {Series Title: Lecture Notes in Computer Science}, -} \ No newline at end of file +@book{marriott-1998-clp, + location = {Cambridge, Mass}, + title = {Programming with constraints: an introduction}, + isbn = {978-0-262-13341-8}, + shorttitle = {Programming with constraints}, + pagetotal = 467, + publisher = {{MIT} Press}, + author = {Marriott, Kim and Stuckey, Peter J.}, + date = 1998, + keywords = {Constraint programming (Computer science), Logic + programming}, +} + +@book{silvano-1990-knapsack, + author = {Martello, Silvano and Toth, Paolo}, + title = {Knapsack Problems: Algorithms and Computer Implementations}, + year = 1990, + isbn = 0471924202, + publisher = {John Wiley \& Sons, Inc.}, + address = {USA} +} diff --git a/assets/glossary.tex b/assets/glossary.tex index 373856e..7ad824e 100644 --- a/assets/glossary.tex +++ b/assets/glossary.tex @@ -8,3 +8,25 @@ % make use of the services and resources provided by another particular software % program that implements that API}, % } + +\newglossaryentry{constraint}{ + name={constraint}, + description={TODO}, +} +\newglossaryentry{decision-variable}{ + name={decision variable}, + description={TODO}, +} +\newglossaryentry{minizinc}{ + name={MiniZinc}, + description={TODO}, +} +\newcommand{\minizinc}{\gls{minizinc}} +\newglossaryentry{solver}{ + name={solver}, + description={TODO}, +} +\newglossaryentry{problem-parameter}{ + name={problem parameter}, + description={TODO}, +} diff --git a/assets/mzn/2_knapsack.mzn b/assets/mzn/2_knapsack.mzn new file mode 100644 index 0000000..01f4abb --- /dev/null +++ b/assets/mzn/2_knapsack.mzn @@ -0,0 +1,15 @@ +% Problem parameters +enum TOYS = {football, tennisball, stuffed_lama, stuffed_elephant}; +array[TOYS] of int: toy_joy = [63, 12, 50, 100]; +array[TOYS] of int: toy_space = [32, 8, 16, 40]; +int: space_left = 64; + +% Decision variables +var set of TOYS: selection; +var int: total_joy = sum(toy in selection)(toy_joy[toy]); + +% Constraints +constraint sum(toy in selection)(toy_space[toy]) < space_left; + +% Goal +solve maximize total_joy; diff --git a/assets/mzn/2_knapsack.mzntex b/assets/mzn/2_knapsack.mzntex new file mode 100644 index 0000000..3be9448 --- /dev/null +++ b/assets/mzn/2_knapsack.mzntex @@ -0,0 +1,17 @@ +\begin{Verbatim}[commandchars=\\\{\},numbers=left,firstnumber=1,stepnumber=1,codes={\catcode`\$=3\catcode`\^=7\catcode`\_=8}] +\PY{c}{\PYZpc{} Problem parameters} +\PY{k+kt}{enum}\PY{l+s}{ }\PY{n+nv}{TOYS}\PY{l+s}{ }\PY{o}{=}\PY{l+s}{ }\PY{p}{\PYZob{}}\PY{n+nv}{football}\PY{p}{,}\PY{l+s}{ }\PY{n+nv}{tennisball}\PY{p}{,}\PY{l+s}{ }\PY{n+nv}{stuffed\PYZus{}lama}\PY{p}{,}\PY{l+s}{ }\PY{n+nv}{stuffed\PYZus{}elephant}\PY{g+gr}{\PYZcb{}}\PY{p}{;} +\PY{k+kt}{array}\PY{p}{[}\PY{n+nv}{TOYS}\PY{g+gr}{]}\PY{l+s}{ }\PY{k+kt}{of}\PY{l+s}{ }\PY{k+kt}{int}\PY{p}{:}\PY{l+s}{ }\PY{n+nv}{toy\PYZus{}joy}\PY{l+s}{ }\PY{o}{=}\PY{l+s}{ }\PY{p}{[}\PY{l+m}{63}\PY{p}{,}\PY{l+s}{ }\PY{l+m}{12}\PY{p}{,}\PY{l+s}{ }\PY{l+m}{50}\PY{p}{,}\PY{l+s}{ }\PY{l+m}{100}\PY{g+gr}{]}\PY{p}{;} +\PY{k+kt}{array}\PY{p}{[}\PY{n+nv}{TOYS}\PY{g+gr}{]}\PY{l+s}{ }\PY{k+kt}{of}\PY{l+s}{ }\PY{k+kt}{int}\PY{p}{:}\PY{l+s}{ }\PY{n+nv}{toy\PYZus{}space}\PY{l+s}{ }\PY{o}{=}\PY{l+s}{ }\PY{p}{[}\PY{l+m}{32}\PY{p}{,}\PY{l+s}{ }\PY{l+m}{8}\PY{p}{,}\PY{l+s}{ }\PY{l+m}{16}\PY{p}{,}\PY{l+s}{ }\PY{l+m}{40}\PY{g+gr}{]}\PY{p}{;} +\PY{k+kt}{int}\PY{p}{:}\PY{l+s}{ }\PY{n+nv}{space\PYZus{}left}\PY{l+s}{ }\PY{o}{=}\PY{l+s}{ }\PY{l+m}{64}\PY{p}{;} + +\PY{c}{\PYZpc{} Decision variables} +\PY{k+kt}{var}\PY{l+s}{ }\PY{k+kt}{set}\PY{l+s}{ }\PY{k+kt}{of}\PY{l+s}{ }\PY{n+nv}{TOYS}\PY{p}{:}\PY{l+s}{ }\PY{n+nv}{selection}\PY{p}{;} +\PY{k+kt}{var}\PY{l+s}{ }\PY{k+kt}{int}\PY{p}{:}\PY{l+s}{ }\PY{n+nv}{total\PYZus{}joy}\PY{l+s}{ }\PY{o}{=}\PY{l+s}{ }\PY{n+nb}{sum}\PY{p}{(}\PY{n+nv}{toy}\PY{l+s}{ }\PY{o}{in}\PY{l+s}{ }\PY{n+nv}{selection}\PY{g+gr}{)}\PY{p}{(}\PY{n+nv}{toy\PYZus{}joy}\PY{p}{[}\PY{n+nv}{toy}\PY{g+gr}{]}\PY{g+gr}{)}\PY{p}{;} + +\PY{c}{\PYZpc{} Constraints} +\PY{k}{constraint}\PY{l+s}{ }\PY{n+nb}{sum}\PY{p}{(}\PY{n+nv}{toy}\PY{l+s}{ }\PY{o}{in}\PY{l+s}{ }\PY{n+nv}{selection}\PY{g+gr}{)}\PY{p}{(}\PY{n+nv}{toy\PYZus{}space}\PY{p}{[}\PY{n+nv}{toy}\PY{g+gr}{]}\PY{g+gr}{)}\PY{l+s}{ }\PY{o}{\PYZlt{}}\PY{l+s}{ }\PY{n+nv}{space\PYZus{}left}\PY{p}{;} + +\PY{c}{\PYZpc{} Goal} +\PY{k}{solve}\PY{l+s}{ }\PY{k}{maximize}\PY{l+s}{ }\PY{n+nv}{total\PYZus{}joy}\PY{p}{;} +\end{Verbatim} diff --git a/assets/packages.tex b/assets/packages.tex index c354ce0..30c6ae4 100644 --- a/assets/packages.tex +++ b/assets/packages.tex @@ -44,12 +44,34 @@ Scale=1.4 \usepackage[ style=apa, ]{biblatex} +\usepackage{cleveref} % Glossary / Acronyms -\usepackage[acronym]{glossaries} +\usepackage[acronym,toc]{glossaries} +\defglsentryfmt[main]{\ifglsused{\glslabel}{\glsgenentryfmt}{\textit{\glsgenentryfmt}}} \makeglossaries{} % Code formatting \usepackage{fancyvrb} \usepackage{color} \input{assets/pygments_header.tex} +\DeclareNewTOC[ +type=program, +float, +name=Program, +counterwithin=chapter, +atbegin={% +\scriptsize +} +]{program} +\crefname{program}{program}{programs} +\DeclareNewTOC[ +type=model, +float, +name=Model, +counterwithin=chapter, +atbegin={% +\scriptsize +} +]{model} +\crefname{model}{model}{models} diff --git a/assets/py/2_dyn_knapsack.py b/assets/py/2_dyn_knapsack.py new file mode 100644 index 0000000..fb78bc7 --- /dev/null +++ b/assets/py/2_dyn_knapsack.py @@ -0,0 +1,28 @@ +toys_joy = [63, 12, 50, 100] +toys_space = [32, 8, 16, 40] +space_left = 64 + +num_toys = len(toys_joy) +# Initialise an empty table +table = [ + [0 for x in range(space_left + 1)] + for x in range(num_toys + 1) +] +for i in range(num_toys + 1): + for j in range(space_left + 1): + # If we are out of space or toys we cannot choose a toy + if i == 0 or j == 0: + table[i][j] = 0 + # If there is space for the toy, then compare the joy of + # picking this toy over picking the next toy with more + # space left + elif toys_space[i - 1] <= j: + table[i][j] = max( + toys_joy[i - 1] + table[i - 1][j - wt[i - 1]], + table[i - 1][j], + ) + # Otherwise, consider the next toy + else: + table[i][j] = table[i - 1][j] + +optimal_joy = table[num_toys][space_left] diff --git a/assets/py/2_dyn_knapsack.pytex b/assets/py/2_dyn_knapsack.pytex new file mode 100644 index 0000000..d106337 --- /dev/null +++ b/assets/py/2_dyn_knapsack.pytex @@ -0,0 +1,30 @@ +\begin{Verbatim}[commandchars=\\\{\},numbers=left,firstnumber=1,stepnumber=1,codes={\catcode`\$=3\catcode`\^=7\catcode`\_=8}] +\PY{n}{toys\PYZus{}joy} \PY{o}{=} \PY{p}{[}\PY{l+m+mi}{63}\PY{p}{,} \PY{l+m+mi}{12}\PY{p}{,} \PY{l+m+mi}{50}\PY{p}{,} \PY{l+m+mi}{100}\PY{p}{]} +\PY{n}{toys\PYZus{}space} \PY{o}{=} \PY{p}{[}\PY{l+m+mi}{32}\PY{p}{,} \PY{l+m+mi}{8}\PY{p}{,} \PY{l+m+mi}{16}\PY{p}{,} \PY{l+m+mi}{40}\PY{p}{]} +\PY{n}{space\PYZus{}left} \PY{o}{=} \PY{l+m+mi}{64} + +\PY{n}{num\PYZus{}toys} \PY{o}{=} \PY{n+nb}{len}\PY{p}{(}\PY{n}{toys\PYZus{}joy}\PY{p}{)} +\PY{c+c1}{\PYZsh{} Initialise an empty table} +\PY{n}{table} \PY{o}{=} \PY{p}{[} + \PY{p}{[}\PY{l+m+mi}{0} \PY{k}{for} \PY{n}{x} \PY{o+ow}{in} \PY{n+nb}{range}\PY{p}{(}\PY{n}{space\PYZus{}left} \PY{o}{+} \PY{l+m+mi}{1}\PY{p}{)}\PY{p}{]} + \PY{k}{for} \PY{n}{x} \PY{o+ow}{in} \PY{n+nb}{range}\PY{p}{(}\PY{n}{num\PYZus{}toys} \PY{o}{+} \PY{l+m+mi}{1}\PY{p}{)} +\PY{p}{]} +\PY{k}{for} \PY{n}{i} \PY{o+ow}{in} \PY{n+nb}{range}\PY{p}{(}\PY{n}{num\PYZus{}toys} \PY{o}{+} \PY{l+m+mi}{1}\PY{p}{)}\PY{p}{:} + \PY{k}{for} \PY{n}{j} \PY{o+ow}{in} \PY{n+nb}{range}\PY{p}{(}\PY{n}{space\PYZus{}left} \PY{o}{+} \PY{l+m+mi}{1}\PY{p}{)}\PY{p}{:} + \PY{c+c1}{\PYZsh{} If we are out of space or toys we cannot choose a toy} + \PY{k}{if} \PY{n}{i} \PY{o}{==} \PY{l+m+mi}{0} \PY{o+ow}{or} \PY{n}{j} \PY{o}{==} \PY{l+m+mi}{0}\PY{p}{:} + \PY{n}{table}\PY{p}{[}\PY{n}{i}\PY{p}{]}\PY{p}{[}\PY{n}{j}\PY{p}{]} \PY{o}{=} \PY{l+m+mi}{0} + \PY{c+c1}{\PYZsh{} If there is space for the toy, then compare the joy of} + \PY{c+c1}{\PYZsh{} picking this toy over picking the next toy with more} + \PY{c+c1}{\PYZsh{} space left} + \PY{k}{elif} \PY{n}{toys\PYZus{}space}\PY{p}{[}\PY{n}{i} \PY{o}{\PYZhy{}} \PY{l+m+mi}{1}\PY{p}{]} \PY{o}{\PYZlt{}}\PY{o}{=} \PY{n}{j}\PY{p}{:} + \PY{n}{table}\PY{p}{[}\PY{n}{i}\PY{p}{]}\PY{p}{[}\PY{n}{j}\PY{p}{]} \PY{o}{=} \PY{n+nb}{max}\PY{p}{(} + \PY{n}{toys\PYZus{}joy}\PY{p}{[}\PY{n}{i} \PY{o}{\PYZhy{}} \PY{l+m+mi}{1}\PY{p}{]} \PY{o}{+} \PY{n}{table}\PY{p}{[}\PY{n}{i} \PY{o}{\PYZhy{}} \PY{l+m+mi}{1}\PY{p}{]}\PY{p}{[}\PY{n}{j} \PY{o}{\PYZhy{}} \PY{n}{wt}\PY{p}{[}\PY{n}{i} \PY{o}{\PYZhy{}} \PY{l+m+mi}{1}\PY{p}{]}\PY{p}{]}\PY{p}{,} + \PY{n}{table}\PY{p}{[}\PY{n}{i} \PY{o}{\PYZhy{}} \PY{l+m+mi}{1}\PY{p}{]}\PY{p}{[}\PY{n}{j}\PY{p}{]}\PY{p}{,} + \PY{p}{)} + \PY{c+c1}{\PYZsh{} Otherwise, consider the next toy} + \PY{k}{else}\PY{p}{:} + \PY{n}{table}\PY{p}{[}\PY{n}{i}\PY{p}{]}\PY{p}{[}\PY{n}{j}\PY{p}{]} \PY{o}{=} \PY{n}{table}\PY{p}{[}\PY{n}{i} \PY{o}{\PYZhy{}} \PY{l+m+mi}{1}\PY{p}{]}\PY{p}{[}\PY{n}{j}\PY{p}{]} + +\PY{n}{optimal\PYZus{}joy} \PY{o}{=} \PY{n}{table}\PY{p}{[}\PY{n}{num\PYZus{}toys}\PY{p}{]}\PY{p}{[}\PY{n}{space\PYZus{}left}\PY{p}{]} +\end{Verbatim} diff --git a/chapters/2_background.tex b/chapters/2_background.tex index a7a113a..0292507 100644 --- a/chapters/2_background.tex +++ b/chapters/2_background.tex @@ -1,3 +1,69 @@ %************************************************ \chapter{Modelling with Constraints}\label{ch:background} %************************************************ + +A goal shared between all programming languages is to provide a certain level of +abstraction: an assembly language allows you to abstract from the binary +instructions and memory positions; Low-level imperial languages, like FORTRAN, +were the first to allow you to abstract from the processor architecture of the +target machine; and nowadays writing a program requires little knowledge of the +actual workings of the hardware. Freuder states that the ``Holy Grail'' of +programming languages would be where the user merely states the problem, and the +computer solves it and that constraint modelling is one of the biggest steps +towards this goal to this day \autocite*{freuder-1997-holygrail}. Different +from imperative (and even other declarative) languages, in a constraint +modelling language the modeller does not describe how to solve the problem, but +rather provides the problem requirements. You could say that a constraint model +actually describes the solution to the problem. + +For example, let us consider the following scenario: Packing for a weekend trip, +I have to decide which toys to bring for my dog, Audrey. We only have a small +amount of space left in the car, so we cannot bring all the toys. Since Audrey +gets enjoys playing with some toys more than others, we can now try and pick the +toys that bring Audrey the most amount of joy, but still fit in the car. + +\begin{program}[ht] + \input{assets/py/2_dyn_knapsack.pytex} + \caption{\label{prog:dyn-knapsack} A Python program that solves a 0-1 knapsack + problem using dynamic programming} +\end{program} + +A well educated reader in optimisation problems might immediately recognise that +this is a variation on the widely known \textit{knapsack problem}, more +specifically a \textit{0-1 knapsack problem} +\autocite[13--67]{silvano-1990-knapsack}. A commonly used solution to this +problem is based on dynamic programming. An implementation of this approach is +shown in \cref{prog:dyn-knapsack}. In a naive recursive approach we would try +all different combinations of toys to find the combination that will give the +most joy, but using a dynamic programming approach this exponential behaviour +(on the number of toys) can be avoided. + +\begin{model}[ht] + \input{assets/mzn/2_knapsack.mzntex} + \caption{\label{model:knapsack} A \minizinc\ model describing a 0-1 knapsack + problem} +\end{model} + +A constraint model offers a different view of the problem. Instead of specifying +the manner in which we can find the solution, we give a concise description of +the problem in terms of what we already know, the \glspl{problem-parameter}, +what we wish to know, the \glspl{decision-variable}, and the relationships that +should exists between them, the \glspl{constraint}. \Cref{model:knapsack} shows +a \minizinc\ model of the knapsack problem, where the different elements of the +constraint model are separated. Although a constraint model does not contain any +instructions to find a suitable solutions, these models can generally be given +to a dedicated solving program, or \gls{solver} for short, that can find a +solution that fits the requirements of the model. + + +\section{Constraint Modelling Basics} +\label{sec:2-constraint-modelling-basics} + +\section{Solving Techniques} +\label{sec:2-solving-techniques} + +\section{A Comparison of Constraint Modelling Languages} +\label{sec:2-different-languages} + +\section{What Makes a ``Good'' Model?} +\label{sec:2-model-quality}