Lindo Systems

MODEL:
! 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; 
 SETS:
  BLOCK: VALUE;
  YR: VSHORT, VOVER;
  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;
 ENDSETS
 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.;