! Small bucket production sequencing with changeovers (prodseqk);
! Minimize the sum of setup plus inventory costs
  for producing multiple products on a single
  machine over multiple periods,
    Subject to:
     At most one product in a time period( the small bucket feature),
     Upper limit on amount produced in a period,
     No backlogging of demand; 
! Keywords: Changeover costs, lot sizing, scheduling, sequencing,
   production scheduling, ;
SETS:
 prod: iinv, ci, insetup;
 timep;
 pxt(prod,timep): dem, inv, x, z;
 pxp( prod, prod): cs;
 pxpxt( pxp, timep): y;
ENDSETS
DATA: ! The products; prod = A B C D E F G H I J K; ! How many machines producing which product at beginning; insetup= 1 0 0 0 0 0 0 0 0 0 0; ! Initial inventory; iinv = 0 2 9 8 6 7 8 3 7 9 8; ! Inventory cost for each product per period; ci = 3 2 2 1 2 4 2 1 1 2 1; ! The time periods; timep = 1..20; ! Changeover cost for each product pair; cs = ! A B C D E F G H I J K; !A; 0 1 2 1 1 3 1 2 1 1 3 !B; 9 0 1 3 1 1 1 1 1 1 1 !C; 8 6 0 1 1 1 1 3 1 1 2 !D; 9 9 9 0 1 1 1 1 1 1 1 !E; 8 9 9 9 0 1 1 1 3 1 3 !F; 9 7 9 9 9 0 1 1 1 1 1 !G; 9 9 9 9 9 9 0 1 1 1 1 !H; 9 9 9 9 9 9 9 0 1 1 1 !I; 9 9 9 9 9 9 9 9 0 1 1 !J; 9 9 9 9 9 9 9 9 9 0 1 !K; 7 9 6 9 9 7 9 9 8 9 0 ; ! Demands for each product(row)and period(col); ! 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20; dem = !A; 0 0 7 0 5 0 1 0 0 0 0 0 0 0 1 1 0 0 0 0 !B; 0 0 2 0 1 0 0 0 0 0 0 2 0 0 0 0 7 0 0 0 !C; 0 0 1 0 1 0 2 0 0 0 0 0 0 0 1 0 0 1 0 0 !D; 0 0 0 0 0 0 0 1 0 1 0 1 0 0 0 3 0 0 0 1 !E; 0 0 0 0 2 0 0 3 0 0 1 0 0 0 0 1 1 0 0 1 !F; 0 0 0 0 0 0 0 0 0 0 9 3 0 0 8 3 0 0 0 0 !G; 0 0 1 0 0 3 0 0 1 0 1 2 0 1 8 0 0 0 0 0 !H; 0 0 0 0 0 1 0 2 0 1 1 0 0 0 0 1 0 0 0 0 !I; 3 0 0 0 1 1 0 0 0 0 0 0 0 3 0 0 0 0 0 0 !J; 0 0 2 4 0 2 1 0 0 0 0 0 0 7 0 0 0 0 1 0 !K; 1 0 0 4 1 0 0 0 0 0 0 0 8 7 6 0 0 0 0 0 ; ! Production capacity per period. All products measured in same units; caplim = 11; ENDDATA SUBMODEL SCHED: ! Definitions: y( i, j, t)= 1 if machine is changed from i to j at end of time period t. x( i, t) = amount produced of product i in period t, z( i, t) = 1 if machine produces (or is capable of) product i during period t; ! Minimize the sum over all periods of the cost of changeovers + inventory; MIN = CCOST + ICOST; CCOST = @SUM( pxpxt(i,j,t): cs(i,j)*y(i,j,t)); ICOST = @SUM( pxt(i,t): ci(i)*inv(i,t)); ! Which product is being produced initially, and if setup for k, must change to some j at end of period; @FOR( prod( k): z( k, 1) = insetup( k); z( k, 1) = @SUM( prod( j): y( k, j, 1); ); ! If we changed from k to some j at the end of s, we had to change from some i to k at end of s-1; @FOR( pxt( k, s)| s #GT# 1: z( k, s) = @SUM( prod( i): y( i, k, s-1)); z( k, s) = @SUM( prod( j): y( k, j, s)); ); ! Setups must be 0 or 1; @FOR( pxt( i, s): @BIN( z( i, s)) ); ! If we produce product i in period s, the machine must be in product i mode in period s. An upper limit on production is total demand of product; @FOR( pxt( i, s): x( i, s) <= @SMIN( caplim, @SUM( timep( t) | t #GE# s: dem( i, t)))* z( i, s) ); ); ! Inventory at end of period 1; @FOR( prod(i): [IEND1] inv( i, 1) = iinv( i) + x( i, 1) - dem( i, 1); ); ! and subsequent periods; ! Compute ending inventory in each period; @FOR( pxt( i, s)| s #gt# 1: [IEND] inv( i, s) = inv( i, s-1) + x( i, s) - dem( i, s); ); ! Production capacity constraints; @FOR( timep( t): @SUM( prod( i): x( i, t)) <= caplim; ); ENDSUBMODEL
CALC: ! Turn off default output; @SET("TERSEO", 2); ! Set relative optimality tolerance; @SET("IPTOLR", .015); ! Time in seconds at which to apply rel tolerance; @SET("TIM2RL", 30); @SOLVE(SCHED); ! Produce a little report; @WRITE(@NEWLINE(2),'Inventory cost = ',@FORMAT(ICOST,"9.2f"), @NEWLINE(1)); @WRITE( 'Changeover costs= ',@FORMAT(CCOST,"9.2f"), @NEWLINE(1)); @WRITE( 'Total costs = ',@FORMAT(ICOST+CCOST,"9.2f"), @NEWLINE(1)); @WRITE(@NEWLINE(1),' Period Product Production', @NEWLINE(1)); @FOR(timep(s): @WRITE(' ',@FORMAT(s,"2.0f"),' '); @FOR(prod(j) | z(j,s) #GT# .5: @WRITE(prod(j),' ',@FORMAT(@ABS(x(j,s)),"8.1f"),@NEWLINE(1))); ); ENDCALC