BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
RobPratt
SAS Super FREQ

Yes, that is a natural approach when one objective is more important than the other.  Here's how you can do it:

proc optmodel;
   set DIMS=1..2;
   set CUSTOMERS;
   set FACILITIES;
   num a {CUSTOMERS,DIMS};
   num demand {CUSTOMERS}; 

   num f {FACILITIES,DIMS};
   num SiteCapacity {FACILITIES};
   str FacilitySiteName {FACILITIES};

*   num p=60; /*Set how many Facilities you want to be OPENED*/

   read data /*ISURGCUS.*/COGcustomers into CUSTOMERS=
      [_N_] {d in DIMS} <a[_N_,d]=col('a'||d)> demand;

   read data /*ISURGCUS.*/cogExistingFacilities into FACILITIES=
      [_N_] {d in DIMS} <f[_N_,d]=col('f'||d)>FacilitySiteName;

   str SiteState{CUSTOMERS};
   read data /*ISURGCUS.*/COGcustomers into CUSTOMERS=
      [_N_] {d in DIMS} <a[_N_,d]=col('a'||d)> SiteState ;

   /* distance from customer i to facility j */
   num dist {i in CUSTOMERS, j in FACILITIES}
      = GEODIST(a[i,1],a[i,2],f[j,1],f[j,2],'M');

   set CUSTOMERS_FACILITIES = {i in CUSTOMERS, j in FACILITIES: dist[i,j] <= 120};
   var Assign {CUSTOMERS_FACILITIES} binary;
   var Build {FACILITIES} binary;

   /* each customer assigned to exactly one site */
   con assign_def {i in CUSTOMERS}:
      sum {<(i),j> in CUSTOMERS_FACILITIES} Assign[i,j] = 1;

   /* if customer i assigned to site j, then facility must be built at j */
   con link {<i,j> in CUSTOMERS_FACILITIES}:
      Assign[i,j] <= Build[j];

   min NumBuild = Sum{j in FACILITIES} Build[j];
   solve;

   num p;
   p = NumBuild;
   con Have_This_Many_FAC_OPEN:
      NumBuild <= p;

   min Cost
      = sum {<i,j> in CUSTOMERS_FACILITIES} dist[i,j] * Assign[i,j]*demand[i];
   solve with milp / primalin;
quit;
Santha
Pyrite | Level 9

Rob

this is awesome. I was so glad that i was also on the same path coding. It worked perfectly fine the way I wanted to.

Thank you. You are simply amazing

 

RobPratt
SAS Super FREQ

No, the MILP solver optimizes only one objective at a time.  The black-box solver can handle multiple objectives, but with no guarantee of optimality.  See this doc example: SAS Help Center: Multiobjective Optimization

Santha
Pyrite | Level 9

Hi Rob

For the same model in this thread, I tried to do this and got "Out of memory" error

set CUSTOMERS_FACILITIES = {i in CUSTOMERS, j in FACILITIES: dist[i,j] <= 120};

what i want to do is for the model to pick exactly 2 facilities from a pool of candidate facilities. 

So in order to do that I set this radius as like a big number like 3000 miles so that there model would solve. It gave me out of memory error. I understand that as giving a radius of 3000 miles means almost all possible combinations of faciliy- customer points. I tried to reduce that number to a point where it is like 550 or 600 then the model would not give me this "out of memory" error. But it would say infeasible which is understandable. So, how do i set this radius which I am using to pre_pick this CUSOMER_FACILITIES list within a certain range and yet solve this p number of facilities problem

 

RobPratt
SAS Super FREQ

You can use the following statement to determine the smallest feasible distance threshold:

   num threshold = min {j1 in FACILITIES, j2 in FACILITIES: j1 < j2} max {i in CUSTOMERS} min(dist[i,j1], dist[i,j2]);

This threshold value turns out to be 1018.4387857.  Now use threshold in the SET statement:

   set CUSTOMERS_FACILITIES = {i in CUSTOMERS, j in FACILITIES: dist[i,j] <= threshold};

The resulting solution has optimal objective value 375267751.16.

Santha
Pyrite | Level 9

Rob

Thank you I tried it the threshold radius that you recommended. That is a great idea. thank you . I get out of memory still. Here are my data sets. Not sure if it is the same that you may have. can u try if u get the same issue or were u able to solve. 

 

Santha
Pyrite | Level 9

here is the code that i used

proc optmodel;
set DIMS=1..2;
set CUSTOMERS;
set FACILITIES;
num a {CUSTOMERS,DIMS};
num demand {CUSTOMERS}; 

num f {FACILITIES,DIMS};
num SiteCapacity {FACILITIES};
str FacilitySiteName {FACILITIES};


num p=2; /*Set how many Facilities you want to be OPENED*/

read data ISURGCUS.COGcustomers into CUSTOMERS=
[_N_] {d in DIMS} <a[_N_,d]=col('a'||d)> demand;


read data ISURGCUS.cogExistingFacilities into FACILITIES=
[_N_] {d in DIMS} <f[_N_,d]=col('f'||d)>FacilitySiteName;

str SiteState{CUSTOMERS};
read data ISURGCUS.COGcustomers into CUSTOMERS=
[_N_] {d in DIMS} <a[_N_,d]=col('a'||d)> SiteState ;

/* distance from customer i to facility j */
   num dist {i in CUSTOMERS, j in FACILITIES}
       = GEODIST(a[i,1],a[i,2],f[j,1],f[j,2],'M');

num threshold_radius=
min {j1 in FACILITIES, j2 in FACILITIES: j1 < j2} max {i in CUSTOMERS} min(dist[i,j1], dist[i,j2]);

set CUSTOMERS_FACILITIES = {i in CUSTOMERS, j in FACILITIES: dist[i,j] <= threshold_radius};
var Assign {CUSTOMERS_FACILITIES} binary;
var Build {FACILITIES} binary;

   
   /* each customer assigned to exactly one site */
   con assign_def {i in CUSTOMERS}:
      sum {<(i),j> in CUSTOMERS_FACILITIES} Assign[i,j] = 1;

   /* if customer i assigned to site j, then facility must be built at j */
   con link {<i,j> in CUSTOMERS_FACILITIES}:
      Assign[i,j] <= Build[j];

con  Have_This_Many_FAC_OPEN:  Sum{j in FACILITIES} Build[j] <=p;
min Cost = sum {<i,j> in CUSTOMERS_FACILITIES} dist[i,j] * Assign[i,j]*demand[i];

solve with milp / primalin;

RobPratt
SAS Super FREQ

With your new data, I get threshold=911.79165962.  Here is the resulting solver log:

NOTE: Problem generation will use 4 threads.
NOTE: The problem has 222881 variables (0 free, 0 fixed).
NOTE: The problem has 222881 binary and 0 integer variables.
NOTE: The problem has 223526 linear constraints (222470 LE, 1056 EQ, 0 GE, 0 range).
NOTE: The problem has 667819 linear constraint coefficients.
NOTE: The problem has 0 nonlinear constraints (0 LE, 0 EQ, 0 GE, 0 range).
NOTE: The OPTMODEL presolver is disabled for linear problems.
NOTE: The initial MILP heuristics are applied.
NOTE: The MILP presolver value AUTOMATIC is applied.
NOTE: The MILP presolver removed 4 variables and 0 constraints.
NOTE: The MILP presolver removed 4 constraint coefficients.
NOTE: The MILP presolver modified 0 constraint coefficients.
NOTE: The presolved problem has 222877 variables, 223526 constraints, and 667815 constraint
      coefficients.
NOTE: The MILP solver is called.
NOTE: The parallel Branch and Cut algorithm is used.
NOTE: The Branch and Cut algorithm is using up to 4 threads.
          Node   Active   Sols    BestInteger      BestBound      Gap    Time
             0        1      1      315481339      315481339    0.00%     102
             0        0      1      315481339      315481339    0.00%     102
NOTE: Optimal.
NOTE: Objective = 315481338.73.
71   quit;
NOTE: PROCEDURE OPTMODEL used (Total process time):
      real time           2:56.77
      cpu time            2:43.81

Santha
Pyrite | Level 9

oh i dont understand why it does not solve for me then. 

RobPratt
SAS Super FREQ

I was using -MEMSIZE 16G, but option fullstimer shows that much less memory (slightly more than 2G) was used:

 

NOTE: PROCEDURE OPTMODEL used (Total process time):
      real time           2:47.68
      user cpu time       2:46.68
      system cpu time     1.92 seconds
      memory              2062201.62k
      OS Memory           2083180.00k
      Timestamp           08/27/2021 05:46:59 PM
      Step Count                        5  Switch Count  15
Santha
Pyrite | Level 9
Problem generation will use 4 threads.
NOTE: The problem has 300092 variables (0 free, 0 fixed).
NOTE: The problem has 300092 binary and 0 integer variables.
NOTE: The problem has 301161 linear constraints (299681 LE, 1480 EQ, 0 GE, 0 range).
NOTE: The problem has 899452 linear constraint coefficients.
NOTE: The problem has 0 nonlinear constraints (0 LE, 0 EQ, 0 GE, 0 range).
NOTE: The row activity (0) of constraint assign_def[1] violates its lower bound (1).
NOTE: The input solution is infeasible or incomplete. Repair heuristics are applied.
NOTE: The initial MILP heuristics are applied.
NOTE: The MILP presolver value AUTOMATIC is applied.
NOTE: The MILP presolver removed 4 variables and 0 constraints.
NOTE: The MILP presolver removed 4 constraint coefficients.
NOTE: The MILP presolver modified 0 constraint coefficients.
NOTE: The presolved problem has 300088 variables, 301161 constraints, and 899448 constraint coefficients.
NOTE: The MILP solver is called.
NOTE: The parallel Branch and Cut algorithm is used.
NOTE: The Branch and Cut algorithm is using up to 4 threads.
ERROR: Out of memory.
NOTE: No integer solutions found.
183
RobPratt
SAS Super FREQ

We are somehow solving different problems.  Please show your whole PROC OPTMODEL log.

Santha
Pyrite | Level 9
proc optmodel;
121  set DIMS=1..2;
122  set CUSTOMERS;
123  set FACILITIES;
124  num a {CUSTOMERS,DIMS};
125  num demand {CUSTOMERS};
126  
127  num f {FACILITIES,DIMS};
128  num SiteCapacity {FACILITIES};
129  str FacilitySiteName {FACILITIES};
130  
131  
132  num p=2;
132!          /*Set how many Facilities you want to be OPENED*/
133  
134  read data ISURGCUS.COGcustomers into CUSTOMERS=
135  [_N_] {d in DIMS} <a[_N_,d]=col('a'||d)> demand;
NOTE: There were 1480 observations read from the data set ISURGCUS.COGCUSTOMERS.
136  
137  
138  read data ISURGCUS.cogExistingFacilities into FACILITIES=
139  [_N_] {d in DIMS} <f[_N_,d]=col('f'||d)>FacilitySiteName;
NOTE: There were 412 observations read from the data set ISURGCUS.COGEXISTINGFACILITIES.
140  
141  str SiteState{CUSTOMERS};
142  read data ISURGCUS.COGcustomers into CUSTOMERS=
143  [_N_] {d in DIMS} <a[_N_,d]=col('a'||d)> SiteState ;
NOTE: There were 1480 observations read from the data set ISURGCUS.COGCUSTOMERS.
144  
145  /*str SiteRegion{CUSTOMERS};
146  read data STDOPT.COGMODELINGDATA intP CUSTOMERS=
147  [_N_] {d in DIMS} <a[_N_,d]=col('a'||d)> SiteRegion ;
148  
149  str SiteComment1{CUSTOMERS};
150  read data STDOPT.COGMODELINGDATA into CUSTOMERS=
151  [_N_] {d in DIMS} <a[_N_,d]=col('a'||d)> SiteComment1;*/
152  
153  
154  /* distance from customer i to facility j */
155     num dist {i in CUSTOMERS, j in FACILITIES}
156         = GEODIST(a[i,1],a[i,2],f[j,1],f[j,2],'M');
157  
158  num threshold_radius=
159  min {j1 in FACILITIES, j2 in FACILITIES: j1 < j2} max {i in CUSTOMERS} min(dist[i,j1], dist[i,j2]);
160  
161  set CUSTOMERS_FACILITIES = {i in CUSTOMERS, j in FACILITIES: dist[i,j] <= 911.79165962};
162  var Assign {CUSTOMERS_FACILITIES} binary;
163  var Build {FACILITIES} binary;
164  
165  
166     /* each customer assigned to exactly one site */
167     con assign_def {i in CUSTOMERS}:
168        sum {<(i),j> in CUSTOMERS_FACILITIES} Assign[i,j] = 1;
169  
170     /* if customer i assigned to site j, then facility must be built at j */
171     con link {<i,j> in CUSTOMERS_FACILITIES}:
172        Assign[i,j] <= Build[j];
173  
174     /* each site can handle at most &SiteCapacity demand */
175  /*con capacity {j in FACILITIES}:
176        sum {<i,(j)> in CUSTOMERS_FACILITIES} demand[i] * Assign[i,j] <=
177           SiteCapacity[j] * Build[j];*/
178  
179  con  Have_This_Many_FAC_OPEN:  Sum{j in FACILITIES} Build[j] <=p;
180  min Cost = sum {<i,j> in CUSTOMERS_FACILITIES} dist[i,j] * Assign[i,j]*demand[i];
181  
182  solve with milp / primalin;
NOTE: Problem generation will use 4 threads.
NOTE: The problem has 300092 variables (0 free, 0 fixed).
NOTE: The problem has 300092 binary and 0 integer variables.
NOTE: The problem has 301161 linear constraints (299681 LE, 1480 EQ, 0 GE, 0 range).
NOTE: The problem has 899452 linear constraint coefficients.
NOTE: The problem has 0 nonlinear constraints (0 LE, 0 EQ, 0 GE, 0 range).
NOTE: The row activity (0) of constraint assign_def[1] violates its lower bound (1).
NOTE: The input solution is infeasible or incomplete. Repair heuristics are applied.
NOTE: The initial MILP heuristics are applied.
NOTE: The MILP presolver value AUTOMATIC is applied.
NOTE: The MILP presolver removed 4 variables and 0 constraints.
NOTE: The MILP presolver removed 4 constraint coefficients.
NOTE: The MILP presolver modified 0 constraint coefficients.
NOTE: The presolved problem has 300088 variables, 301161 constraints, and 899448 constraint coefficients.
NOTE: The MILP solver is called.
NOTE: The parallel Branch and Cut algorithm is used.
NOTE: The Branch and Cut algorithm is using up to 4 threads.
ERROR: Out of memory.
NOTE: No integer solutions found.
183  
Santha
Pyrite | Level 9
the above code is what used. i hard coded the threshold_radius wiht 911. but earlier i used the actual threshold radius . both resulted in out ouf memory
RobPratt
SAS Super FREQ

The CUST.xlsx you attached has 1056 customers, but your log shows 1480 customers.

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
  • 32 replies
  • 1625 views
  • 0 likes
  • 2 in conversation