You need SAS/OR 13.2 or later to use the CLP solver in PROC OPTMODEL. As a workaround, you can use PROC CLP instead:
proc clp out=clpout findallsolns;
var (X1-X8)=[0,8];
var X9=[0,2];
lincon X1 + X2 + X3 + X4 + X5 + X6 + X7 + X8 + X9 = 8;
run;
proc optmodel printlevel=0;
num n = 9;
num Xub {j in 1..n} = (if j <= 8 then 8 else 2);
set OBS;
num nsol1 = card(OBS);
num xsol {1..n, 1..nsol1};
read data clpout into OBS=[_N_] {j in 1..n} <xsol[j,_N_]=col('X'||j)>;
num solsum {s in 1..nsol1} = sum {j in 1..n-1} j * xsol[j,s];
/* for each solution, maximize the number of groups with sum 8 and minimize remainder */
num curr_sol;
set GROUPS = 1..solsum[curr_sol]/8;
var NumInGroup {j in 1..n-1, GROUPS} integer >= 0 <= xsol[j,curr_sol];
var Unassigned {j in 1..n-1} integer >= 0 <= xsol[j,curr_sol];
var IsEight {GROUPS} binary;
/* primary objective: maximize NumEights, secondary objective: minimize NumUnassigned */
impvar NumEights = sum {g in GROUPS} IsEight[g];
impvar NumUnassigned = sum {j in 1..n-1} Unassigned[j];
/* 1-unit increase in NumEights is more valuable than 8-unit decrease in NumUnassigned */
max Objective = 9 * NumEights - NumUnassigned;
con NumInGroupCon {j in 1..n-1}:
sum {g in GROUPS} NumInGroup[j,g] + Unassigned[j] = xsol[j,curr_sol];
con IsEightCon {g in GROUPS}:
sum {j in 1..n-1} j * NumInGroup[j,g] = 8 * IsEight[g];
str solstatus {1..nsol1};
num Ecnt {1..nsol1};
num Rcnt {1..nsol1};
num Jcnt {1..nsol1};
num count {1..nsol1};
/* independent problems, so can solve in parallel by using COFOR */
option nonotes;
cofor {s in 1..nsol1} do;
curr_sol = s;
solve;
solstatus[s] = _solution_status_;
Jcnt[s] = xsol[n,s];
Ecnt[s] = round(NumEights.sol + Jcnt[s]);
Rcnt[s] = round(sum {j in 1..n-1} Unassigned[j].sol);
count[s] = prod {j in 1..n} comb(Xub[j],xsol[j,s]);
end;
option notes;
create data out(drop=s) from [s]=(1..nsol1) solstatus
{j in 1..n} <col('X'||j)=xsol[j,s]>
Ecnt Rcnt Jcnt count;
quit;
proc freq data=out noprint;
table Ecnt*Rcnt*Jcnt / out=freqout(rename=(count=Freq));
weight count;
quit;
/* check that total is comb(66,8) */
proc sql;
select sum(Freq) format=best20., comb(66,8) format=best20. from freqout;
quit;
... View more