openpit.gms : Dynamic open pit mining extraction

**Description**

This is an example of how to model material extractions that have sequencing requirements with a multi-period decision process. A segment has to be extracted completely before we can start on the next segment. Segments not completely extracted have to be extracted in the next time period or remain partially extracted in the last time period. The requirement of full extraction adds complications to the modeling within the multi-period framework.

**Reference**

- GAMS Development Corporation, Formulation and Language Example.

**Large Model of Type :** MIP

**Category :** GAMS Model library

**Main file :** openpit.gms

```
$title Dynamic Open Pit Mining Extraction (OPENPIT,SEQ=309)
$onText
This is an example of how to model material extractions that
have sequencing requirements with a multi-period decision process.
A segment has to be extracted completely before we can start on
the next segment. Segments not completely extracted have to be
extracted in the next time period or remain partially extracted in
the last time period. The requirement of full extraction adds
complications to the modeling within the multi-period framework.
Reference: GAMS Development Corporation, Formulation and Language
Example.
Keywords: mixed integer linear programming, open pit mining, multi-period scheduling
$offText
$if not set tmx $set tmx 4
$if not set smx $set smx 50
$if not set pmx $set pmx 4
Set
t 'extraction periods' / t1*t%tmx% /
s 'extraction segments' / s1*s%smx% /
p 'pits' / p1*p%pmx% /;
Parameter
nev(p,s) 'net extraction benefit'
evo(p,s) 'extraction volume'
demand(t) 'product demand'
rho 'discount rate'
delta(t) 'discount factor'
fix(p) 'offset for random value'
var(p) 'var for random values';
* produce random input data with differing net benefit profiles
fix(p) = uniform(-1,+1);
var(p) = -sign(fix(p))*uniform(1,5);
nev(p,s) = (fix(p) + var(p)/card(s)*(ord(s) - 1));
evo(p,s) = uniform(.1,1);
* set demand to 70 percent of total resource
demand(t) = sum((p,s), evo(p,s))*0.7/card(t);
rho = 0.1;
delta(t) = power(1 + rho,1 - ord(t));
Binary Variable
b(p,s,t) 'segment can be extracted'
e(p,s,t) 'last extracted segment and start'
open(p,s) 'segments activated';
Integer Variable
ej(p,t) 'period of last segment';
Positive Variable
out(p,s,t) 'extraction level'
pout(p,t) 'pit output';
Variable
obj 'total discounted net income';
Equation
eone(p,t) 'extraction sequence ends only once'
etwo(p,t) 'extraction ending sequence'
ethree(p,t) 'sequencing of end start'
opendef(p,s,t) 'set open to one'
openlow(p,s) 'set open to zero'
brun(p,s,t) 'define staircase for B'
defpout(p,t) 'define pit output'
dem(t) 'total demand'
outlim(p,s,t) 'extraction limit'
outmax(p,s) 'total extraction limit'
outall(p,s) 'force complete extraction except last one'
defobj;
eone(p,t).. sum(s, e(p,s,t)) =e= 1;
etwo(p,t).. ej(p,t) =e= sum(s, ord(s)*e(p,s,t));
ethree(p,t-1).. ej(p,t-1) =l= ej(p,t);
brun(p,s,t).. b(p,s,t) =e= b(p,s-1,t) - e(p,s-1,t) + e(p,s,t-1) + (ord(t) = 1 and ord(s) = 1);
defpout(p,t).. pout(p,t) =e= sum(s, out(p,s,t));
dem(t).. sum(p, pout(p,t)) =e= demand(t);
opendef(p,s,t).. open(p,s) =g= b(p,s,t);
openlow(p,s).. open(p,s) =l= sum(t, b(p,s,t));
outlim(p,s,t).. out(p,s,t) =l= evo(p,s)*b(p,s,t);
outall(p,s).. sum(t, out(p,s,t)) =g= evo(p,s)*open(p,s+1);
outmax(p,s).. sum(t, out(p,s,t)) =l= evo(p,s)*open(p,s);
defobj.. obj =e= sum((p,s,t), delta(t)*nev(p,s)*out(p,s,t));
Model extract / all /;
if(card(s)*card(p)*card(t) > 200,
option limRow = 0, limCol = 0, solPrint = off, optCr = 0.01;
else
option optCr = 0;
display evo, nev;
);
* limit single pit output to 80 percent of demand
pout.up(p,t) = 0.8*demand(t);
solve extract using mip max obj;
display ej.l, e.l, b.l, out.l, pout.l;
```