Here is my IML code. If your compute was good eough , change the following parameter as big as you can to make sure find the optimal solution.
niter = 10000;
NOTE: I highly strong recommend you to post this question at OR forum, Maybe there is some OR code offered by @RobPratt you can use , due to the fact GA can't guarantee you get the optimal solution for the sake of large scale problem.
data have;
infile cards expandtabs truncover;
input TableList : $20. PlayerList : $20. ScoreA ScoreB ScoreC ScoreD;
cards;
A_C_P_AC 12 4 8 12 16
R_AA_AB 17 3 6 9 12
B_F_G_K_L_O 3,4,11 18 36 54 72
S_T_U_V_AD 5,6 10 20 30 40
D_E_H_I_J_M_N 1,2,14 21 42 63 84
Y,Z 13,16 4 8 12 16
W,X 7,15 4 8 12 16
Q 8,9,10 3 6 9 12
;
run;
proc iml;
use have;
read all var _num_ into age[c=vname] ;
close ;
start function(x) global(age,group,nrow,ncol);
sum_group=j(group,ncol,0);
do i=1 to group;
do j=1 to nrow;
if x[j]=i then sum_group[i,]=sum_group[i,]+age[j,];
end;
end;
obj=sum(sum_group[<>,]-sum_group[><,]);
return (obj);
finish;
start switch_mut(s) global(nswitches);
n = ncol(s);
do i = 1 to nswitches;
k1 = int(uniform(123456789)*n) + 1;
k2 = int(uniform(123456789)*n) + 1;
if k1^=k2 then do;
temp=s[k2];
s[k2] = s[k1];
s[k1] = temp;
end;
end;
finish;
start uniform_cross(child1, child2, parent1, parent2) global(nrow);
child1 = parent1;
child2 = parent2;
do i = 1 to ncol(parent1);
r = uniform(123456789);
if r<0.5 then do;
child1[i] = parent2[i];
child2[i] = parent1[i];
end;
end;
finish;
ncol=ncol(age);
nrow=nrow(age);
obs=t(1:nrow);
group=4; /* <--Change it(divide into 4 groups)*/
nswitches = 4;
encoding=j(2,nrow,1);
encoding[2,]=group;
id=gasetup(2,nrow,123456789);
call gasetobj(id,0,"function");
call gasetcro(id,0.95,0,"uniform_cross");
call gasetmut(id,0.95,0,"switch_mut");
call gasetsel(id,100,1,1);
call gainit(id,1000,encoding);
niter = 10000;
do i = 1 to niter;
call garegen(id);
call gagetval(value, id);
end;
call gagetmem(mem, value, id, 1);
groups=t(mem);
create group var {groups};
append;
close;
print value[l = "Min Value:"] ;
call gaend(id);
quit;
data want;
merge group have;
run;
proc summary data=want nway;
class groups;
var _numeric_;
output out=sum(drop=_:) sum=;
run;
proc print noobs;run;
proc print data=want noobs;run;
This one could be faster. Same result with previous .
data have;
infile cards expandtabs truncover;
input TableList : $20. PlayerList : $20. ScoreA ScoreB ScoreC ScoreD;
cards;
A_C_P_AC 12 4 8 12 16
R_AA_AB 17 3 6 9 12
B_F_G_K_L_O 3,4,11 18 36 54 72
S_T_U_V_AD 5,6 10 20 30 40
D_E_H_I_J_M_N 1,2,14 21 42 63 84
Y,Z 13,16 4 8 12 16
W,X 7,15 4 8 12 16
Q 8,9,10 3 6 9 12
;
run;
proc iml;
use have;
read all var _num_ into age[c=vname] ;
close ;
start function(x) global(age,group,nrow,ncol);
sum_group=j(group,ncol,0);
do i=1 to group;
do j=1 to nrow;
if x[j]=i then sum_group[i,]=sum_group[i,]+age[j,];
end;
end;
obj=sum(sum_group[<>,]-sum_group[><,]);
return (obj);
finish;
ncol=ncol(age);
nrow=nrow(age);
group=4; /* <--Change it(divide into 4 groups)*/
encoding=j(2,nrow,1);
encoding[2,]=group;
id=gasetup(2,nrow,123456789);
call gasetobj(id,0,"function");
call gasetsel(id,100,1,1);
call gainit(id,1000,encoding);
niter = 10000;
do i = 1 to niter;
call garegen(id);
call gagetval(value, id);
end;
call gagetmem(mem, value, id, 1);
groups=t(mem);
create group var {groups};
append;
close;
print value[l = "Min Value:"] ;
call gaend(id);
quit;
data want;
merge group have;
run;
proc summary data=want nway ;
class groups;
var _numeric_;
output out=sum(drop=_:) sum=;
run;
proc print noobs;run;
proc print data=want noobs;run;
Hi KSharp,
I ran the code you sent and it works perfectly on the small sample dataset. I applied it to the the actual larger dataset and after 24 hours of contiuous running it still wasn't finished. Is there anything I can do that will make this run faster???
Thanks,
Krislynn
Can you post it at
https://communities.sas.com/t5/Mathematical-Optimi
@RobPratt is there , He maybe give you fast way.
About reducing time , you can change niter=10000 into a small number ,
But I don't recommend to do that because you may not find a best solution.
I advice to wait .
That is really odd.
Can you start a brand new sas session and run the code again ?
I would suggest retain that statement .
If you could accept OR code , I really suggest you post it at OR forum , and let Rob know .
How many obs do you have ? Maybe your number is too big to pass the limit of SAS.
Try following:
P.S. Better post some sample data to let us test it .
call gasetsel(id,10,1,1); /*10 <-- Change it smaller as possible*/
call gainit(id,100,encoding); /*10 <-- Change it smaller as possible
niter = 10000; /*<-- Change it bigger as possible to make sure find a optimal solution*/
Can you set the option -memsize 10G in the sas config file SASCFGV9 to make your memory size as bigger as it could be ?
OR Try this way:
After that you can check how much memory SAS have already used .
Can you explain where WEEK come from ?
Why some TableList have the same week ?
TableList | PlayerList | ScoreA | ScoreB | ScoreC | ScoreD | Total Samples | Week |
A_C_P_AC | 12 | 4 | 8 | 12 | 16 | 40 | Week2 |
R_AA_AB | 17 | 3 | 6 | 9 | 12 | 30 | Week2 |
B_F_G_K_L_O | 3,4,11 | 18 | 36 | 54 | 72 | 180 | Week1 |
S_T_U_V_AD | 5,6 | 10 | 20 | 30 | 40 | 100 | Week2 |
D_E_H_I_J_M_N | 1,2,14 | 21 | 42 | 63 | 84 | 210 | Week3 |
Y,Z | 13,16 | 4 | 8 | 12 | 16 | 40 | Week4 |
W,X | 7,15 | 4 | 8 | 12 | 16 | 40 | Week4 |
Q | 8,9,10 | 3 | 6 | 9 | 12 | 30 | Week4 |
SAS Innovate 2025 is scheduled for May 6-9 in Orlando, FL. Sign up to be first to learn about the agenda and registration!
Learn how use the CAT functions in SAS to join values from multiple variables into a single value.
Find more tutorials on the SAS Users YouTube channel.
Ready to level-up your skills? Choose your own adventure.