BookmarkSubscribeRSS Feed
☑ This topic is solved. Need further help from the community? Please sign in and ask a new question.
DanHouston
Obsidian | Level 7

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.

1 ACCEPTED SOLUTION

Accepted Solutions
RobPratt
SAS Super FREQ

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.

View solution in original post

6 REPLIES 6
RobPratt
SAS Super FREQ

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.

DanHouston
Obsidian | Level 7

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];
RobPratt
SAS Super FREQ
Yes, that looks correct if i is a facility and k is a customer. This constraint enforces Assign2[i,k] = 1 if and only if Assign2[i,’377’] = 1.
ChanceTGardener
SAS Employee

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;
DanHouston
Obsidian | Level 7

Thanks for the idea. They may not be consecutive in this case.

ChanceTGardener
SAS Employee

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];

 

 

Ready to join fellow brilliant minds for the SAS Hackathon?

Build your skills. Make connections. Enjoy creative freedom. Maybe change the world. Registration is now open through August 30th. Visit the SAS Hackathon homepage.

Register today!
Multiple Linear Regression in SAS

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.

Discussion stats
  • 6 replies
  • 967 views
  • 2 likes
  • 3 in conversation