1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150
|
/* Food Manufacture 2, section 12.2 in
* Williams, "Model Building in Mathematical Programming"
*
* Sebastian Nowozin <nowozin@gmail.com>
*/
set oils;
set month;
/* Buying prices of the raw oils in the next six month. */
param buyingprices{month,oils};
/* Actual amount bought in each month. */
var buys{month,oils} >= 0;
/* Stock for each oil. */
var stock{month,oils} >= 0;
/* Price of the produced product */
param productprice >= 0;
param storagecost;
param oilhardness{oils} >= 0;
param M >= 0;
/* Actual amount of output oil produced in each month */
var production{m in month} >= 0;
var useoil{m in month, o in oils} >= 0, <= M;
var useoilb{m in month, o in oils}, binary;
maximize totalprofit:
sum{m in month} productprice*production[m]
- sum{m in month, o in oils} buyingprices[m,o]*buys[m,o]
- sum{m in month, o in oils} storagecost*stock[m,o];
/* Constraints */
/* 1. Starting stock */
s.t. startstock{o in oils}:
stock[1,o] = 500;
s.t. endstock{o in oils}:
stock[6,o] + buys[6,o] - useoil[6,o] >= 500;
/* 2. Stock constraints */
s.t. stocklimit{m in month, o in oils}:
stock[m,o] <= 1000;
s.t. production1{m in month, o in oils}:
useoil[m,o] <= stock[m,o] + buys[m,o];
s.t. production2{m1 in month, m2 in month, o in oils : m2 = m1+1}:
stock[m2,o] = stock[m1,o] + buys[m1,o] - useoil[m1,o];
s.t. production3a{m in month}:
sum{o in oils} oilhardness[o]*useoil[m,o] >= 3*production[m];
s.t. production3b{m in month}:
sum{o in oils} oilhardness[o]*useoil[m,o] <= 6*production[m];
s.t. production4{m in month}:
production[m] = sum{o in oils} useoil[m,o];
/* 3. Refining constraints */
s.t. refine1{m in month}:
useoil[m,"VEG1"]+useoil[m,"VEG2"] <= 200;
s.t. refine2{m in month}:
useoil[m,"OIL1"]+useoil[m,"OIL2"]+useoil[m,"OIL3"] <= 250;
/* 4. Additional conditions:
* i) The food may never be made up of more than three oils every month
*/
s.t. useoilb_calc{m in month, o in oils}:
M*useoilb[m,o] >= useoil[m,o];
s.t. useoilb_limit{m in month}:
sum{o in oils} useoilb[m,o] <= 3;
/* ii) If an oil is used in a month, at least 20 tons must be used.
*/
s.t. useminimum{m in month, o in oils}:
20*useoilb[m,o] <= useoil[m,o];
/* iii) If either of VEG1 or VEG2 is used in a month, OIL2 must also be used
*/
s.t. use_oil2a{m in month}:
useoilb[m,"VEG1"] <= useoilb[m,"OIL3"];
s.t. use_oil2b{m in month}:
useoilb[m,"VEG2"] <= useoilb[m,"OIL3"];
solve;
for {m in month} {
printf "Month %d\n", m;
printf "PRODUCE %4.2f tons, hardness %4.2f\n", production[m],
(sum{o in oils} oilhardness[o]*useoil[m,o]) / (sum{o in oils} useoil[m,o]);
printf "\tVEG1\tVEG2\tOIL1\tOIL2\tOIL3\n";
printf "STOCK";
printf "%d", m;
for {o in oils} {
printf "\t%4.2f", stock[m,o];
}
printf "\nBUY";
for {o in oils} {
printf "\t%4.2f", buys[m,o];
}
printf "\nUSE";
printf "%d", m;
for {o in oils} {
printf "\t%4.2f", useoil[m,o];
}
printf "\n";
printf "\n";
}
printf "Total profit: %4.2f\n",
(sum{m in month} productprice*production[m]
- sum{m in month, o in oils} buyingprices[m,o]*buys[m,o]
- sum{m in month, o in oils} storagecost*stock[m,o]);
printf " turnover: %4.2f\n",
sum{m in month} productprice*production[m];
printf " buying costs: %4.2f\n",
sum{m in month, o in oils} buyingprices[m,o]*buys[m,o];
printf " storage costs: %4.2f\n",
sum{m in month, o in oils} storagecost*stock[m,o];
data;
param : oils : oilhardness :=
VEG1 8.8
VEG2 6.1
OIL1 2.0
OIL2 4.2
OIL3 5.0 ;
set month := 1 2 3 4 5 6;
param buyingprices
: VEG1 VEG2 OIL1 OIL2 OIL3 :=
1 110 120 130 110 115
2 130 130 110 90 115
3 110 140 130 100 95
4 120 110 120 120 125
5 100 120 150 110 105
6 90 100 140 80 135 ;
param productprice := 150;
param storagecost := 5;
param M := 1000;
end;
|