! Mining sequencing problem (dunbrmin);
! Problem:  Which blocks to mine each year so we are
   within yearly capacity, produce a steady flow of
   useable material(e.g., precious metal), and 
   satisfy removal precedence constraints;
! Keywords: Mining, Scheduling, Multi-period, Precedence constraints
   Smoothing, Open pit mine, Open cast mine; 
  BXY( BLOCK, YR): Y, ! Y(b,t)=1 if block b removed in year t;
                   W; ! W(b,t)=1 if block b removed in t or earlier;
  BXB( BLOCK, BLOCK); ! Need pairs of blocks for precedences;
DATA: ! Yearly target for value removed; YTARG = 15; ! Penalty/unit short of target in each year; PENUN = 10; ! Penalty/unit over of target in each year; PENOV = 4; ! Capacity/year in blocks removed; YCAP = 3; ! The years; YR = Y0 Y1 Y2 Y3 Y4 Y5 Y6 ; ! The individual blocks and their value; BLOCK = B11 B12 B13 B14 B15 B16 B21 B22 B23 B31 B32 B41 B42 B51 B52 B61 B62 B71 B81 ; VALUE = 0 0 1 20 1 1 12 2 3 9 8 1 12 0 1 11 5 4 20; ! Graphically, the blocks are arranged vertically as follows: B11 B12 B13 B14 B15 B16 \ | \/ | / \ / B21 B22 B23 \ / | B31 B32 | | B41 B42 | | B51 B52 \ / | B61 B62 \ / B71 | B81 ; ! Precedence pairs. Must do 1st block of pair in same or earlier period than 2nd block. The comma is used as an optional/cosmetic separator for each ordered pair; BXB = B11,B21 B12,B21 B13,B21 B12,B22 B13,B22 B14,B22 B15,B23 B16,B23 B21,B31 B22,B31 B23,B32 B31,B41 B32,B42 B41,B51 B42,B52 B51,B61 B52,B61 B52,B62 B61,B71 B62,B71 B71,B81; ENDDATA ! Minimize the cost of shortfalls over planning horizon; MIN = @SUM( YR(t): PENUN * VSHORT(t) + PENOV* VOVER(t)); ! For each year t; @FOR( YR( t): ! Compute yearly short fall or overage; [TARG] VSHORT( t) - VOVER(t) = YTARG - @SUM( BLOCK( b): VALUE( b)* Y( b, t)); ! Enforce capacity each year; [CAPY] @SUM( BLOCK( b): Y( b, t)) <= YCAP; ); @FOR( BLOCK(b): ! W(b,t)=1 if block b removed in year t or earlier; [DEFW1] W(b,1) = Y(b,1); @FOR( BXY(b,t) | t #GT# 1: [DEFW] W(b,t) = W(b,t-1) + Y(b,t); ); ); ! Precedence constraints. Tight version. For each precedence pair BXB(b,b1)...; @FOR( BXB(b,b1): @FOR( YR(t): ! If block b1 removed in year t or earlier, then block b must be removed in t or earlier; [PREC] W(b1,t) <= W(b,t); ); ); ! A block can be removed at most once; @FOR( BLOCK( b): [ONCE] @SUM( YR( t): Y( b, t)) <= 1; ); ! You either do the block or you do not; @FOR( BXY( b, t): @BIN( Y( b, t));); ! Complications not considered here: Target value and capacity may vary from year to year. Work required to remove a block may vary among blocks. There may be a distinct removal cost for each block. Time value of money may be important. Precedence relations may be more complicated.;