The CLP Procedure

Eight Queens

The Eight Queens problem is a special instance of the N-Queens problem, where the objective is to position N queens on an N×N chessboard such that no two queens attack each other. The CLP procedure provides an expressive constraint for variable arrays that can be used for solving this problem very efficiently.

You can model this problem by using a variable array A of dimension N, where upper A left-bracket i right-bracket is the row number of the queen in column i. Since no two queens can be in the same row, it follows that all the upper A left-bracket i right-bracket’s must be pairwise distinct.

In order to ensure that no two queens can be on the same diagonal, the following should be true for all i and j:

upper A left-bracket j right-bracket minus upper A left-bracket i right-bracket less-than greater-than j minus i

and

upper A left-bracket j right-bracket minus upper A left-bracket i right-bracket less-than greater-than i minus j

In other words,

upper A left-bracket i right-bracket minus i less-than greater-than upper A left-bracket j right-bracket minus j

and

upper A left-bracket i right-bracket plus i less-than greater-than upper A left-bracket j right-bracket plus j

Hence, the left-parenthesis upper A left-bracket i right-bracket plus i right-parenthesis’s are pairwise distinct, and the left-parenthesis upper A left-bracket i right-bracket minus i right-parenthesis’s are pairwise distinct.

These two conditions, in addition to the one requiring that the upper A left-bracket i right-bracket’s be pairwise distinct, can be formulated using the FOREACH statement.

One possible such CLP formulation is presented as follows:

proc clp out=mylib.out
         varselect=fifo; /* Variable Selection Strategy               */
   array A[8] (A1-A8);   /* Define the array A                        */
   var (A1-A8)=[1,8];    /* Define each of the variables in the array */
                         /* Initialize domains                        */
   /* A[i] is the row number of the queen in column i*/
   foreach(A, DIFF,  0); /* A[i] 's are pairwise distinct */
   foreach(A, DIFF, -1); /* A[i] - i 's are pairwise distinct */
   foreach(A, DIFF,  1); /* A[i] + i 's are pairwise distinct */
run;

The ARRAY statement is required when you are using a FOREACH statement, and it defines the array A in terms of the eight variables A1–A8. The domain of each of these variables is explicitly specified in the VARIABLE statement to be the digits 1 through 8 since they represent the row number on an 8×8 board. FOREACH(A, DIFF, 0) represents the constraint that the upper A left-bracket i right-bracket’s are different. FOREACH(A, DIFF, –1) represents the constraint that the left-parenthesis upper A left-bracket i right-bracket minus i right-parenthesis’s are different, and FOREACH(A, DIFF, 1) represents the constraint that the left-parenthesis upper A left-bracket i right-bracket plus i right-parenthesis’s are different. The VARSELECT= option specifies the variable selection strategy to be first-in-first-out, the order in which the variables are encountered by the CLP procedure.

The following statements display the Solution data table shown in Output 4.2:

proc print data=mylib.out noobs label;
   label A1=a A2=b A3=c A4=d
         A5=e A6=f A7=g A8=h;
run;

Output 4.2: A Solution to the Eight Queens Problem

abcdefgh
15863724


The corresponding solution to the Eight Queens problem is displayed in Figure 1.

Figure 1: A Solution to the Eight Queens Problem

A Solution to the Eight Queens Problem


Last updated: November 20, 2025