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 |
Are you ready for the spotlight? We're accepting content ideas for SAS Innovate 2025 to be held May 6-9 in Orlando, FL. The call is open until September 25. Read more here about why you should contribute and what is in it for you!
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.