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;
... View more