solve(Data) :- model(Data, Variables), search(Variables), print_solution(Variables). |
Figure 12.1 shows a search space with N (here 16) possible total assignments, some of which are solutions. Search methods now differ in the way in which these assignments are visited. We can classify search methods according to different criteria:![]()
Figure 12.1: A search space of size 16
Method | exploration | assignments | random |
Full tree search | complete | constructive | no |
Credit search | incomplete | constructive | no |
Bounded backtrack | incomplete | constructive | no |
Limited discrepancy | complete | constructive | no |
Hill climbing | incomplete | move-based | possibly |
Simulated annealing | incomplete | move-based | yes |
Tabu search | incomplete | move-based | possibly |
Weak commitment | complete | hybrid | no |
Figure 12.4 shows a sample tree search, namely a depth-first incomplete traversal. As opposed to that, figure 12.3 shows an example of an incomplete move-based search which does not follow a fixed search space structure. Of course, it will have to take other precautions to avoid looping and ensure termination.![]()
Figure 12.2: Search space structured using a search tree
![]()
Figure 12.3: A move-based search
A few further observations: Move-based methods are usually incomplete. This is not surprising given typical sizes of search spaces. A complete exploration of a huge search space is only possible if large sub-spaces can be excluded a priori, and this is only possible with constructive methods which allow one to reason about whole classes of similar assignments. Moreover, a complete search method must remember which parts of the search space have already been visited. This can only be implemented with acceptable memory requirements if there is a simple structuring of the space that allows compact encoding of sub-spaces.![]()
Figure 12.4: A tree search (depth-first)