I can't seem to come up with how to write this constraint. I have a list of possible facilities and a list of customers and all possible arcs between customers and facilities. I want a group of customers to be served by the same facility.
facilities: 1,2,3
customers: 1,2,3,4,5,6,7,8,9,10
customers will be assigned to the closest facility, but customers 2,3, and 4 need to be assigned to the same facility. This seems like it should be simple, but for some reason I cannot get it together.
If you have binary decision variables X[i,j] that indicate whether customer i is assigned to facility j, the desired constraints are X[2,j] = X[3,j] and X[2,j] = X[4,j] for all j.
If you have binary decision variables X[i,j] that indicate whether customer i is assigned to facility j, the desired constraints are X[2,j] = X[3,j] and X[2,j] = X[4,j] for all j.
Something like:
con group_con{<i,k> in ARCS2: i in {'1358063','1441229','1441227','1441288','1441275','1441272','1441271','1441267','1441259','1436770','1441256'} and k in {'377','378','379','400','401','402','403','404','405','406','407','408','409','413','414','417','418','425','426','427','471'}}:
Assign2[i,'377']=Assign2[i,k];
Your real-world use case might be more complex, but if your customer uid's iterate by 1 (e.g., 1..10), and consecutive customers need to be in the same facility (e.g., 2,3,4), this might work:
Below customers 1, 2, and 3 are forced into the same facility through the group_con constraint.
data arcs;
input customers facilities $ dist;
datalines;
1 F1 3
1 F2 2
1 F3 6
2 F1 1
2 F2 4
2 F3 2
3 F1 1
3 F2 2
3 F3 0
4 F1 3
4 F2 2
4 F3 1
5 F1 4
5 F2 1
5 F3 2
;
data force;
input customers;
datalines;
1
2
3
;
proc optmodel;
set <num,str> ARCS;
set CUSTOMERS = setof{<i,j> in ARCS} i;
set FACILITIES = setof{<i,j> in ARCS} j;
set <num> FORCE;
num dist{ARCS};
read data arcs into ARCS=[customers facilities] dist;
read data force into FORCE=[customers];
var Assign{ARCS} binary;
min TotalDistance = sum{<i,j> in ARCS} Assign[i,j]*dist[i,j];
/* each customer is assigned to only one facility */
con one_facility{c in CUSTOMERS}:
sum{f in FACILITIES} Assign[c,f] = 1;
/* customers in the FORCE set assigned to the same facility */
con group_con{i in FORCE,j in FACILITIES: i < card(FORCE)}:
Assign[i,j] = Assign[i+1,j];
solve;
print Assign;
quit;
Thanks for the idea. They may not be consecutive in this case.
In that case, the approach below groups customers into the same facility without requiring sequential ordering of the customer uid.
Without grouping, the model below assigns each customer to one of three facilities to minimize total distance.
data arcs;
input customers $ facilities $ dist;
datalines;
C1 F1 3
C1 F2 2
C1 F3 6
C2 F1 1
C2 F2 4
C2 F3 2
C3 F1 1
C3 F2 2
C3 F3 0
C4 F1 3
C4 F2 2
C4 F3 1
C5 F1 4
C5 F2 1
C5 F3 2
;
proc optmodel;
set <str,str> ARCS;
set CUSTOMERS = setof{<c,f> in ARCS} c;
set FACILITIES = setof{<c,f> in ARCS} f;
num dist{ARCS};
read data arcs into ARCS=[customers facilities] dist;
var Assign{ARCS} binary;
min TotalDistance = sum{<c,f> in ARCS} Assign[c,f] * dist[c,f];
/* each customer is assigned to only one facility */
con one_facility{c in CUSTOMERS}:
sum{f in FACILITIES} Assign[c,f] = 1;
solve;
print Assign;
quit;
The modifications below force customers C1 & C4 into the same group, and customers C3 & C5 into the same group.
data force;
input i $ j $;
datalines;
C1 C4
C3 C5
;
Inside of OPTMODEL, add:
set <str,str> FORCE;
read data force into FORCE=[i j];
var Group{FORCE,FACILITIES} binary;
con group_con1{<i,j> in FORCE, f in FACILITIES}:
Group[i,j,f] = Assign[i,f];
con group_con2{<i,j> in FORCE, f in FACILITIES}:
Group[i,j,f] = Assign[j,f];
Registration is now open for SAS Innovate 2025 , our biggest and most exciting global event of the year! Join us in Orlando, FL, May 6-9.
Sign up by Dec. 31 to get the 2024 rate of just $495.
Register now!
Learn how to run multiple linear regression models with and without interactions, presented by SAS user Alex Chaplin.
Find more tutorials on the SAS Users YouTube channel.