Section~#secbacktrack#60058> introduced algorithms that backtrack. An algorithm
is a recursive function that generates new problems for the recursive step
rather than using the pieces of its input data. On occasion, an algorithm may
have to make choices among several different branches on the path to a
solution. Some of them may lead nowhere. In such cases, an algorithm can
backtrack. That is, it can restart the search for a solution with a different
branch to check if it succeeds.
When the data representation for a problem uses structures or vectors, a
backtracking algorithm can use structure mutation to test different
approaches to a solution. The key is to design a pair of functions that
change the state of the problem representation and that undo such a change
in case the attempt fails. In this section, we discuss two examples of this
kind: the Queens puzzle and the Peg Solitaire problem.
Recall the Queens puzzle from section~#secqueens#60059>. The goal of the
puzzle is to place <#70601#><#60060#>n<#60060#><#70601#> queens on some board of arbitrary size <#60061#>m<#60061#>-by-<#60062#>m<#60062#> such that the queens do not threaten each other. A queen in
chess threatens all places on the row, the column, and the two diagonals
going through her own position. Figure~#figqueens#60063> illustrates the
notion with a single queen on an 8-by-8 board.
In section~#secqueens#60064>, we represented chess boards with
lists. When we got to know vectors, we also developed a vector-based
representation in exercise~#exvectorchess#60065>, as follows:
<#72132#>;; A <#70602#><#60070#>chess board<#60070#><#70602#> <#70603#><#60071#>CB<#60071#><#70603#> is a <#70604#><#60072#>(vectorof<#60072#> <#60073#>(vectorof<#60073#> <#60074#>boolean))<#60074#><#70604#><#72132#>
<#60075#>;; such that all vectors have the same size.<#60075#>
<#72133#>;; <#70605#><#60076#>make-chess-board<#60076#> <#60077#>:<#60077#> <#60078#>N<#60078#> <#60079#><#60079#><#60080#>-;SPMgt;<#60080#><#60081#><#60081#> <#60082#>CB<#60082#><#70605#><#72133#>
<#60083#>(d<#60083#><#60084#>efine<#60084#> <#60085#>(make-chess-board<#60085#> <#60086#>m)<#60086#>
<#60087#>(build-vector<#60087#> <#60088#>m<#60088#> <#60089#>(lambda<#60089#> <#60090#>(i)<#60090#> <#60091#>(build-vector<#60091#> <#60092#>m<#60092#> <#60093#>(lambda<#60093#> <#60094#>(j)<#60094#> <#60095#>true)))))<#60095#>
The initial value of <#70606#><#60099#>true<#60099#><#70606#> indicates that it is still legitimate to
place a queen on the corresponding field.
The queen-placement algorithm places a queen on one of the available field
on the given board and creates a new board that reflects the addition of
the queen. This step is repeated until there are no more queens to be
placed, in which case the puzzle is solved, or until there are no more
places to choose from. In the second case, the algorithm backtracks. That
is, the algorithm removes the last queen that was added and chooses some
other available field. If there are no more fields, it backtracks further.
The algorithm signals a complete failure when it becomes impossible to
backtrack.
On one hand, creating a new board at each stage is acceptable because the
chosen field may turn out to be the wrong one in which case the old board is
the starting point for the next step. On the other hand, a human player is more
likely to place the queen on the board and to remove it if the position turns
out to be a bad choice. Thus the Queens problem is an example of where the
ability of computer programs to create many different alternative ``worlds''
clashes with the human world, which offers extremely limited possibilities of
this kind and thus restricts human imagination. Still, it is worth exploring
how the addition of vector mutation to our vocablulary enables us to mimic the
actions of a human player more closely than before.
<#60103#>Exercise 43.3.1<#60103#>
Placing an additional queen on a chess board means that some of the fields
on the chess board have to be set to <#70607#><#60105#>false<#60105#><#70607#> because they are now
threatened and no longer available for future placements of queens. The
placement of a queen is a function of the given chess board and the indices
of the new queen:
<#72134#>;; <#70608#><#60110#>place-queen<#60110#> <#60111#>:<#60111#> <#60112#>CB<#60112#> <#60113#>N<#60113#> <#60114#>N<#60114#> <#60115#><#60115#><#60116#>-;SPMgt;<#60116#><#60117#><#60117#> <#60118#>void<#60118#><#70608#><#72134#>
<#72135#>;; effect: to set those fields in <#70609#><#60119#>CB<#60119#><#70609#> to <#70610#><#60120#>false<#60120#><#70610#> that are threatened by <#72135#>
<#72136#>;; a queen on row <#70611#><#60121#>i<#60121#><#70611#>, column <#70612#><#60122#>j<#60122#><#70612#><#72136#>
<#60123#>(define<#60123#> <#60124#>(place-queen<#60124#> <#60125#>CB<#60125#> <#60126#>i<#60126#> <#60127#>j)<#60127#> <#60128#>...))<#60128#>
<#60132#>Hints:<#60132#> \ (1) Recall <#70613#><#60133#>threatened?<#60133#><#70613#> from exercise~#exqueen2#60134>. (2)
Consider developing an abstract function for processing all items on a
board. The function is analogous to <#70614#><#60135#>vec-for-all<#60135#><#70614#> from
exercise~#exabsvec#60136>.~ Solution<#70615#><#70615#>
<#60142#>Exercise 43.3.2<#60142#>
Develop <#70616#><#60144#>unplace-queen<#60144#><#70616#>. The function removes a queen and its threats
from a chess board:
<#72137#>;; <#70617#><#60149#>unplace-queen<#60149#> <#60150#>:<#60150#> <#60151#>CB<#60151#> <#60152#>N<#60152#> <#60153#>N<#60153#> <#60154#><#60154#><#60155#>-;SPMgt;<#60155#><#60156#><#60156#> <#60157#>void<#60157#><#70617#><#72137#>
<#72138#>;; effect: to set those fields in <#70618#><#60158#>CB<#60158#><#70618#> to <#70619#><#60159#>false<#60159#><#70619#> that were threatened by <#72138#>
<#72139#>;; a queen on row <#70620#><#60160#>i<#60160#><#70620#>, column <#70621#><#60161#>j<#60161#><#70621#><#72139#>
<#60162#>(define<#60162#> <#60163#>(unplace-queen<#60163#> <#60164#>CB<#60164#> <#60165#>i<#60165#> <#60166#>j)<#60166#> <#60167#>...))<#60167#>
Given any chess board <#70622#><#60171#>CB<#60171#><#70622#>, the following equation holds:
<#60176#>(b<#60176#><#60177#>egin<#60177#>
<#60178#>(place-queen<#60178#> <#60179#>CB<#60179#> <#60180#>i<#60180#> <#60181#>j)<#60181#>
<#60182#>(unplace-queen<#60182#> <#60183#>CB<#60183#> <#60184#>i<#60184#> <#60185#>j)<#60185#>
<#60186#>CB)<#60186#>
<#60187#>=<#60187#> <#60188#>CB<#60188#>
for all legal positios <#70623#><#60192#>i<#60192#><#70623#> and <#70624#><#60193#>j<#60193#><#70624#>. Why is this not true if
we swap the first two subexpressions?~ Solution<#70625#><#70625#>
<#60199#>Exercise 43.3.3<#60199#>
Modify the solution of the Queens problem in section~#secqueens#60201> to
use the vector-based representation of chess boards and the functions
<#70626#><#60202#>place-queen<#60202#><#70626#> and <#70627#><#60203#>unplace-queen<#60203#><#70627#> from
exercises~#exiqueen0#60204> and~#exiqueen1#60205>.~ Solution<#70628#><#70628#>
<#60211#>Exercise 43.3.4<#60211#>
Use the <#60213#>draw.ss<#60213#> teachpack to develop a view for the Queens
problem. Recall that a view is a function that illustrates certain aspects
of a problem in a graphical manner. The natural solution here is to display
the intermediate stages of the solution process according to the algorithm
of exercise~#exiqueen2#60214>, including the backtracking
steps.~ Solution<#70629#><#70629#>
In section~#secmoreaccusoli#60222> we discussed the Peg Solitaire
problem. The goal of the game is to eliminate the pegs one by one, until
only one peg is left. A player can eliminate a peg if one of the
neighboring holes is unoccupied and if there is a peg in the hole in the
opposite direction. In that case, the second peg can jump over the first
one and the first one is eliminated.
Just as with the Queens puzzle, we can represent the problem state with
vectors and indicators for pegs and holes. In the real world, moving a peg
corresponds to physical action that changes the state of the board. When a
player backtracks, the two pegs are placed back to their original
positions.
<#60225#>Exercise 43.3.5<#60225#>
Design a vector representation for the triangular peg solitaire
board. Develop an auxiliary function for creating a board with
a single hole.~ Solution<#70630#><#70630#>
<#60232#>Exercise 43.3.6<#60232#>
Design a data representation for a move in the Peg Solitaire problem. Develop
a function for making a move. Develop a function for undoing a move. The two
functions should exclusively rely on effects. Do the functions satisfy an
equation analogous to <#70631#><#60234#>place-queen<#60234#><#70631#> and <#70632#><#60235#>unplace-queen<#60235#><#70632#> in
exercise~#exiqueen1#60236>?~ Solution<#70633#><#70633#>
<#60242#>Exercise 43.3.7<#60242#>
Develop a backtracking algorithm for solving a Peg Solitaire problem whose
hole is placed randomly.~ Solution<#70634#><#70634#>
<#60249#>Exercise 43.3.8<#60249#>
Use the <#60251#>draw.ss<#60251#> teachpack to develop a view for the Peg Solitaire
problem. Recall that a view is a function that illustrates certain aspects
of a problem in a graphical manner. The natural solution here is to display
the intermediate stages of the solution process according to the algorithm
of exercise~#exisolitaire2#60252>, including the backtracking
steps.~ Solution<#70635#><#70635#>