Project OR
Project OR
Project OR
Let:
Variables in code:
Variable Name Interpretation
IsOpen[mine,year] 1 if mine is open in that year; 0 otherwise
IsWorked[mine,year] 1 if mine is worked in that year; 0 otherwise
Extract[mine,year] output from mine i in year t
ExtractedPerYear[year] quantity of blended ore produced in year t
Constraints:
xit - Miδit ≤ 0 for all i, t.
Where Mi is the maximum anually output from mine i.
These constraints mean that if mine i is not worked in year t there can be no output from it in that
year.
∑𝟒𝐢=𝟏 𝛅it ≤ 3 for all t.
This constraint requires no more than three mines to be worked in any year.
This constraint ensures that the tonnage of blended ore in each year equals the combined tonnage
of the constituents. There are five such constraints. In total there are 71 constraints.
Constraints in code:
- Bound on variables
- For year 𝜖 YEARS,
Extract[mine,year] ≤ Extract[mine,year].ub∙IsWorked[mine,year]
IsWorked[mine,year] ≤ IsOpen[mine,year]
A mining company is going to continue operating in a certain area for the next five years. There are four
mines in this area but it can operate at most three in any one year. Although a mine may not operate in a
certain year it is still necessary to keep it ‘open’, in the sense that royalties are payable, should it be
operated in a future year. Clearly if a mine is not going to be worked again it can be closed down
permanently and no more royalties need be paid. The yearly royalties payable on each mine kept ‘open’
are
Mine 1. £5 million
Mine 2. £4 million
Mine 3. £4 million
Mine 4. £5 million
There is an upper limit to the amount of ore which can be extracted from each mine in a year. These upper
limits are:
The ore from the different mines is of varying quality. This quality is measured on a scale so that blending
ores together results in a linear combination of the quality measurements, e.g. if equal quantities of two
ores were combined the resultant ore would have a quality measurement half way between that of the
ingredient ores. Measured in these units the qualities of the ores from the mines are given below:
Mine 1 1.0
Mine 2 0.7
Mine 3 1.5
Mine 4 0.5
In each year it is necessary to combine the total outputs from each mine to produce a blended ore of
exactly some stipulated quality. For each year these qualities are
Year 1 0.9
Year 2 0.8
Year 3 1.2
Year 4 0.6
Year 5 1.0
The final blended ore sells for £10 per ton each year. Revenue and expenditure for future years must be
discounted at a rate of 10% per annum.
Which mines should be operated each year and how much should they produce?
Objective:
The total profit consists of the income from selling the blended ore minus the royalties payable. This is to be
maximized. It can be written
Rit is the royalty payable on mine i in year t discounted at a rate of 10% per annum. I t is the selling price of each ton
of blended ore in year t discounted at a rate of 10% per annum. The advantage of this formulation of the problem
over an alternative one is discussed by Williams (1978).
There would seem to be advantage in this model in working mines early in the hope that they may be closed
permanently later. In addition, the dis- counting of revenue gives an advantage to working mines early. The
suggested solution strategy is therefore to branch on the variables δ it , giving priority to low values of t.
The objective is to maximize the following function, where TotalRevenue is a linear function of
ExtractedPerYear, and TotalCost is a linear function of isOpen:
Result
Coding
code.mod
int NbMines = ...;
range Mines = 1..NbMines;
maximize Objective;
subject to {
// Maximum yearly capacity
forall(m in Mines, y in Years)
ctMaxYearCap: Ore[m][y] <= LimExtract[m] * Work[m][y];
// Balance constraint
forall(y in Years)
ctBalance: sum(m in Mines) Ore[m][y] == Blend[y];
Work[2][3]==0;
Work[1][2]==0;
Work[2][1]==0;
Work[4][4]==1;
Work[4][3]==0;
Work[3][4]==0;
Work[4][5]==0;
}
tuple BlendSolutionT{
int Years;
float value;
};
{BlendSolutionT} BlendSolution = {<i0,Blend[i0]> | i0 in Years};
tuple OpenSolutionT{
int Mines;
int Years;
int value;
};
{OpenSolutionT} OpenSolution = {<i0,i1,Open[i0][i1]> | i0 in Mines,i1 in Years};
tuple OreSolutionT{
int Mines;
int Years;
float value;
};
{OreSolutionT} OreSolution = {<i0,i1,Ore[i0][i1]> | i0 in Mines,i1 in Years};
tuple WorkSolutionT{
int Mines;
int Years;
int value;
};
{WorkSolutionT} WorkSolution = {<i0,i1,Work[i0][i1]> | i0 in Mines,i1 in Years};
File .dat
NbMines = 4;
NbYears = 5;
// Units are millions of pounds for costs, millions of tons for ore
Royalties = [5 4 4 5];
LimExtract = [2 2.5 1.3 3];
LimWork = 3;
OreQual = [1.0 0.7 1.5 0.5];
BlendQual = [0.9 0.8 1.2 0.6 1.0];
BlendPrice = 10;
DiscountRate = 0.10;