MODEL:
SETS:
! The set covering/packing problem (COVERPAK);
! Given a set of customers, a set of candidate facilities, 
   and the set of customers served by each facility,
   which facilities should be opened?;
!  Keywords: Covering / Logistics / Marketing / Network / Plant Location / Scheduling / Staff Scheduling / Airlines;

! Data based on the airline crew scheduling problem in
  "Optimization Modeling with LINGO";
 FACILITY/ 1..37/: COST, Y;
 CUST/ F101 F410 F220 F17 F7 F13 F11 F19 F23 F3/: CU, CV, U, V;
! The "facility serves customer" 2-tuples;
 FXC( FACILITY, CUST)/ 
  1,F101 2,F410 3,F220 4,F17 5,F7 6,F13 7,F11 8,F19 9,F23 10,F3
 11,F101 11,F23 12,F410 12,F13 13,F410 13,F19 14,F220 14,F17
 15,F220 15,F11 16,F17 16,F101 17,F7 17,F13 18,F7 18,F19 
 19,F11 19,F410 20,F19 20,F17 21,F19  21,F11 22,F23 22,F17
 23,F23 23,F11  24,F3  24,F23 25,F101 25,F23 25,F17 
 26,F101 26,F13 26,F11 27,F410 27,F19 27,F17
 28,F410 28,F19 28,F11 29,F220 29,F17 29,F101 30,F220 30,F11 30,F410
 31,F7 31,F19 31,F17 32,F7 32,F19 32,F11 33,F11 33,F410 
 34,F19 34,F17 34,F101 35,F23 35,F11 35,F410 36,F3 36,F23 36,F17
 37,F3 37,F23 37,F11
 /:;
ENDSETS
DATA:
!  Cost of each facility;
 COST = 3 3 3 3 3 3 3 3 3 3 3 2 3 3 2 3 3 3 3 2
        3 3 3 2 2 3 3 2 3 3 3 3 3 3 3 3 3;
! Cost/unit under at each customer;
  CU = 1 1 1 1 1 1 1 1 1 1;
! Cost/unit over at each customer;
  CV = 1 1 1 1 1 1 1 1 1 1;
! Max allowed to spend on facilities;
 BUDGET = 9999;
! Max allowed underage at each customer, 
     0 makes a covering problem;
  BUDU = 0;
! Max allowed overage at each customer, 
     0 makes it a packing problem;
  BUDV = 0;
! Both = 0 makes it a partitioning problem;
ENDDATA
!--------------------------------------------------------;
! Minimize cost of facilities opened, customers poorly served;
   MIN = @SUM( FACILITY( I): COST( I) * Y(I)) 
       + @SUM( CUST( J): CU( J) * U( J) + CV( J) * V( J));
! Can serve a customer only if a serving facility is open;
   @FOR( CUST( J):
      @SUM( FXC( I, J): Y( I)) + U( J) - V( J) = 1;    );
! Stay within budget on facilities cost;
   @SUM( FACILITY: COST * Y) <= BUDGET;
! and customer service costs;
   @SUM( CUST: CU * U) <= BUDU;
   @SUM( CUST: CV * V) <= BUDV;
! A facility is either open or it is not, no halfsies;
 @FOR( FACILITY( I): @BIN( Y( I)););
END
