cws/cw03.tex
changeset 213 f968188d4a9b
parent 212 4bda49ec24da
child 216 8c868feb917b
equal deleted inserted replaced
212:4bda49ec24da 213:f968188d4a9b
     1 \documentclass{article}
     1 \documentclass{article}
     2 \usepackage{chessboard}
     2 \usepackage{chessboard}
     3 \usepackage[LSBC4,T1]{fontenc}
     3 \usepackage[LSBC4,T1]{fontenc}
     4 \let\clipbox\relax
     4 \let\clipbox\relax
     5 \usepackage{../style}
     5 \usepackage{../style}
       
     6 \usepackage{../langs}
     6 \usepackage{disclaimer}
     7 \usepackage{disclaimer}
     7 
     8 
     8 \begin{document}
     9 \begin{document}
     9 
    10 
    10 \setchessboard{smallboard,
    11 \setchessboard{smallboard,
    14                hlabelformat=\arabic{ranklabel},
    15                hlabelformat=\arabic{ranklabel},
    15                vlabelformat=\arabic{filelabel}}
    16                vlabelformat=\arabic{filelabel}}
    16 
    17 
    17 \mbox{}\\[-18mm]\mbox{}
    18 \mbox{}\\[-18mm]\mbox{}
    18 
    19 
    19 \section*{Coursework 7 (Scala)}
    20 \section*{Coursework 8 (Scala)}
    20 
    21 
    21 This coursework is worth 10\%. It is about searching and
    22 This coursework is worth 10\%. It is about searching and
    22 backtracking. The first part is due on 29 November at 11pm; the
    23 backtracking. The first part is due on 29 November at 11pm; the
    23 second, more advanced part, is due on 20 December at 11pm. You are
    24 second, more advanced part, is due on 20 December at 11pm. You are
    24 asked to implement Scala programs that solve various versions of the
    25 asked to implement Scala programs that solve various versions of the
    25 \textit{Knight's Tour Problem} on a chessboard. Note the second, more
    26 \textit{Knight's Tour Problem} on a chessboard. Note the second, more
    26 advanced, part might include material you have not yet seen in the
    27 advanced, part might include material you have not yet seen in the
    27 first two lectures. \bigskip
    28 first three lectures. \bigskip
    28 
    29 
    29 \IMPORTANT{}
    30 \IMPORTANT{}
    30 Also note that the running time of each part will be restricted to a
    31 Also note that the running time of each part will be restricted to a
    31 maximum of 360 seconds on my laptop: If you calculate a result once,
    32 maximum of 30 seconds on my laptop: If you calculate a result once,
    32 try to avoid to calculate the result again. Feel free to copy any code
    33 try to avoid to calculate the result again. Feel free to copy any code
    33 you need from files \texttt{knight1.scala}, \texttt{knight2.scala} and
    34 you need from files \texttt{knight1.scala}, \texttt{knight2.scala} and
    34 \texttt{knight3.scala}.
    35 \texttt{knight3.scala}.
    35 
    36 
    36 \DISCLAIMER{}
    37 \DISCLAIMER{}
   136 
   137 
   137 If you cannot remember how a knight moves in chess, or never played
   138 If you cannot remember how a knight moves in chess, or never played
   138 chess, below are all potential moves indicated for two knights, one on
   139 chess, below are all potential moves indicated for two knights, one on
   139 field $(2, 2)$ (blue moves) and another on $(7, 7)$ (red moves):
   140 field $(2, 2)$ (blue moves) and another on $(7, 7)$ (red moves):
   140 
   141 
   141 
   142 {\chessboard[maxfield=g7,
   142 \chessboard[maxfield=g7,
       
   143             color=blue!50,
   143             color=blue!50,
   144             linewidth=0.2em,
   144             linewidth=0.2em,
   145             shortenstart=0.5ex,
   145             shortenstart=0.5ex,
   146             shortenend=0.5ex,
   146             shortenend=0.5ex,
   147             markstyle=cross,
   147             markstyle=cross,
   148             markfields={a4, c4, Z3, d3, Z1, d1, a0, c0},
   148             markfields={a4, c4, Z3, d3, Z1, d1, a0, c0},
   149             color=red!50,
   149             color=red!50,
   150             markfields={f5, e6},
   150             markfields={f5, e6},
   151             setpieces={Ng7, Nb2}]
   151             setpieces={Ng7, Nb2},
   152 
   152             boardfontsize=12pt,labelfontsize=9pt]}
   153 
   153 
   154 \noindent
   154 \subsection*{Reference Implementation}
   155 \textbf{Hints:} useful list functions: \texttt{.contains(..)} checks
   155 
       
   156 The Scala assignment comes with reference implementations in form of
       
   157 a \texttt{jar}-files. This allows you to run any test cases on your own
       
   158 computer. For example you can call Scala on the command line with the
       
   159 option \texttt{-cp knight1.jar} and then query any function from the
       
   160 template file. 
       
   161 
       
   162 \begin{lstlisting}[language={},numbers=none,basicstyle=\ttfamily\small]
       
   163 $ scala -cp knight1.jar
       
   164   
       
   165 scala> CW8a.enum_tours(5, List((0, 0))).length
       
   166 Time needed: 1.722 secs.
       
   167 res0: Int = 304
       
   168 
       
   169 scala> CW8a.print_board(8, CW8a.first_tour(8, List((0, 0))).get)
       
   170 Time needed: 15.411 secs.
       
   171 
       
   172  51  46  55  44  53   4  21  12 
       
   173  56  43  52   3  22  13  24   5 
       
   174  47  50  45  54  25  20  11  14 
       
   175  42  57   2  49  40  23   6  19 
       
   176  35  48  41  26  61  10  15  28 
       
   177  58   1  36  39  32  27  18   7 
       
   178  37  34  31  60   9  62  29  16 
       
   179   0  59  38  33  30  17   8  63 
       
   180 \end{lstlisting}%$
       
   181 
       
   182 
       
   183 \subsection*{Hints}
       
   184 
       
   185 \noindent
       
   186 \textbf{Part 1} useful list functions: \texttt{.contains(..)} checks
   156 whether an element is in a list, \texttt{.flatten} turns a list of
   187 whether an element is in a list, \texttt{.flatten} turns a list of
   157 lists into just a list, \texttt{\_::\_} puts an element on the head of
   188 lists into just a list, \texttt{\_::\_} puts an element on the head of
   158 the list, \texttt{.head} gives you the first element of a list (make
   189 the list, \texttt{.head} gives you the first element of a list (make
   159 sure the list is not \texttt{Nil}).
   190 sure the list is not \texttt{Nil}); a useful option function:
   160 
   191 \texttt{.isDefined} returns true, if an option is \texttt{Some(..)};
   161 \noindent
   192 anonymous functions can be constructed using \texttt{(x:Int) => ...},
   162 \textbf{Hints:} a useful list function: \texttt{.sortBy} sorts a list
   193 this functions takes an \texttt{Int} as an argument.\medskip
       
   194 
       
   195 
       
   196 \noindent
       
   197 \textbf{Part 2} a useful list function: \texttt{.sortBy} sorts a list
   163 according to a component given by the function; a function can be
   198 according to a component given by the function; a function can be
   164 tested to be tail recursive by annotation \texttt{@tailrec}, which is
   199 tested to be tail recursive by annotation \texttt{@tailrec}, which is
   165 made available by importing \texttt{scala.annotation.tailrec}.
   200 made available by importing \texttt{scala.annotation.tailrec}.
   166 
   201 
   167             
   202 
   168 \subsection*{Part 1 (7 Marks)}
   203 
       
   204 
       
   205 \subsection*{Part 1 (6 Marks)}
   169 
   206 
   170 You are asked to implement the knight's tour problem such that the
   207 You are asked to implement the knight's tour problem such that the
   171 dimension of the board can be changed.  Therefore most functions will
   208 dimension of the board can be changed.  Therefore most functions will
   172 take the dimension of the board as an argument.  The fun with this
   209 take the dimension of the board as an argument.  The fun with this
   173 problem is that even for small chessboard dimensions it has already an
   210 problem is that even for small chessboard dimensions it has already an
   176 with exhaustively exploring the complete search space for small
   213 with exhaustively exploring the complete search space for small
   177 chessboards.\medskip
   214 chessboards.\medskip
   178 
   215 
   179 \noindent
   216 \noindent
   180 Let us first fix the basic datastructures for the implementation.  The
   217 Let us first fix the basic datastructures for the implementation.  The
   181 board dimension is an integer (we will never go beyond board sizes of
   218 board dimension is an integer.
   182 $40 \times 40$).  A \emph{position} (or field) on the chessboard is
   219 A \emph{position} (or field) on the chessboard is
   183 a pair of integers, like $(0, 0)$. A \emph{path} is a list of
   220 a pair of integers, like $(0, 0)$. A \emph{path} is a list of
   184 positions. The first (or 0th move) in a path is the last element in
   221 positions. The first (or 0th move) in a path is the last element in
   185 this list; and the last move in the path is the first element. For
   222 this list; and the last move in the path is the first element. For
   186 example the path for the $5\times 5$ chessboard above is represented
   223 example the path for the $5\times 5$ chessboard above is represented
   187 by
   224 by
   242 there are 304 of tours. If you try out every field of a $5 \times
   279 there are 304 of tours. If you try out every field of a $5 \times
   243 5$-board as a starting field and add up all tours, you obtain
   280 5$-board as a starting field and add up all tours, you obtain
   244 1728. A $6\times 6$ board is already too large to be searched
   281 1728. A $6\times 6$ board is already too large to be searched
   245 exhaustively.\footnote{For your interest, the number of tours on
   282 exhaustively.\footnote{For your interest, the number of tours on
   246   $6\times 6$, $7\times 7$ and $8\times 8$ are 6637920, 165575218320,
   283   $6\times 6$, $7\times 7$ and $8\times 8$ are 6637920, 165575218320,
   247   19591828170979904, respectively.}\bigskip
   284   19591828170979904, respectively.}\smallskip
   248 
   285 
   249 
   286 
   250 
   287 
   251 \subsubsection*{Tasks (file knight2.scala)}
   288 \subsubsection*{Tasks (cont.)}
   252 
   289 
   253 \begin{itemize}
   290 \begin{itemize}
   254 \item[(4)] Implement a \texttt{first}-function. This function takes a list of
   291 \item[(4)] Implement a \texttt{first}-function. This function takes a list of
   255   positions and a function $f$ as arguments; $f$ is the name we give to
   292   positions and a function $f$ as arguments; $f$ is the name we give to
   256   this argument). The function $f$ takes a position as argument and
   293   this argument). The function $f$ takes a position as argument and
   269 
   306 
   270   \noindent That is, we want to find the first position where the
   307   \noindent That is, we want to find the first position where the
   271   result of $f$ is not \texttt{None}, if there is one. Note that
   308   result of $f$ is not \texttt{None}, if there is one. Note that
   272   `inside' \texttt{first}, you do not (need to) know anything about
   309   `inside' \texttt{first}, you do not (need to) know anything about
   273   the argument $f$ except its type, namely \texttt{Pos =>
   310   the argument $f$ except its type, namely \texttt{Pos =>
   274     Option[Path]}. There is one additional point however you should
   311     Option[Path]}. If you want to find out what the result of $f$ is
       
   312   on a particular argument, say $x$, you can just write $f(x)$. 
       
   313   There is one additional point however you should
   275   take into account when implementing \texttt{first}: you will need to
   314   take into account when implementing \texttt{first}: you will need to
   276   calculate what the result of $f(x)$ is; your code should do this
   315   calculate what the result of $f(x)$ is; your code should do this
   277   only \textbf{once} and for as \textbf{few} elements in the list as
   316   only \textbf{once} and for as \textbf{few} elements in the list as
   278   possible! Do not calculate $f(x)$ for all elements and then see which 
   317   possible! Do not calculate $f(x)$ for all elements and then see which 
   279   is the first \texttt{Some}.\\\mbox{}\hfill[1 Mark]
   318   is the first \texttt{Some}.\\\mbox{}\hfill[1 Mark]
   280   
   319   
   281 \item[(5)] Implement a \texttt{first\_tour} function that uses the
   320 \item[(5)] Implement a \texttt{first\_tour} function that uses the
   282   \texttt{first}-function from (2a), and searches recursively for a tour.
   321   \texttt{first}-function from (4), and searches recursively for single tour.
   283   As there might not be such a tour at all, the \texttt{first\_tour} function
   322   As there might not be such a tour at all, the \texttt{first\_tour} function
   284   needs to return a value of type
   323   needs to return a value of type
   285   \texttt{Option[Path]}.\\\mbox{}\hfill[1 Mark]
   324   \texttt{Option[Path]}.\\\mbox{}\hfill[1 Mark]
   286 \end{itemize}
   325 \end{itemize}
   287 
   326 
   288 \noindent
   327 \noindent
   289 \textbf{Testing:} The \texttt{first\_tour} function will be called with board
   328 \textbf{Testing:} The \texttt{first\_tour} function will be called with board
   290 sizes of up to $8 \times 8$.
   329 sizes of up to $8 \times 8$.
   291 \bigskip
   330 \bigskip
   292 
   331 
   293 \noindent
       
   294 \textbf{Hints:} a useful list function: \texttt{.filter(..)} filters a
       
   295 list according to a boolean function; a useful option function:
       
   296 \texttt{.isDefined} returns true, if an option is \texttt{Some(..)};
       
   297 anonymous functions can be constructed using \texttt{(x:Int) => ...},
       
   298 this functions takes an \texttt{Int} as an argument.
       
   299 
   332 
   300 
   333 
   301 %%\newpage
   334 %%\newpage
   302 \subsection*{Part 2 (3 Marks)}
   335 \subsection*{Advanced Part 2 (4 Marks)}
   303 
   336 
   304 As you should have seen in Part 1, a naive search for tours beyond
   337 As you should have seen in Part 1, a naive search for tours beyond
   305 $8 \times 8$ boards and also searching for closed tours even on small
   338 $8 \times 8$ boards and also searching for closed tours even on small
   306 boards takes too much time. There is a heuristic, called \emph{Warnsdorf's
   339 boards takes too much time. There is a heuristic, called \emph{Warnsdorf's
   307 Rule} that can speed up finding a tour. This heuristic states that a
   340 Rule} that can speed up finding a tour. This heuristic states that a
   331 \noindent
   364 \noindent
   332 Whenever there are ties, the corresponding onward moves can be in any
   365 Whenever there are ties, the corresponding onward moves can be in any
   333 order.  When calculating the number of onward moves for each field, we
   366 order.  When calculating the number of onward moves for each field, we
   334 do not count moves that revisit any field already visited.
   367 do not count moves that revisit any field already visited.
   335 
   368 
   336 \subsubsection*{Tasks (file knight3.scala)}
   369 \subsubsection*{Tasks (file knight2.scala)}
   337 
   370 
   338 \begin{itemize}
   371 \begin{itemize}
   339 \item[(6)] Write a function \texttt{ordered\_moves} that calculates a list of
   372 \item[(6)] Write a function \texttt{ordered\_moves} that calculates a list of
   340   onward moves like in (2) but orders them according to the
   373   onward moves like in (2) but orders them according to the
   341   Warnsdorf’s Rule. That means moves with the fewest legal onward moves
   374   Warnsdorf’s Rule. That means moves with the fewest legal onward moves
   342   should come first (in order to be tried out first). \hfill[1 Mark]
   375   should come first (in order to be tried out first). \hfill[1 Mark]
   343   
   376   
   344 \item[(7)] Implement a \texttt{first\_closed-tour\_heuristic}
   377 \item[(7)] Implement a \texttt{first\_closed\_tour\_heuristic}
   345   function that searches for a
   378   function that searches for a single
   346   \textbf{closed} tour on a $6\times 6$ board. It should use the
   379   \textbf{closed} tour on a $6\times 6$ board. It should try out
   347   \texttt{first}-function from (4) and tries out onward moves according to
   380   onward moves according to
   348   the \texttt{ordered\_moves} function from (3a). It is more likely to find
   381   the \texttt{ordered\_moves} function from (6). It is more likely to find
   349   a solution when started in the middle of the board (that is
   382   a solution when started in the middle of the board (that is
   350   position $(dimension / 2, dimension / 2)$). \hfill[1 Mark]
   383   position $(dimension / 2, dimension / 2)$). \hfill[1 Mark]
   351 
   384 
   352 \item[(8)] Implement a \texttt{first\_tour\_heuristic} function
   385 \item[(8)] Implement a \texttt{first\_tour\_heuristic} function
   353   for boards up to
   386   for boards up to
   354   $40\times 40$.  It is the same function as in (7) but searches for
   387   $30\times 30$.  It is the same function as in (7) but searches for
   355   tours (not just closed tours). You have to be careful to write a
   388   tours (not just closed tours). It might be called with any field on the
   356   tail-recursive function of the \texttt{first\_tour\_heuristic} function
   389   board as start.\\
   357   otherwise you will get problems with stack-overflows.\\
   390   %You have to be careful to write a
       
   391   %tail-recursive function of the \texttt{first\_tour\_heuristic} function
       
   392   %otherwise you will get problems with stack-overflows.\\
       
   393   \mbox{}\hfill[1 Mark]
       
   394 \end{itemize}    
       
   395 
       
   396 \subsubsection*{Task (file knight3.scala)}
       
   397 \begin{itemize}
       
   398 \item[(9)] Implement a function \texttt{tour\_on\_mega\_board} which is
       
   399   the same function as (7), \textbf{but} can deal with boards up to
       
   400   $70\times 70$ \textbf{within 30 seconds}. This will be tested
       
   401   by starting from field $(0, 0)$. You have to be careful to
       
   402   write a tail-recursive function otherwise you will get problems
       
   403   with stack-overflows. Please observe the requirements about
       
   404   the submissions: no tricks involving \textbf{.par}.\medskip
       
   405 
       
   406   The timelimit of 30 secs is with respect to the laptop on which the
       
   407   marking will happen. You can estimate how well your
       
   408   implementation performs by running \texttt{knight3.jar} on your
       
   409   computer. For example:
       
   410   
       
   411   \begin{lstlisting}[language={},numbers=none,basicstyle=\ttfamily\small]
       
   412 $ scala -cp knight3.jar
       
   413   
       
   414 scala> CW8c.tour_on_mega_board(70, List((0, 0)))
       
   415 Time needed: 9.484 secs.
       
   416 ...<<long_list>>...
       
   417 \end{lstlisting}%$
       
   418 
   358   \mbox{}\hfill[1 Mark]
   419   \mbox{}\hfill[1 Mark]
   359 \end{itemize}  
   420 \end{itemize}  
   360 \bigskip
   421 \bigskip
   361 
   422 
   362 
   423