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;
|