CALL LEXCOMBI Routine

Generates all combinations of the indices of n objects taken k at a time in lexicographic order.

Category: Combinatorial

Syntax

CALL LEXCOMBI(n, k, index-1, …, index-k);

Required Arguments

n

is a numeric constant, variable, or expression that specifies the total number of objects.

k

is a numeric constant, variable, or expression that specifies the number of objects in each combination.

index

is a numeric variable that contains indices of the objects in the combination that is returned. Indices are integers between 1 and n, inclusive.

Tip If index-1 is missing or zero, then the CALL LEXCOMBI routine initializes the indices to index-1=1 through index-k=k. Otherwise, CALL LEXCOMBI creates a new combination by removing one index from the combination and adding another index.

Details

CALL LEXCOMBI Processing

Before the first call to the LEXCOMBI routine, complete one of the following tasks:
  • Set index-1 equal to zero or to a missing value.
  • Initialize index-1 through index-k to distinct integers between 1 and n inclusive.
The number of combinations of n objects taken k at a time can be computed as COMB(n,k). To generate all combinations of n objects taken k at a time, call LEXCOMBI in a loop that executes COMB(n,k) times.

Using the CALL LEXCOMBI Routine with Macros

If you call the LEXCOMBI routine from the macro processor with %SYSCALL, then you must initialize all arguments to numeric values. %SYSCALL reformats the values that are returned.
If an error occurs during the execution of the CALL LEXCOMBI routine, then both of the following values are set:
  • &SYSERR is assigned a value that is greater than 4.
  • &SYSINFO is assigned a value that is less than –100.
If there are no errors, then &SYSERR is set to zero, and &SYSINFO is set to one of the following values:
  • 1 if the value of variable-1 changed
  • j if variable-1 through variable-i did not change, but variable-j did change, where j=i+1
  • –1 if all distinct combinations have already been generated

Comparisons

The CALL LEXCOMBI routine generates all combinations of the indices of n objects taken k at a time in lexicographic order. The CALL ALLCOMBI routine generates all combinations of the indices of n objects taken k at a time in a minimum change order.

Examples

Example 1: Using the CALL LEXCOMBI Routine with the DATA Step

The following example uses the CALL LEXCOMBI routine to generate combinations of indices in lexicographic order.
data _null_;
   array x[5] $3 ('ant' 'bee' 'cat' 'dog' 'ewe');
   array c[3] $3;
   array i[3];
   n=dim(x);
   k=dim(i);
   i[1]=0;
   ncomb=comb(n,k);
   do j=1 to ncomb;
      call lexcombi(n, k, of i[*]);
      do h=1 to k;
         c[h]=x[i[h]];
      end;
      put @4 j= @10 'i= ' i[*] +3 'c= ' c[*];
   end;
run;
SAS writes the following output to the log:
   j=1   i= 1 2 3    c= ant bee cat
   j=2   i= 1 2 4    c= ant bee dog
   j=3   i= 1 2 5    c= ant bee ewe
   j=4   i= 1 3 4    c= ant cat dog
   j=5   i= 1 3 5    c= ant cat ewe
   j=6   i= 1 4 5    c= ant dog ewe
   j=7   i= 2 3 4    c= bee cat dog
   j=8   i= 2 3 5    c= bee cat ewe
   j=9   i= 2 4 5    c= bee dog ewe
   j=10  i= 3 4 5    c= cat dog ewe

Example 2: Using the CALL LEXCOMBI Routine with Macros and Displaying the Return Code

The following example uses the CALL LEXCOMBI routine with macros. The output includes values for the %SYSINFO macro.
%macro test;
   %let x1=0;
   %let x2=0;
   %let x3=0;
   %let n=5;
   %let k=3;
   %let ncomb=%sysfunc(comb(&n,&k));
   %do j=1 %to &ncomb+1;
      %syscall lexcombi(n,k,x1,x2,x3);
      %let jfmt=%qsysfunc(putn(&j,5.));
      %let pad=%qsysfunc(repeat(%str(),6-%length(&x1 &x2 &x3)));
      %put &jfmt: &x1 &x2 &x3 &pad sysinfo=&sysinfo;
   %end;
%mend;
%test
SAS writes the following output to the log:
    1: 1 2 3  sysinfo=1
    2: 1 2 4  sysinfo=3
    3: 1 2 5  sysinfo=3
    4: 1 3 4  sysinfo=2
    5: 1 3 5  sysinfo=3
    6: 1 4 5  sysinfo=2
    7: 2 3 4  sysinfo=1
    8: 2 3 5  sysinfo=3
    9: 2 4 5  sysinfo=2
   10: 3 4 5  sysinfo=1
   11: 3 4 5  sysinfo=-1