When a constraint program uses optimisation, i.e. min_max/2,5 or minimize/2,5 , its structure is slightly different than when just looking for any solution. The labelling predicate, instead of being simply called, is executed under the control of the minimisation predicate. To simplify the use and tracing of optimising programs, Grace provides the predicate grace_minimize(Expr). When it is called instead of grace_label/0, Grace will label all registered variables and find the solution that minimises the expression Expr. The user can specify interactively whether the branch and bound method should use the restarting ( min_max/5 ) or the continuation ( minimize/5 ) strategy and whether to use a percentage for the optimality proof. For example, let us find the solution to the N-queens problem which minimises the sum of the first three queen's rows. The file queensm.pl looks as follows:
We have used two utility predicates (see Appendix C), one to extract the first list elements and another one to construct their symbolic sum. At the beginning of the program, the control panel looks as usual, except that the current cost value is displayed in the status window::- lib(grace). % Grace queens(N, List) :- grace_start(queens), % Grace % Define variables and their domains length(List, N), List :: 1..N, grace_matrix(List, queens), % Grace % Constraints %2 alldistinct(List), %3 constrain_queens(List), % Define the expression to minimise list_range(1, 3, List, SubList), list_sum(SubList, Cost), % Label the variables grace_minimize(Cost). % Grace
The program stops without highlighting the selected variable, i.e. asynchronously, and waits for user actions before the labelling starts. In this way, the user has the possibility to change some optimisation parameters, e.g. the branch_and_bound or percent options, because as soon as the labelling starts, it is no longer possible to modify them. Let us for example change the default restart strategy to continue:
We then press the RUN button and the program runs until it finds the first solution:
Note that the solution number is in parentheses which means that it is the number of sub-optimal solutions found so far. Moreover, the status message tells us that a solution with a particular cost has been found. Up to now, the execution was similar to the non-optimising one. When we press RUN for the second time, however, we obtain a new solution which is better than the first one:
The program then finds another solution with cost 9. It is proven to be optimal and the control panel shows
The number of solutions is now shown without parentheses, because this is really a global solution of the whole problem.