I will anonymize the data. In what format do you want me to send?
Ideally, you can provide the three SAS data sets that appear in the READ DATA statements.
One file is too large to attach.
here are the 2 smaller files.
Even a zipped file (9.8MB) is still too large (limit 5Mb) to attach.
Can you zip the large one? Or include only the needed observations with PDStemTravelDistance <= MaxStemDist.
where PDStemTravelDistance <153 ;
Three customers do not appear in the zip file:
'C2819','C2820','C2821'
They were all exclude because they exceed the MaxStemDist.
where PDStemTravelDistance <153 ;
OK, then I will modify the set CUSTOMERS to exclude them because otherwise the problem is infeasible.
Is it important that Assign is binary, or is it possible to split a customer's demand among multiple facilities?
This is an operational requirement of assigning a customer to exactly one facility.
OK, the other post that I linked to allows fractional Assign values and also has CUSTOMERS = FACILITIES, so that approach does not directly apply.
For your data, I reduced the set of customers (by 3) to avoid infeasibility, as mentioned earlier:
CUSTOMERS = setof {<i,j> in CUSTOMERS_FACILITIES} i;
I used the sparse formulation (as in the "Sparse Modeling" documentation example) with only the Capacitated and SingleSource constraints:
var Assign {CUSTOMERS_FACILITIES} binary;
var Build {FACILITIES} binary;
/* declare implicit variables */
impvar Total_PDStemTravelCost = sum {<i,j> in CUSTOMERS_FACILITIES} PDStemTravelCost[i,j] * Assign[i,j];
impvar Total_FacOperCost = sum {j in FACILITIES} FacOperCost&cap.[j] * Build[j];
/******************************************************
Declare constraints on decision variables with CON
*******************************************************/
/* define constraint: sum of customer demands assigned to a facility must be less than the facility capacity */
con Capacitated {j in FACILITIES}:
sum {<i,(j)> in CUSTOMERS_FACILITIES} CustZipDemand[i] * Assign[i,j] <= FacCapacity&cap.[j] * Build[j];
/* define constraint: each customer is assigned to exactly one facility, all customers are assigned */
con SingleSource {i in CUSTOMERS}:
sum {<(i),j> in CUSTOMERS_FACILITIES} Assign[i,j] = 1;
With the following SOLVE statement, I got a 1% solution after 4.5 hours with SAS/OR 15.1 on my Windows laptop:
solve with milp / relobjgap=0.01 heuristics=aggressive;
Here are the last few lines of the iteration log:
554817 367415 205 1087826 1076877 1.02% 15785
554893 367453 205 1087826 1076877 1.02% 15790
557157 345573 206 1086185 1076877 0.86% 15793
NOTE: Optimal within relative gap.
NOTE: Objective = 1086185.2119.
Correction: that log was from a slower desktop. It took 3.5 hours to get to 1% gap on my laptop:
560186 405268 130 1088541 1077326 1.04% 12540
560498 405580 130 1088541 1077326 1.04% 12545
560792 405874 130 1088541 1077326 1.04% 12550
560880 401671 131 1087946 1077326 0.99% 12551
NOTE: Optimal within relative gap.
NOTE: Objective = 1087946.3943.
Glad to see your solution worked! I will try it and hopefully I will not get an "our of memory" as before. One thing, I am using SAS/OR 14.3 which is probably not as efficient as 15.1. Thanks again.
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.