changeset 166 | 780c40aaad27 |
parent 163 | 84917f2e16cd |
child 202 | f7bcb27d1940 |
165:1347bbd86c52 | 166:780c40aaad27 |
---|---|
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{disclaimer} |
|
6 |
7 |
7 \begin{document} |
8 \begin{document} |
8 |
9 |
9 \setchessboard{smallboard, |
10 \setchessboard{smallboard, |
10 zero, |
11 zero, |
23 asked to implement Scala programs that solve various versions of the |
24 asked to implement Scala programs that solve various versions of the |
24 \textit{Knight's Tour Problem} on a chessboard. Note the second part |
25 \textit{Knight's Tour Problem} on a chessboard. Note the second part |
25 might include material you have not yet seen in the first two |
26 might include material you have not yet seen in the first two |
26 lectures. \bigskip |
27 lectures. \bigskip |
27 |
28 |
28 \noindent |
29 \IMPORTANT{} |
29 \textbf{Important:} |
|
30 |
|
31 \begin{itemize} |
|
32 \item Make sure the files you submit can be processed by just calling\\ |
|
33 \mbox{\texttt{scala <<filename.scala>>}} on the commandline. |
|
34 |
|
35 \item Do not use any mutable data structures in your |
|
36 submissions! They are not needed. This means you cannot create new |
|
37 \texttt{Array}s or \texttt{ListBuffer}s, for example. |
|
38 |
|
39 \item Do not use \texttt{return} in your code! It has a different |
|
40 meaning in Scala, than in Java. |
|
41 |
|
42 \item Do not use \texttt{var}! This declares a mutable variable. Only |
|
43 use \texttt{val}! |
|
44 |
|
45 \item Do not use any parallel collections! No \texttt{.par} therefore! |
|
46 Our testing and marking infrastructure is not set up for it. |
|
47 \end{itemize} |
|
48 |
|
49 \noindent |
|
50 Also note that the running time of each part will be restricted to a |
30 Also note that the running time of each part will be restricted to a |
51 maximum of 360 seconds on my laptop: If you calculate a result once, |
31 maximum of 360 seconds on my laptop: If you calculate a result once, |
52 try to avoid to calculate the result again. Feel free to copy any code |
32 try to avoid to calculate the result again. Feel free to copy any code |
53 you need from files \texttt{knight1.scala}, \texttt{knight2.scala} and |
33 you need from files \texttt{knight1.scala}, \texttt{knight2.scala} and |
54 \texttt{knight3.scala}. |
34 \texttt{knight3.scala}. |
55 |
35 |
56 \subsection*{Disclaimer} |
36 \DISCLAIMER{} |
57 |
|
58 It should be understood that the work you submit represents |
|
59 your \textbf{own} effort. You have not copied from anyone else. An |
|
60 exception is the Scala code I showed during the lectures or |
|
61 uploaded to KEATS, which you can freely use. |
|
62 |
37 |
63 \subsection*{Background} |
38 \subsection*{Background} |
64 |
39 |
65 The \textit{Knight's Tour Problem} is about finding a tour such that |
40 The \textit{Knight's Tour Problem} is about finding a tour such that |
66 the knight visits every field on an $n\times n$ chessboard once. For |
41 the knight visits every field on an $n\times n$ chessboard once. For |
210 |
185 |
211 |
186 |
212 \subsubsection*{Tasks (file knight1.scala)} |
187 \subsubsection*{Tasks (file knight1.scala)} |
213 |
188 |
214 \begin{itemize} |
189 \begin{itemize} |
215 \item[(1a)] Implement an \texttt{is-legal-move} function that takes a |
190 \item[(1a)] Implement an \texttt{is\_legal\_move} function that takes a |
216 dimension, a path and a position as argument and tests whether the |
191 dimension, a path and a position as arguments and tests whether the |
217 position is inside the board and not yet element in the |
192 position is inside the board and not yet element in the |
218 path. \hfill[1 Mark] |
193 path. \hfill[1 Mark] |
219 |
194 |
220 \item[(1b)] Implement a \texttt{legal-moves} function that calculates for a |
195 \item[(1b)] Implement a \texttt{legal\_moves} function that calculates for a |
221 position all legal onward moves. If the onward moves are |
196 position all legal onward moves. If the onward moves are |
222 placed on a circle, you should produce them starting from |
197 placed on a circle, you should produce them starting from |
223 ``12-o'clock'' following in clockwise order. For example on an |
198 ``12-o'clock'' following in clockwise order. For example on an |
224 $8\times 8$ board for a knight on position $(2, 2)$ and otherwise |
199 $8\times 8$ board for a knight at position $(2, 2)$ and otherwise |
225 empty board, the legal-moves function should produce the onward |
200 empty board, the legal-moves function should produce the onward |
226 positions in this order: |
201 positions in this order: |
227 |
202 |
228 \begin{center} |
203 \begin{center} |
229 \texttt{List((3,4), (4,3), (4,1), (3,0), (1,0), (0,1), (0,3), (1,4))} |
204 \texttt{List((3,4), (4,3), (4,1), (3,0), (1,0), (0,1), (0,3), (1,4))} |
236 \begin{center} |
211 \begin{center} |
237 \texttt{List((6,5), (5,6))} |
212 \texttt{List((6,5), (5,6))} |
238 \end{center} |
213 \end{center} |
239 \mbox{}\hfill[1 Mark] |
214 \mbox{}\hfill[1 Mark] |
240 |
215 |
241 \item[(1c)] Implement two recursive functions (count-tours and |
216 \item[(1c)] Implement two recursive functions (\texttt{count\_tours} and |
242 enum-tours). They each take a dimension and a path as |
217 \texttt{enum\_tours}). They each take a dimension and a path as |
243 arguments. They exhaustively search for tours starting |
218 arguments. They exhaustively search for tours starting |
244 from the given path. The first function counts all possible |
219 from the given path. The first function counts all possible |
245 tours (there can be none for certain board sizes) and the second |
220 tours (there can be none for certain board sizes) and the second |
246 collects all tours in a list of paths.\hfill[2 Marks] |
221 collects all tours in a list of paths.\hfill[2 Marks] |
247 \end{itemize} |
222 \end{itemize} |
264 sure the list is not \texttt{Nil}). |
239 sure the list is not \texttt{Nil}). |
265 |
240 |
266 \subsubsection*{Tasks (file knight2.scala)} |
241 \subsubsection*{Tasks (file knight2.scala)} |
267 |
242 |
268 \begin{itemize} |
243 \begin{itemize} |
269 \item[(2a)] Implement a first-function. This function takes a list of |
244 \item[(2a)] Implement a \texttt{first}-function. This function takes a list of |
270 positions and a function $f$ as arguments. The function $f$ takes a |
245 positions and a function $f$ as arguments; $f$ is the name we give to |
271 position as argument and produces an optional path. So $f$'s type is |
246 this argument). The function $f$ takes a position as argument and |
272 \texttt{Pos => Option[Path]}. The idea behind the first-function is |
247 produces an optional path. So $f$'s type is \texttt{Pos => |
273 as follows: |
248 Option[Path]}. The idea behind the \texttt{first}-function is as follows: |
274 |
249 |
275 \[ |
250 \[ |
276 \begin{array}{lcl} |
251 \begin{array}{lcl} |
277 \textit{first}(\texttt{Nil}, f) & \dn & \texttt{None}\\ |
252 \textit{first}(\texttt{Nil}, f) & \dn & \texttt{None}\\ |
278 \textit{first}(x\!::\!xs, f) & \dn & \begin{cases} |
253 \textit{first}(x\!::\!xs, f) & \dn & \begin{cases} |
281 \end{cases} |
256 \end{cases} |
282 \end{array} |
257 \end{array} |
283 \] |
258 \] |
284 |
259 |
285 \noindent That is, we want to find the first position where the |
260 \noindent That is, we want to find the first position where the |
286 result of $f$ is not \texttt{None}, if there is one. Note that you |
261 result of $f$ is not \texttt{None}, if there is one. Note that |
287 do not (need to) know anything about the function $f$ except its |
262 `inside' \texttt{first}, you do not (need to) know anything about |
288 type, namely \texttt{Pos => Option[Path]}. There is one additional |
263 the argument $f$ except its type, namely \texttt{Pos => |
289 point however you should take into account when implementing |
264 Option[Path]}. There is one additional point however you should |
290 \textit{first}: you will need to calculate what the result of $f(x)$ |
265 take into account when implementing \texttt{first}: you will need to |
291 is; your code should do this only \textbf{once}!\\\mbox{}\hfill[1 Mark] |
266 calculate what the result of $f(x)$ is; your code should do this |
267 only \textbf{once} and for as \textbf{few} elements in the list as |
|
268 possible! Do not calculate $f(x)$ for all elements and then see which |
|
269 is the first \texttt{Some}.\\\mbox{}\hfill[1 Mark] |
|
292 |
270 |
293 \item[(2b)] Implement a first-tour function that uses the |
271 \item[(2b)] Implement a \texttt{first\_tour} function that uses the |
294 first-function from (2a), and searches recursively for a tour. |
272 \texttt{first}-function from (2a), and searches recursively for a tour. |
295 As there might not be such a tour at all, the first-tour function |
273 As there might not be such a tour at all, the \texttt{first\_tour} function |
296 needs to return an \texttt{Option[Path]}.\\\mbox{}\hfill[2 Marks] |
274 needs to return a value of type |
275 \texttt{Option[Path]}.\\\mbox{}\hfill[2 Marks] |
|
297 \end{itemize} |
276 \end{itemize} |
298 |
277 |
299 \noindent |
278 \noindent |
300 \textbf{Testing:} The first tour function will be called with board |
279 \textbf{Testing:} The \texttt{first\_tour} function will be called with board |
301 sizes of up to $8 \times 8$. |
280 sizes of up to $8 \times 8$. |
302 \bigskip |
281 \bigskip |
303 |
282 |
304 \noindent |
283 \noindent |
305 \textbf{Hints:} a useful list function: \texttt{.filter(..)} filters a |
284 \textbf{Hints:} a useful list function: \texttt{.filter(..)} filters a |
307 \texttt{.isDefined} returns true, if an option is \texttt{Some(..)}; |
286 \texttt{.isDefined} returns true, if an option is \texttt{Some(..)}; |
308 anonymous functions can be constructed using \texttt{(x:Int) => ...}, |
287 anonymous functions can be constructed using \texttt{(x:Int) => ...}, |
309 this functions takes an \texttt{Int} as an argument. |
288 this functions takes an \texttt{Int} as an argument. |
310 |
289 |
311 |
290 |
312 \newpage |
291 %%\newpage |
313 \subsection*{Part 2 (3 Marks)} |
292 \subsection*{Part 2 (3 Marks)} |
314 |
293 |
315 As you should have seen in Part 1, a naive search for tours beyond |
294 As you should have seen in Part 1, a naive search for tours beyond |
316 $8 \times 8$ boards and also searching for closed tours even on small |
295 $8 \times 8$ boards and also searching for closed tours even on small |
317 boards takes too much time. There is a heuristic, called Warnsdorf's |
296 boards takes too much time. There is a heuristic, called \emph{Warnsdorf's |
318 rule that can speed up finding a tour. This heuristic states that a |
297 Rule} that can speed up finding a tour. This heuristic states that a |
319 knight is moved so that it always proceeds to the field from which the |
298 knight is moved so that it always proceeds to the field from which the |
320 knight will have the \underline{fewest} onward moves. For example for |
299 knight will have the \underline{fewest} onward moves. For example for |
321 a knight on field $(1, 3)$, the field $(0, 1)$ has the fewest possible |
300 a knight on field $(1, 3)$, the field $(0, 1)$ has the fewest possible |
322 onward moves, namely 2. |
301 onward moves, namely 2. |
323 |
302 |
330 text = \small 5, markfield=b1, |
309 text = \small 5, markfield=b1, |
331 text = \small 2, markfield=Z1, |
310 text = \small 2, markfield=Z1, |
332 setpieces={Na3}] |
311 setpieces={Na3}] |
333 |
312 |
334 \noindent |
313 \noindent |
335 Warnsdorf's rule states that the moves on the board above should be |
314 Warnsdorf's Rule states that the moves on the board above should be |
336 tried in the order |
315 tried in the order |
337 |
316 |
338 \[ |
317 \[ |
339 (0, 1), (0, 5), (2, 1), (2, 5), (3, 4), (3, 2) |
318 (0, 1), (0, 5), (2, 1), (2, 5), (3, 4), (3, 2) |
340 \] |
319 \] |
345 do not count moves that revisit any field already visited. |
324 do not count moves that revisit any field already visited. |
346 |
325 |
347 \subsubsection*{Tasks (file knight3.scala)} |
326 \subsubsection*{Tasks (file knight3.scala)} |
348 |
327 |
349 \begin{itemize} |
328 \begin{itemize} |
350 \item[(3a)] Write a function ordered-moves that calculates a list of |
329 \item[(3a)] Write a function \texttt{ordered\_moves} that calculates a list of |
351 onward moves like in (1b) but orders them according to the |
330 onward moves like in (1b) but orders them according to the |
352 Warnsdorf’s rule. That means moves with the fewest legal onward moves |
331 Warnsdorf’s Rule. That means moves with the fewest legal onward moves |
353 should come first (in order to be tried out first). \hfill[1 Mark] |
332 should come first (in order to be tried out first). \hfill[1 Mark] |
354 |
333 |
355 \item[(3b)] Implement a first-closed-tour-heuristic function that searches for a |
334 \item[(3b)] Implement a \texttt{first\_closed-tour\_heuristic} |
335 function that searches for a |
|
356 \textbf{closed} tour on a $6\times 6$ board. It should use the |
336 \textbf{closed} tour on a $6\times 6$ board. It should use the |
357 first-function from (2a) and tries out onward moves according to |
337 \texttt{first}-function from (2a) and tries out onward moves according to |
358 the ordered-moves function from (3a). It is more likely to find |
338 the \texttt{ordered\_moves} function from (3a). It is more likely to find |
359 a solution when started in the middle of the board (that is |
339 a solution when started in the middle of the board (that is |
360 position $(dimension / 2, dimension / 2)$). \hfill[1 Mark] |
340 position $(dimension / 2, dimension / 2)$). \hfill[1 Mark] |
361 |
341 |
362 \item[(3c)] Implement a first-tour-heuristic function for boards up to |
342 \item[(3c)] Implement a \texttt{first\_tour\_heuristic} function |
343 for boards up to |
|
363 $40\times 40$. It is the same function as in (3b) but searches for |
344 $40\times 40$. It is the same function as in (3b) but searches for |
364 tours (not just closed tours). You have to be careful to write a |
345 tours (not just closed tours). You have to be careful to write a |
365 tail-recursive version of the first-tour-heuristic function |
346 tail-recursive function of the \texttt{first\_tour\_heuristic} function |
366 otherwise you will get problems with stack-overflows.\\ |
347 otherwise you will get problems with stack-overflows.\\ |
367 \mbox{}\hfill[1 Mark] |
348 \mbox{}\hfill[1 Mark] |
368 \end{itemize} |
349 \end{itemize} |
369 \bigskip |
350 \bigskip |
370 |
351 |