Please see if the following does what you want:
proc optmodel;
set <num,num> ORIGINS_DESTINATIONS;
read data have into ORIGINS_DESTINATIONS=[originid destinationid];
set ORIGINS;
num capacity {ORIGINS};
read data have into ORIGINS=[originid] capacity;
set DESTINATIONS;
num demand {DESTINATIONS};
read data have into DESTINATIONS=[destinationid] demand=pop10;
var IsOpen {ORIGINS} binary;
var Serve {ORIGINS_DESTINATIONS} binary;
con Cover {d in DESTINATIONS}:
sum {<o,(d)> in ORIGINS_DESTINATIONS} Serve[o,d] >= 1;
con CapacityCon {o in ORIGINS}:
sum {<(o),d> in ORIGINS_DESTINATIONS} demand[d] * Serve[o,d] <= capacity[o] * IsOpen[o];
/* primary objective: minimize number of open origins */
min NumOpen = sum {o in ORIGINS} IsOpen[o];
/* secondary objective: maximize total coverage of demands */
max TotalCoverage = sum {<o,d> in ORIGINS_DESTINATIONS} demand[d] * Serve[o,d];
solve obj NumOpen;
print NumOpen TotalCoverage;
print Serve;
print IsOpen {o in ORIGINS} (sum {<(o),d> in ORIGINS_DESTINATIONS} demand[d] * Serve[o,d]);
num minNumOpen;
minNumOpen = NumOpen.sol;
con ObjectiveCut:
NumOpen <= minNumOpen;
solve obj TotalCoverage;
print NumOpen TotalCoverage;
print Serve;
print IsOpen {o in ORIGINS} (sum {<(o),d> in ORIGINS_DESTINATIONS} demand[d] * Serve[o,d]);
quit;
NumOpen
TotalCoverage
2
41
Serve
1
2
3
4
1
1
1
2
0
1
1
3
0
0
4
0
0
[1]
IsOpen
1
1
20
2
1
21
3
0
0
4
0
0
... View more