1% BEGIN LICENSE BLOCK
2% Version: CMPL 1.1
3%
4% The contents of this file are subject to the Cisco-style Mozilla Public
5% License Version 1.1 (the "License"); you may not use this file except
6% in compliance with the License.  You may obtain a copy of the License
7% at www.eclipse-clp.org/license.
8% 
9% Software distributed under the License is distributed on an "AS IS"
10% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.  See
11% the License for the specific language governing rights and limitations
12% under the License. 
13% 
14% The Original Code is  The ECLiPSe Constraint Logic Programming System. 
15% The Initial Developer of the Original Code is  Cisco Systems, Inc. 
16% Portions created by the Initial Developer are
17% Copyright (C) 2006 Cisco Systems, Inc.  All Rights Reserved.
18% 
19% Contributor(s): 
20% 
21% END LICENSE BLOCK
22
23\chapter{Tree Search Methods}
24\label{chapsearch}
25%HEVEA\cutdef[1]{section}
26%----------------------------------------------------------------------
27\section{Introduction}
28%----------------------------------------------------------------------
29In this chapter we will take a closer look at the principles and
30\index{alternative search methods}
31alternative methods of searching for solutions in the presence of
32constraints. Let us first recall what we are talking about.
33We assume we have the standard pattern of a constraint program:
34\begin{code}
35solve(Data) :-
36        model(Data, Variables),
37        search(Variables),
38        print_solution(Variables).
39\end{code}
40The model part contains the logical {\em model} of our problem. It defines
41the variables and the constraints.
42Every variable has a {\em domain} of values that it can take
43(in this context, we only consider domains with a finite number of values).
44
45Once the model is set up, we go into the search phase.
46Search is necessary since generally the implementation of the constraints
47is not complete, i.e.\ not strong enough to logically infer directly
48the solution to the problem. Also, there may be multiple solutions
49which have to be located by search, e.g.\ in order to find the best one.
50In the following, we will use the following terminology:
51\begin{itemize}
52\item If a variable is given a value (from its domain, of course),
53    \index{assignment}
54        we call this an {\em assignment}. If every problem variable is given
55        a value, we call this a {\em total assignment}.
56\item A total assignment is a {\em solution} if it satisfies all the
57        constraints.
58\item The {\em search space} is the set of all possible total assignments.
59    \index{search space}
60        The search space is usually very large because it grows exponentially
61        with the problem size:
62        \begin{displaymath}
63        SearchSpaceSize = {DomainSize}^{NumberOfVariables}
64        \end{displaymath}
65\end{itemize}
66
67
68% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
69\subsection{Overview of Search Methods}
70% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
71
72\begin{figure}
73\begin{center}
74\resizebox{0.55\textwidth}{!}{\includegraphics{../search/search3.eps}}
75\end{center}
76\caption{A search space of size 16}
77\label{figsearchspace}
78\end{figure}
79Figure \ref{figsearchspace} shows a search space with N (here 16)
80possible total assignments, some of which are solutions.
81Search methods now differ in the way in which these assignments
82are visited.
83We can classify search methods according to different criteria:
84\begin{description}
85\item[Complete vs incomplete exploration] complete search means that the search space
86    \index{complete search}
87    \index{incomplete search}
88    is investigated in such a way that all solutions are guaranteed to be found.
89    This is necessary when the optimal solution is needed (one has to prove
90    that no better solution exists). Incomplete search may be sufficient when
91    just some solution or a relatively good solution is needed.
92\item[Constructive vs move-based] this indicates whether the method advances
93    \index{constructive search}
94    \index{move-based search}
95    by incrementally constructing assignments (thereby reasoning about partial
96    assignments which represent subsets of the search space) or by moving
97    between total assignments (usually by modifying previously explored
98    assignments).
99\item[Randomness] some methods have a random element while others follow
100    \index{random search}
101    fixed rules.
102\end{description}
103Here is a selection of search methods together with their properties:
104
105\begin{center}
106\begin{tabular}{|l|lll|}
107\hline
108Method&                 exploration&    assignments&    random\\
109\hline
110Full tree search&       complete&       constructive&   no\\
111Credit search&          incomplete&     constructive&   no\\
112Bounded backtrack&      incomplete&     constructive&   no\\
113Limited discrepancy&    complete&       constructive&   no\\
114Hill climbing&          incomplete&     move-based&     possibly\\
115Simulated annealing&    incomplete&     move-based&     yes\\
116Tabu search&            incomplete&     move-based&     possibly\\
117Weak commitment&        complete&       hybrid&         no\\
118\hline
119\end{tabular}
120\end{center}
121
122\index{tree search}
123\index{search tree}
124The constructive search methods usually organise the search space by
125partitioning it systematically.  This can be done naturally with a
126search tree (Figure \ref{figsearchtree}).  The nodes in this tree
127represent choices which partition the remaining search space into two
128or more (usually disjoint) sub-spaces.  Using such
129a tree structure, the search space can be traversed systematically and
130completely (with as little as O(N) memory requirements).
131
132\begin{figure}
133\begin{center}
134\resizebox{0.55\textwidth}{!}{\includegraphics{../search/search4.eps}}
135\end{center}
136\caption{Search space structured using a search tree}
137\label{figsearchtree}
138\end{figure}
139Figure \ref{figtreesearch} shows a sample tree search, namely a depth-first
140incomplete traversal.
141As opposed to that, figure \ref{figmovesearch} shows an example of an
142incomplete move-based search which does not follow a fixed search space
143structure. Of course, it will have to take other precautions to avoid
144looping and ensure termination.
145\begin{figure}
146\begin{center}
147\resizebox{0.55\textwidth}{!}{\includegraphics{../search/search5.eps}}
148\end{center}
149\caption{A move-based search}
150\label{figmovesearch}
151\end{figure}
152
153\begin{figure}
154\begin{center}
155\resizebox{0.55\textwidth}{!}{\includegraphics{../search/search6.eps}}
156\end{center}
157\caption{A tree search (depth-first)}
158\label{figtreesearch}
159\end{figure}
160
161A few further observations:
162Move-based methods are usually incomplete. This is not surprising given
163typical sizes of search spaces.
164A complete exploration of a huge search space
165is only possible if large sub-spaces can be excluded a priori, and this
166is only possible with constructive methods which allow one to reason about
167whole classes of similar assignments.
168Moreover, a complete search method must remember which parts of the
169search space have already been visited.
170This can only be implemented with
171acceptable memory requirements if there is a simple structuring of the
172space that allows compact encoding of sub-spaces.
173
174
175% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
176\subsection{Optimisation and Search}
177% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
178\label{secbboptsearch}
179\index{optimisation}
180Many practical problems are in fact optimisation problems, ie.\ we are
181not just interested in some solution or all solutions, but in
182the best solution.
183
184Fortunately, there is a general method to find the optimal solution
185based on the ability to find all solutions.
186\index{branch-and-bound}
187The {\em branch-and-bound} technique works as follows:
188\begin{enumerate}
189\item Find a first solution
190\item Add a constraint requiring a better solution than the best
191    one we have so far (e.g.\ require lower cost)
192\item Find a solution which satisfies this new constraint.
193    If one exists, we have a new best solution and we repeat step 2.
194    If not, the last solution found is the proven optimum.
195\end{enumerate}
196The {\em branch\_and\_bound} library provides generic predicates 
197which implement this technique:
198\begin{description}
199\item[minimize(+Goal,-Cost)]
200This is the simplest predicate in the {\em branch_and_bound} library:
201A solution of the goal {\it Goal} is found that minimizes the value of
202{\em Cost}. {\em Cost} should be a variable that is affected, and 
203eventually instantiated, by the execution of {\it Goal}. Usually, {\it Goal}
204is the search procedure of a constraint problem and {\it Cost} is the variable
205representing the cost.
206
207\item[bb_min(+Goal, -Cost, ++Options)]
208A more flexible version where the programmer can take more control
209over the branch and bound behaviour and choose between different
210strategies and parameter settings.
211\end{description}
212
213
214% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
215\subsection{Heuristics}
216% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
217
218Since search space sizes grow exponentially with problem size,
219it is not possible to explore all assignments except for the
220very smallest problems.
221The only way out is {\em not} to look at the whole search space.
222There are only two ways to do this:
223\begin{itemize}
224\item {\bf Prove} that certain areas of the space contain no solutions.
225    This can be done with the help of constraints. This is often referred
226    to as {\em pruning}\index{pruning}.
227\item {\bf Ignore} parts of the search space that are unlikely to contain
228    solutions (i.e.\ do incomplete search), or at least postpone their exploration.
229    This is done by using {\em heuristics}\index{heuristics}.
230    A heuristic is a particular traversal order of the search space
231    which explores promising areas first.
232\end{itemize}
233
234In the following sections we will first investigate the considerable
235degrees of freedom that are available for heuristics within the framework of
236systematic tree search, which is the traditional search method
237in the Constraint Logic Programming world.
238
239Subsequently, we will turn our attention to move-based methods
240which in {\eclipse} can be implemented using the facilities of the 
241{\tt repair} library.
242
243
244%----------------------------------------------------------------------
245\section{Complete Tree Search with Heuristics}
246%----------------------------------------------------------------------
247
248\index{complete search}
249There is one form of tree search which is especially economic: 
250depth-first, left-to-right search by backtracking.  It allows
251a search tree to be traversed systematically while requiring only a stack
252of maximum depth N for bookkeeping.  Most other strategies of tree
253search (e.g.  breadth-first) have exponential memory requirements. 
254This unique property is the reason why backtracking is a built feature
255of {\eclipse}.  Note that the main disadvantage of the depth-first
256strategy (the danger of going down an infinite branch) does not come
257into play here because we deal with finite search trees.
258
259\index{depth-first search}
260Sometimes depth-first search and heuristic search are treated as antonyms.
261This is only justified when the shape of the search tree is statically fixed.
262Our case is different: we have the freedom of deciding on the shape of every
263sub-tree before we start to traverse it depth-first. While this does not
264allow for absolutely {\em any} order of visiting the leaves of the search tree,
265it does provide considerable flexibility. This flexibility can be exploited
266by variable and value selection strategies.
267
268% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
269\subsection{Search Trees}
270% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
271
272In general, the nodes of a search tree represent {\em choices}.
273\index{choice}
274These choices should be mutually exclusive and therefore partition the
275\index{partition a search space}
276search space into two or more disjoint sub-spaces.
277In other words, the original problem is reduced to a disjunction
278of simpler sub-problems.
279
280In the case of finite-domain problems, the most common form of choice
281is to choose a particular value for a problem variable
282(this technique is often called
283\index{labeling}
284{\em labeling}).
285For a boolean variable, this means setting the variable to 0 in one
286branch of the search tree and to 1 in the other.
287In {\eclipse}, this can be written as a disjunction
288(which is implemented by backtracking):
289\begin{quote}\begin{alltt}
290( X1=0 ; X1=1 )
291\end{alltt}\end{quote}
292Other forms of choices are possible. If X2 is a variable that can take
293integer values from 0 to 3 (assume it has been declared as \verb'X2::0..3'),
294we can make a n-ary search tree node by writing
295\begin{quote}\begin{alltt}
296( X2=0 ; X2=1 ; X2=2 ; X2=3 )
297\end{alltt}\end{quote}
298or more compactly
299\begin{quote}\begin{alltt}
300indomain(X2)
301\end{alltt}\end{quote}
302However, choices do not necessarily involve choosing a concrete value
303for a variable. It is also possible to make disjoint choices by
304\index{domain splitting}
305{\em domain splitting}, e.g.
306\begin{quote}\begin{alltt}
307( X2 #=< 1 ; X2 #>= 2 )
308\end{alltt}\end{quote}
309or by choosing a value in one branch and excluding it in the other:
310\begin{quote}\begin{alltt}
311( X2 = 0 ; X2 #>= 1 )
312\end{alltt}\end{quote}
313In the following examples, we will mainly use simple labeling,
314which means that the search tree nodes correspond to a variable
315and a node's branches correspond to the different values that the
316variable can take.
317
318
319% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
320\subsection{Variable Selection}
321\index{variable selection}
322% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
323
324\begin{figure}
325\begin{center}
326\resizebox{0.5\textwidth}{!}{\includegraphics{../search/search1.eps}}
327\end{center}
328\caption{The effect of variable selection}
329\label{figvarsel}
330\end{figure}
331
332Figure \ref{figvarsel} shows how variable selection reshapes a search tree.
333If we decide to choose values for X1 first (at the root of the search tree)
334and values for X2 second, then the search tree has one particular shape.
335If we now assume a depth-first, left-to-right traversal by backtracking,
336this corresponds to one particular order of visiting the leaves of the tree:
337(0,0), (0,1), (0,2), (0,3), (1,0), (1,1), (1,2), (1,3).
338
339If we decide to choose values for X2 first and X1 second, then the tree and
340consequently the order of visiting the leaves is different:
341(0,0), (1,0), (0,1), (1,1), (0,2), (1,2), (0,3), (1,3).
342
343While with 2 variables there are only 2 variable selection strategies,
344this number grows exponentially with the number of variables. For 5
345variables there are already $2^{2^{5}-1} = 2147483648$ different variable selection
346strategies to choose from.
347
348Note that the example shows something else: If the domains of the variables
349are different, then the variable selection can change the number of internal
350nodes in the tree (but not the number of leaves). To keep the number of nodes
351down, variables with small domains should be selected first.
352
353
354% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
355\subsection{Value Selection}
356\index{value selection}
357% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
358
359The other way to change the search tree is value selection, i.e. reordering
360the child nodes of a node by choosing the 
361values from the domain of a variable in a particular order.
362Figure \ref{figvalsel} shows how this can change the order of visiting the
363leaves:
364(1,2), (1,1), (1,0), (1,3), (0,1), (0,3), (0,0), (0,2).
365
366\begin{figure}
367\begin{center}
368\resizebox{0.5\textwidth}{!}{\includegraphics{../search/search2.eps}}
369\end{center}
370\caption{The effect of value selection}
371\label{figvalsel}
372\end{figure}
373
374By combining variable and value selection alone, a large number of different
375heuristics can be implemented.
376To give an idea of the numbers involved, table \ref{visits} shows the search
377space sizes, the number of possible search space traversal orderings,
378and the number of orderings
379that can be obtained by variable and value selection (assuming domain size 2).
380
381\begin{figure}[t]
382\enableunderscores
383\begin{center}
384\begin{tabular}{|l|l|l|l|}
385\hline
386Variables&      Search space&   Visiting orders&        Selection Strategies\\
387\hline
3881&              2&                      2&              2\\
3892&              4&                      24&             16\\
3903&              8&                      40320&          336\\
3914&              16&                     $2.1*10^{13}$&  $1.8*10^7$\\
3925&              32&                     $2.6*10^{35}$&  $3.5*10^{15}$\\
393n&              $2^n$&          $2^n!$& 
394                                $2^{{2^n}-1} \prod_{i=0}^{n-1} (n-1)^{2^i}$\\
395\hline
396\end{tabular}
397\end{center}
398\caption{Flexibility of Variable/Value Selection Strategies}
399\label{visits}
400\disableunderscores
401\end{figure}
402
403% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
404\subsection{Example}
405% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
406
407\index{queens}
408We use the famous N-Queens problem to illustrate how heuristics can be applied
409to backtrack search through variable and value selection.
410We model the problem with one variable per queen, assuming that each queen
411occupies one colunm. The variables range from 1 to N and indicate the row
412in which the queen is being placed. The constraints ensure that no two
413queens occupy the same row or diagonal:
414\label{queenscode}
415\begin{code}
416:- lib(ic).
417
418queens(N, Board) :-
419        length(Board, N),
420        Board :: 1..N,
421        ( fromto(Board, [Q1|Cols], Cols, []) do
422            ( foreach(Q2, Cols), count(Dist,1,_), param(Q1) do
423                noattack(Q1, Q2, Dist)
424            )
425        ).
426
427    noattack(Q1,Q2,Dist) :-
428        Q2 #\verb.\.= Q1,
429        Q2 - Q1 #\verb.\.= Dist,
430        Q1 - Q2 #\verb.\.= Dist.
431\end{code}
432We are looking for a first solution to the 16-queens problem by calling
433\begin{quote}\begin{alltt}
434?- queens(16, Vars),   % model
435   labeling(Vars).     % search
436\end{alltt}\end{quote}
437We start naively, using the pre-defined labeling-predicate that comes with the
438{\em ic} library. It is defined as follows:
439\begin{code}
440labeling(AllVars) :-
441        ( foreach(Var, AllVars) do
442            indomain(Var)                       % select value
443        ).
444\end{code}
445The strategy here is simply to select the variables
446from left to right as they occur in the list, and they are
447assigned values starting from the lowest to the numerically highest they can
448take (this is the definition of indomain/1).
449A solution is found after 542 backtracks
450(see section \ref{countbt} below for how to count backtracks).
451
452A first improvement is to employ a
453{\bf general-purpose variable-selection heuristic},
454\index{first-fail principle}
455the so called first-fail principle. It requires to label the
456variables with the smallest domain first. This reduces the branching
457factor at the root of the search tree and the total number of internal nodes.
458\index{ic_search}
459The delete/5 predicate from the {\em ic_search} library
460implements this strategy for finite integer domains.
461Using delete/5, we can redefine our labeling-routine as follows:
462\begin{code}
463:- lib(ic_search).
464labeling_b(AllVars) :-
465        ( fromto(AllVars, Vars, VarsRem, []) do
466            delete(Var, Vars, VarsRem, 0, first_fail), % dynamic var-select
467            indomain(Var)                              % select value
468        ).
469\end{code}
470Indeed, for the 16-queens example, this leads to a dramatic improvement,
471the first solution is found with only 3 backtracks now.
472But caution is necessary: The 256-queens instance for example solves
473nicely with the naive strategy, but our improvement leads to a
474disappointment: the time increases dramatically!
475This is not uncommmon with heuristics: one has to keep in mind that the
476search space is not reduced, just re-shaped. Heuristics that yield good
477results with some problems can be useless or counter-productive with others.
478Even different instances of the same problem can exhibit widely different
479characteristics.
480 
481Let us try to employ a {\bf problem-specific heuristic}:
482\index{problem-specific heuristic}
483Chess players know that pieces in the middle of the board are more
484useful because they can attack more fields. We could therefore start
485placing queens in the middle of the board to reduce the number of
486unattacked fields earlier. We can achieve that simply by pre-ordering the
487variables such that the middle ones are first in the list:
488\begin{code}
489labeling_c(AllVars) :-
490        middle_first(AllVars, AllVarsPreOrdered), % static var-select
491        ( foreach(Var, AllVarsPreOrdered) do
492            indomain(Var)                         % select value
493        ).
494\end{code}
495The implementation of middle\_first/2 requries a bit of list manipulation
496\index{middle-first}
497and uses primitives from the lists-library:
498\begin{code}
499:- lib(lists).
500
501middle_first(List, Ordered) :-
502        halve(List, Front, Back),
503        reverse(Front, RevFront),
504        splice(Back, RevFront, Ordered).
505\end{code}
506This strategy also improves things for the 16-queens instance, the
507first solution requires 17 backtracks.
508
509We can now improve things further by {\bf combining} the two
510variable-selection strategies:
511When we pre-order the variables such that the middle ones are first,
512\index{delete/5}
513the delete/5 predicate will prefer middle variables when several
514have the same domain size:
515\begin{code}
516labeling_d(AllVars) :-
517        middle_first(AllVars, AllVarsPreOrdered), % static var-select
518        ( fromto(AllVarsPreOrdered, Vars, VarsRem, []) do
519            delete(Var, Vars, VarsRem, 0, first_fail),  % dynamic var-select
520            indomain(Var)                       % select value
521        ).
522\end{code}
523The result is positive: for the 16-queens instance,
524the number of backtracks goes down to zero,
525and more difficult instances become solvable!
526
527Actually, we have not yet implemented our intuitive heuristics properly.
528We start placing queens in the middle columns, but not on the middle rows.
529With our model, that can only be achieved by {\bf changing the value selection},
530ie.\ setting the variables to values in the middle of their domain first.
531For this we can use indomain/2, a more flexible variant of indomain/1,
532provided by the {\em ic_search} library.
533It allows us to specify that we want to start labeling with the middle value
534in the domain:
535\begin{code}
536labeling_e(AllVars) :-
537        middle_first(AllVars, AllVarsPreOrdered), % static var-select
538        ( fromto(AllVarsPreOrdered, Vars, VarsRem, []) do
539            delete(Var, Vars, VarsRem, 0, first_fail),  % dynamic var-select
540            indomain(Var, middle)                 % select value
541        ).
542\end{code}
543Surprisingly, this improvement again increases the backtrack count for
54416-queens again to 3.
545However, when looking at a number of different instances of the problem,
546we can observe that the overall behaviour has improved and the
547performance has become more predictable than with the
548initial more naive strategies.
549Figure \ref{queensresult} shows the behaviour of the different
550strategies on various problem sizes.
551\begin{figure}
552\begin{center}
553\begin{tabular}{l|l|l|l|l|l|l|l|l}
554N =     &8  &12 &14 &16 &32 &64 &128    &256\\
555\hline
556labeling_a  &10 &15 &103    &542    &   &   &   &\\
557labeling_b  &10 &16 &11 &3  &4  &148    &   &\\
558labeling_c  &0  &3  &22 &17 &   &   &   &\\
559labeling_d  &0  &0  &1  &0  &1  &1  &   &\\
560labeling_e  &3  &3  &38 &3  &7  &1  &0  &0\\
561\end{tabular}
562\end{center}
563\label{queensresult}
564\caption{N-Queens with different labeling strategies: Number of backtracks}
565\end{figure}
566
567
568
569% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
570\subsection{Counting Backtracks}
571\index{backtrack count}
572% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
573
574%The size of the (remaining) search space can be computed easily
575%in finite-domain problems. All we have to do is to multiply the
576%sizes of all the (remaining) variable's domains:
577%\begin{quote}\begin{alltt}
578%search_space(Vars, Size) :-
579%        ( foreach(V,Vars), fromto(1,S0,S1,Size) do
580%            dvar_domain(V,D), S1 is S0*dom_size(D)
581%        ).
582%\end{alltt}\end{quote}
583
584\label{countbt}
585An interesting piece of information during program development is the
586number of backtracks. It is a good measure for the quality of
587both constraint propagation and search heuristics.
588We can instrument our labeling routine as follows:
589\begin{code}
590labeling(AllVars) :-
591        init_backtracks,
592        ( foreach(Var, AllVars) do
593            count_backtracks,       % insert this before choice!
594            indomain(Var)
595        ),
596        get_backtracks(B),
597        printf("Solution found after %d backtracks%n", [B]).
598\end{code}
599The backtrack counter itself can be implemented by the code below.
600It uses a non-logical counter variable (backtracks) and an additional
601flag (deep\_fail) which ensures that backtracking to exhausted choices
602does not increment the count.
603\begin{code}
604:- local variable(backtracks), variable(deep_fail).
605
606init_backtracks :-
607        setval(backtracks,0).
608
609get_backtracks(B) :-
610        getval(backtracks,B).
611
612count_backtracks :-
613        setval(deep_fail,false).
614count_backtracks :-
615        getval(deep_fail,false),        % may fail
616        setval(deep_fail,true),
617        incval(backtracks),
618        fail.
619\end{code}
620Note that there are other possible ways of defining the number of backtracks.
621However, the one suggested here has the following useful properties:
622\begin{itemize}
623\item Shallow backtracking (an attempt to instantiate a variable which
624    \index{shallow backtrack}
625    causes immediate failure due to constraint propagation) is not counted.
626    If constraint propagation works well, the count is therefore zero.
627\item With a perfect heuristic, the first solution is found with zero
628    backtracks.
629\item If there are N solutions, the best achievable value is N (one backtrack
630    per solution). Higher values indicate an opportunity to improve pruning
631    by constraints.
632\end{itemize}
633
634The search/6 predicates from the libary {\tt ic_search} 
635have this backtrack counter built-in.
636
637
638%----------------------------------------------------------------------
639\section{Incomplete Tree Search}
640\index{incomplete search}
641%----------------------------------------------------------------------
642
643The library {\tt ic_search} contains a flexible
644search routine
645\bipref{search/6}{../bips/lib/ic_search/search-6.html},
646which implements several variants of incomplete tree search.
647
648For demonstration, we will use the N-queens problem from above.
649The following use of search/6 is equivalent to labeling(Xs) and
650will print all 92 solutions:
651\begin{quote}\begin{verbatim}
652?-  queens(8, Xs),
653    search(Xs, 0, input_order, indomain, complete, []),
654    writeln(Xs),
655    fail.
656[1, 5, 8, 6, 3, 7, 2, 4]
657...
658[8, 4, 1, 3, 6, 2, 7, 5]
659No.
660\end{verbatim}\end{quote}
661
662
663% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
664\subsection{First Solution}
665% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
666
667One of the easiest ways to do incomplete search is to simply stop after
668the first solution has been found. This is simply programmed using cut or
669\index{first solution}
670\index{once/1}
671once/1:
672\begin{quote}\begin{verbatim}
673?-  queens(8, Xs),
674    once search(Xs, 0, input_order, indomain, complete, []),
675    writeln(Xs),
676    fail.
677[1, 5, 8, 6, 3, 7, 2, 4]
678No.
679\end{verbatim}\end{quote}
680This will of course not speed up the finding of the first solution.
681
682
683% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
684\subsection{Bounded Backtrack Search} 
685\index{bounded backtrack search} 
686% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
687
688Another way to limit the scope of backtrack search is to keep a
689record of the number of backtracks, and curtail the search when this
690limit is exceeded.
691\begin{figure}
692\begin{center}
693\resizebox{0.6\textwidth}{!}{\includegraphics{bbs.eps}}
694\end{center}
695\caption{Bounded-backtrack search}
696\label{figbbs}
697\end{figure}
698The {\em bbs} option of the search/6 predicate implements this:
699\begin{quote}\begin{verbatim}
700?-  queens(8, Xs),
701    search(Xs, 0, input_order, indomain, bbs(20), []),
702    writeln(Xs),
703    fail.
704[1, 5, 8, 6, 3, 7, 2, 4]
705[1, 6, 8, 3, 7, 4, 2, 5]
706[1, 7, 4, 6, 8, 2, 5, 3]
707[1, 7, 5, 8, 2, 4, 6, 3]
708No.
709\end{verbatim}\end{quote}
710Only the first 4 solutions are found, the next solution would have
711required more backtracks than were allowed. 
712Note that the solutions that are found are all located on the left hand
713side of the search tree. This often makes sense because with a good
714search heuristic, the solutions tend to be towards the left hand side.
715Figure \ref{figbbs} illustrates the effect of bbs (note that the diagram
716does not correspond to the queens example, it shows an unconstrained search
717tree with 5 binary variables).
718
719
720% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
721\subsection{Depth Bounded Search}
722\index{depth-bounded search} 
723% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
724
725A simple method of limiting search is to limit the depth of the search
726tree. In many constraint problems with a fixed number of variables
727this is not very useful, since all solutions occur at the same depth
728of the tree. However, one may want to explore the tree completely
729up to a certain depth and switch to an incomplete search method below this
730depth. The search/6 predicate allows for instance the combination of
731depth-bounded search with bounded-backtrack search. The following
732explores the first 2 levels of the search tree completely, and does not
733allow any backtracking below this level.
734\begin{figure}
735\begin{center}
736\resizebox{0.6\textwidth}{!}{\includegraphics{dbsbbs.eps}}
737\end{center}
738\caption{Depth-bounded, combined with bounded-backtrack search}
739\label{figdbsbbs}
740\end{figure}
741This gives 16 solutions, equally distributed over the search tree:
742\begin{quote}\begin{verbatim}
743?-  queens(8, Xs),
744    search(Xs, 0, input_order, indomain, dbs(2,bbs(0)), []),
745    writeln(Xs),
746    fail.
747[3, 5, 2, 8, 1, 7, 4, 6]
748[3, 6, 2, 5, 8, 1, 7, 4]
749[4, 2, 5, 8, 6, 1, 3, 7]
750[4, 7, 1, 8, 5, 2, 6, 3]
751[4, 8, 1, 3, 6, 2, 7, 5]
752[5, 1, 4, 6, 8, 2, 7, 3]
753[5, 2, 4, 6, 8, 3, 1, 7]
754[5, 3, 1, 6, 8, 2, 4, 7]
755[5, 7, 1, 3, 8, 6, 4, 2]
756[6, 4, 1, 5, 8, 2, 7, 3]
757[7, 1, 3, 8, 6, 4, 2, 5]
758[7, 2, 4, 1, 8, 5, 3, 6]
759[7, 3, 1, 6, 8, 5, 2, 4]
760[8, 2, 4, 1, 7, 5, 3, 6]
761[8, 3, 1, 6, 2, 5, 7, 4]
762[8, 4, 1, 3, 6, 2, 7, 5]
763No (0.18s cpu)
764\end{verbatim}\end{quote}
765
766
767% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
768\subsection{Credit Search}
769\index{credit search}
770% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
771
772Credit search\cite{beldiceanu:credit}
773is a tree search method where the number of
774nondeterministic choices is limited a priori.  This is achieved by
775starting the search at the tree root with a certain integral amount of
776credit.  This credit is split between the child nodes, their credit
777between their child nodes, and so on.  A single unit of credit cannot
778be split any further: subtrees provided with only a single credit unit
779are not allowed any nondeterministics choices, only one path though these
780subtrees can be explored, i.e. only one leaf in the subtree can be visited.
781Subtrees for which no credit is left are pruned,
782i.e.\ not visited.
783
784The following code (a replacement for labeling/1)
785implements credit search. For ease of understanding, it is
786limited to boolean variables:
787\begin{code}
788% Credit search (for boolean variables only)
789credit_search(Credit, Xs) :-
790        (
791            foreach(X, Xs),
792            fromto(Credit, ParentCredit, ChildCredit, _)
793        do
794            ( var(X) ->
795                ParentCredit > 0,  % possibly cut-off search here
796                ( % Choice
797                    X = 0, ChildCredit is (ParentCredit+1)//2
798                ;
799                    X = 1, ChildCredit is ParentCredit//2
800                )
801            ;
802                ChildCredit = ParentCredit
803            )
804        ).
805\end{code}
806Note that the leftmost alternative (here X=0)
807gets slightly more credit than the rightmost one (here X=1)
808by rounding the child node's credit up rather than down. 
809This is especially relevant when the leftover credit is down to 1:
810from then on, only the leftmost alternatives will be taken until a
811leaf of the search tree is reached. The leftmost alternative should
812therefore be the one favoured by the search heuristics.
813
814What is a reasonable amount of credit to give to a search?
815In an unconstrained search tree, the credit is equivalent to the
816number of leaf nodes that will be reached.
817The number of leaf nodes grows exponentially with the number of
818labelled variables, while tractable computations should have
819polynomial runtimes. A good rule of thumb could therefore be to
820use as credit the number of variables squared or cubed, thus enforcing
821polynomial runtime.
822
823Note that this method in its pure form allows choices only close to the
824root of the search tree, and disallows choices completely below a certain
825tree depth. This is too restrictive when the value selection strategy
826is not good enough. A possible remedy is to combine credit search with
827bounded backtrack search.
828
829
830The implementation of credit search in the search/6 predicate works for
831arbitrary domain variables: Credit is distributed by giving half to the
832leftmost child node, half of the remaining credit to the second child node
833and so on. Any remaining credit after the last child node is lost.
834\begin{figure}
835\begin{center}
836\resizebox{0.6\textwidth}{!}{\includegraphics{credit.eps}}
837\end{center}
838\caption{Credit-based incomplete search}
839\label{figcredit}
840\end{figure}
841In this implementation, credit search is always combined with another
842search method which is to be used when the credit runs out.
843
844When we use credit search in the queens example, we get a limited number
845of solutions, but these solutions are not the leftmost ones (like with
846bounded-backtrack search), they are
847from different parts of the search tree, although biased towards the left:
848\begin{quote}\begin{verbatim}
849?- queens(8, Xs),
850   search(Xs, 0, input_order, indomain, credit(20,bbs(0)), []),
851   writeln(Xs),
852   fail.
853[2, 4, 6, 8, 3, 1, 7, 5]
854[2, 6, 1, 7, 4, 8, 3, 5]
855[3, 5, 2, 8, 1, 7, 4, 6]
856[5, 1, 4, 6, 8, 2, 7, 3]
857No.
858\end{verbatim}\end{quote}
859We have used a credit limit of 20. When credit runs out, we switch to
860bounded backtrack search with a limit of 0 backtracks.
861
862
863
864% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
865\subsection{Timeout}
866\index{timeout}
867% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
868
869Another form of incomplete tree search is simply to use time-outs.
870\index{bb_min/3}
871\index{bb_min/6}
872The branch-and-bound primitives {\tt bb_min/3,6} allow
873a maximal runtime to be specified. If a timeout occurs, the best solution
874found so far is returned instead of the proven optimum.
875
876A general timeout is available from the library {\tt test_util}.
877It has parameters {\tt timeout(Goal, Seconds, TimeOutGoal)}.
878When {\tt Goal} has run for
879more than {\tt Seconds} seconds, it is aborted and {\tt TimeOutGoal}
880is called instead. 
881
882%----------------------------------------------------------------------
883\subsection{Limited Discrepancy Search}
884\index{limited discrepancy search}
885%----------------------------------------------------------------------
886
887% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
888%\subsubsection{Introduction}
889% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
890
891Limited discrepancy search ({\em LDS}) is a search method that assumes
892the user has a good heuristic for directing the search.  A perfect
893heuristic would, of course, not require any search.  However most
894heuristics are occasionally misleading.  Limited Discrepancy Search
895follows the heuristic on almost every decision.  The
896``discrepancy'' is a measure of the degree to which it fails to follow
897the heuristic.  LDS starts searching with a discrepancy of $0$ (which
898means it follows the heuristic exactly).  Each time LDS fails to find
899a solution with a given discrepancy, the discrepancy is increased and
900search restarts.  In theory the search is complete, as eventually the
901discrepancy will become large enough to admit a solution, or cover
902the whole search space.  In practice, however, it is only beneficial
903to apply LDS with small discrepancies.  Subsequently, if no solution
904is found, other search methods should be tried.
905The definitive reference to LDS is \cite{harvey95:lds:inp}
906%\begin{quote}
907%Limited Discrepancy Search, Harvey and Ginsberg,
908%pp.607-613, Proc. IJCAI'95
909%\end{quote}
910
911\index{discrepancy}
912There are different possible ways of measuring discrepancies.
913The one implemented in the search/6 predicate is a variant of the
914original proposal. It considers the first
915value selection choice as the heuristically best value with
916discrepancy 0, the first alternative has a discrepancy of 1, the
917second a discrepancy of 2 and so on.
918\begin{figure}
919\begin{center}
920\resizebox{0.6\textwidth}{!}{\includegraphics{lds.eps}}
921\end{center}
922\caption{Incomplete search with LDS}
923\label{figlds}
924\end{figure}
925
926As LDS relies on a good heuristic, it only makes sense for the queens
927problem if we use a good heuristic, e.g. first-fail variable selection
928and indomain-middle value selection. Allowing a discrepancy of 1 yields
9294 solutions:
930\begin{quote}\begin{verbatim}
931?- queens(8, Xs), 
932   search(Xs, 0, first_fail, indomain_middle, lds(1), []),
933   writeln(Xs),
934   fail.
935[4, 6, 1, 5, 2, 8, 3, 7]
936[4, 6, 8, 3, 1, 7, 5, 2]
937[4, 2, 7, 5, 1, 8, 6, 3]
938[5, 3, 1, 6, 8, 2, 4, 7]
939No.
940\end{verbatim}\end{quote}
941
942The reference also suggests that combining LDS with Bounded Backtrack
943Search ({\em BBS}) yields good behaviour. The search/6 predicate
944accordingly supports the combination of LDS with BBS and DBS.
945The rationale for this is that heuristic choices typically get
946more reliable deeper down in the search tree.
947
948
949%% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
950%\subsubsection{Limited Discrepancy Search using a Static Heuristic}
951%% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
952%
953%We start by assuming a static heuristic, which is a complete
954%assignment to the problem variables specified in advance of the
955%search.  The predicate supporting static LDS takes a list of variables
956%(those which are to be labelled) and a list of values (one heuristic
957%value for each variable, respectively).  Each variable has a finite
958%domain, and its heuristic value should belong to its domain (though
959%the LDS search can still succeed even if this is not the case).
960%
961%The measure of discrepancy, in this case, is simply the number of
962%variables labelled differently to the heuristic.  Thus the maximum
963%discrepancy is just the number of variables to be
964%labelled.
965%
966%LDS search is implemented in the file
967%{\tt lds.ecl} in the {\tt doc/examples} directory of your
968%{\eclipse} installation. You can copy this file and load it with
969%\begin{quote}\begin{alltt}
970%:- use_module(lds).
971%\end{alltt}\end{quote}
972%Static LDS search is then available via the predicate
973%{\bf static_lds(Var, Vals, Discrepancy)} whose arguments are
974%\begin{description}
975%\item[Vars] the list of problem variables.  Some of the
976%variables may already be instantiated.  The others
977%must have associated finite domains.
978%\item[Vals] the list of values according to the heuristic.  It
979%must be the same length as Vars, and the heuristic
980%must match the value, in case the variable is
981%already instantiated.
982%\item[Discrepancy] the discrepancy of the solution returned.  Typically this
983%is an output of the search (an integer between $0$ and the number of
984%variables), but it can also be used as an input.
985%\end{description}
986%The finite domain library must be loaded, and the variables must have
987%finite domains.  An example invocation is:
988%\begin{quote}\begin{alltt}
989%?- [X,Y,Z]::1..3, X+Y+Z#=5, static_lds([X,Y,Z],[1,2,3],D).
990%\end{alltt}\end{quote}
991%The answers are returned on backtracking in the following order:
992%\begin{itemize}
993%\item
994%X = 1
995%Y = 2
996%Z = 2
997%D = 1     
998%\item
999%X = 1
1000%Y = 1
1001%Z = 3
1002%D = 1     
1003%\item
1004%X = 1
1005%Y = 3
1006%Z = 1
1007%D = 2     
1008%\item
1009%X = 2
1010%Y = 2
1011%Z = 1
1012%D = 2     
1013%\item
1014%X = 2
1015%Y = 1
1016%Z = 2
1017%D = 3     
1018%\item
1019%X = 3
1020%Y = 1
1021%Z = 1
1022%D = 3
1023%\end{itemize}
1024%
1025%
1026%% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1027%\subsubsection{Limited Discrepancy Search using a Dynamic Heuristic}
1028%% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1029%
1030%Often the heuristic value is calculated on the fly, during search.  To
1031%cope with this we use the {\eclipse} ``tentative value'' facility in
1032%{\eclipse}'s {\em repair} library. 
1033%The heuristic is stored with the variable as its tentative value. 
1034%
1035%The tentative value may be changed during search.  For example if a
1036%variable is instantiated as a consequence of constraint propagation
1037%during search, its tentative value is automatically changed to its
1038%actual value. 
1039%
1040%Dynamic LDS search is available in {\eclipse} via the predicate
1041%{\bf dynamic_lds(Vars, Discrepancy)}.
1042%Each variable in the list of variables {\em Vars} 
1043%must have a tentative value.
1044%
1045%An example invocation is:
1046%\begin{quote}\begin{alltt}
1047%?- [X,Y,Z]::1..3, [X,Y,Z] tent_set [1,2,3], X+Y+Z#=5,
1048%   dynamic_lds([X,Y,Z],D).
1049%\end{alltt}\end{quote}
1050%The answers are returned on backtracking in the following order.
1051%Notice that the first solution has a discrepancy of $0$, because
1052%constraint propagation instantiates the third variable to $2$,
1053%thus changing its tentative value from $3$ to $2$.
1054%\begin{itemize}
1055%\item
1056%X = 1
1057%Y = 2
1058%Z = 2
1059%D = 0    
1060%\item
1061%X = 1
1062%Y = 1
1063%Z = 3
1064%D = 1    
1065%\item
1066%X = 1
1067%Y = 3
1068%Z = 1
1069%D = 1    
1070%\item
1071%X = 2
1072%Y = 2
1073%Z = 1
1074%D = 1    
1075%\item
1076%X = 3
1077%Y = 1
1078%Z = 1
1079%D = 1    
1080%\item
1081%X = 2
1082%Y = 1
1083%Z = 2
1084%D = 2 
1085%\end{itemize}
1086%
1087%% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1088%\subsubsection{LDS and BBS Combined}
1089%% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1090%
1091%The two search techniques, BBS and LDS, can be merged quite simply in
1092%{\eclipse}, so that for each discrepancy level only a limited number of
1093%backtracks are allowed.  
1094%
1095%An example invocation is:
1096%\begin{quote}\begin{alltt}
1097%?- Vars=[X,Y,Z], Vars::1..3, Vars tent_set [1,2,3], X+Y+Z#=6,
1098%   bbs_dynamic_lds(Vars,4,D).
1099%\end{alltt}\end{quote}
1100%The answers are returned on backtracking in the following order:
1101%\begin{itemize}
1102%\item
1103%X = 1
1104%Y = 2
1105%Z = 3
1106%D = 0   
1107%\item
1108%X = 1
1109%Y = 3
1110%Z = 2
1111%D = 1   
1112%\item
1113%X = 2
1114%Y = 2
1115%Z = 2
1116%D = 1   
1117%\item
1118%X = 3
1119%Y = 2
1120%Z = 1
1121%D = 1   \\
1122%Backtrack limit exceeded
1123%\item
1124%X = 2
1125%Y = 1
1126%Z = 3
1127%D = 2 \\
1128%Backtrack limit exceeded
1129%\end{itemize}
1130
1131%----------------------------------------------------------------------
1132\section{Exercises}
1133%----------------------------------------------------------------------
1134
1135For exercises 1-3, start from the constraint model for the queens problem
1136given in section \ref{queenscode}. It is available in the examples directory
1137as queens_ic.ecl.
1138
1139\begin{enumerate}
1140
1141\item Use the search/6 predicate from the ic_search library and the
1142standard model for the queens problem (given below) to find ONE
1143solution to the 42-queens problem.
1144With a naive search strategy this requires millions of backtracks.
1145Using heuristics and/or incomplete search, try to find a solution
1146in less than 100 backtracks!
1147
1148
1149\item How many solutions does the 9-queens problem have?
1150
1151
1152\item Solve the "8 sticky queens problem": Assume that the queens
1153in neighbouring columns want to stick together as close as possible.
1154Minimize the sum of the vertical distances between neighbouring queens.
1155What is the best and what is the worst solution for this problem?
1156
1157
1158\item For given N, create a list of length N whose members are numbers
1159between 1 and N (inclusive), which are all different (easy so far) 
1160and satisfy the following constraint.
1161For each element E of the list, its successors are divided into two sets,
1162   \begin{itemize}
1163   \item BiggerE: the successors which are greater than E and
1164   \item SmallerE: the successors less than E.
1165   \end{itemize}
1166(Thus no successor takes the same value as E).
1167The cardinalities of the sets BiggerE and SmallerE differ by at most 1. 
1168
1169
1170\item A harder version of the problem is similar.
1171For given N, create a list of length N whose members are numbers
1172between 1 and some upper bound Max (start with, say Max = $N^2$), 
1173which are all different (easy so far) 
1174and satisfy the following (more complex) constraint.
1175For each K from 1..N, call the Kth element of the list Ek. 
1176Its successors are divided into two sets, as before:
1177   \begin{itemize}
1178   \item BiggerEk: the successors which are greater than or equal to Ek + K and
1179   \item SmallerEk: the successors less than or equal to Ek - K.
1180   \end{itemize}
1181(Thus no successor takes a value between Ek-K+1 and Ek+K-1.)
1182The cardinalities of the sets BiggerEk and SmallerEk differ 
1183by at most 1. 
1184
1185What is the smallest upper bound Max for which there is a feasible solution?
1186
1187\end{enumerate}
1188
1189%HEVEA\cutend
1190