1 # EGYPT, a static model of fertilizer production
4 # Robert Fourer, David M. Gay and Brian W. Kernighan, "A Modeling Language
5 # for Mathematical Programming." Management Science 36 (1990) 519-554.
9 set center; # Locations from which final product may be shipped
10 set port within center; # Locations at which imports can be received
11 set plant within center; # Locations of plants
13 set region; # Demand regions
15 set unit; # Productive units
20 set c_final; # Final products (fertilizers)
21 set c_inter; # Intermediate products
22 set c_ship within c_inter; # Intermediates for shipment
23 set c_raw; # Domestic raw materials and miscellaneous inputs
25 set commod := c_final union c_inter union c_raw;
31 param cf75 {region,c_final} >= 0;
33 # Consumption of fertilizer 1974-75 (1000 tpy)
35 param fn {c_final,nutr} >= 0;
37 # Nutrient content of fertilizers
39 param cn75 {r in region, n in nutr} := sum {c in c_final} cf75[r,c] * fn[c,n];
41 # Consumption of nutrients 1974-75 (1000 tpy)
43 param road {region,center} >= 0;
47 param rail_half {plant,plant} >= 0;
48 param rail {p1 in plant, p2 in plant} :=
49 if rail_half[p1,p2] > 0 then rail_half[p1,p2] else rail_half[p2,p1];
51 # Interplant rail distances (kms)
53 param impd_barg {plant} >= 0;
54 param impd_road {plant} >= 0;
56 # Import distances (kms) by barge and road
58 param tran_final {pl in plant, r in region} :=
59 if road[r,pl] > 0 then .5 + .0144 * road[r,pl] else 0;
61 param tran_import {r in region, po in port} :=
62 if road[r,po] > 0 then .5 + .0144 * road[r,po] else 0;
64 param tran_inter {p1 in plant, p2 in plant} :=
65 if rail[p1,p2] > 0 then 3.5 + .03 * rail[p1,p2] else 0;
67 param tran_raw {pl in plant} :=
68 (if impd_barg[pl] > 0 then 1.0 + .0030 * impd_barg[pl] else 0)
69 + (if impd_road[pl] > 0 then 0.5 + .0144 * impd_road[pl] else 0);
71 # Transport cost (le per ton) for:
72 # final products, imported final products,
73 # interplant shipment, imported raw materials
75 param io {commod,proc}; # Input-output coefficients
77 param util {unit,proc} >= 0;
79 # Capacity utilization coefficients
81 param p_imp {commod} >= 0; # Import Price (cif US$ per ton 1975)
83 param p_r {c_raw} >= 0;
84 param p_pr {plant,c_raw} >= 0;
86 param p_dom {pl in plant, c in c_raw} :=
87 if p_r[c] > 0 then p_r[c] else p_pr[pl,c];
89 # Domestic raw material prices
91 param dcap {plant,unit} >= 0;
93 # Design capacity of plants (t/day)
95 param icap {u in unit, pl in plant} := 0.33 * dcap[pl,u];
97 # Initial capacity of plants (t/day)
99 param exch := 0.4; # Exchange rate
101 param util_pct := 0.85; # Utilization percent for initial capacity
103 ### DERIVED SETS OF "POSSIBILITIES" ###
105 set m_pos {pl in plant} := {u in unit: icap[u,pl] > 0};
107 # At each plant, set of units for which there is
110 set p_cap {pl in plant} :=
111 {pr in proc: forall {u in unit: util[u,pr] > 0} u in m_pos[pl] };
113 # At each plant, set of processes for which
114 # all necessary units have some initial capacity
116 set p_except {plant} within proc;
118 # At each plant, list of processes that are
119 # arbitrarily ruled out
121 set p_pos {pl in plant} := p_cap[pl] diff p_except[pl];
123 # At each plant, set of possible processes
125 set cp_pos {c in commod} := {pl in plant: sum {pr in p_pos[pl]} io[c,pr] > 0};
127 set cc_pos {c in commod} := {pl in plant: sum {pr in p_pos[pl]} io[c,pr] < 0};
129 set c_pos {c in commod} := cp_pos[c] union cc_pos[c];
131 # For each commodity, set of plants that can
132 # produce it (cp_pos) or consume it (cc_pos),
133 # and their union (c_pos)
137 var Z {pl in plant, p_pos[pl]} >= 0;
139 # Z[pl,pr] is level of process pr at plant pl
141 var Xf {c in c_final, cp_pos[c], region} >= 0;
143 # Xf[c,pl,r] is amount of final product c
144 # shipped from plant pl to region r
146 var Xi {c in c_ship, cp_pos[c], cc_pos[c]} >= 0;
148 # Xi[c,p1,p2] is amount of intermediate c
149 # shipped from plant p1 to plant p2
151 var Vf {c_final,region,port} >= 0;
153 # Vf[c,r,po] is amount of final product c
154 # imported by region r from port po
156 var Vr {c in c_raw, cc_pos[c]} >= 0;
158 # Vr[c,pl] is amount of raw material c
159 # imported for use at plant pl
161 var U {c in c_raw, cc_pos[c]} >= 0;
163 # U[c,pl] is amount of raw material c
164 # purchased domestically for use at plant pl
166 var Psip; # Domestic recurrent cost
167 var Psil; # Transport cost
168 var Psii; # Import cost
172 minimize Psi: Psip + Psil + Psii;
176 subject to mbd {n in nutr, r in region}:
178 sum {c in c_final} fn[c,n] *
179 (sum {po in port} Vf[c,r,po] +
180 sum {pl in cp_pos[c]} Xf[c,pl,r]) >= cn75[r,n];
182 # Total nutrients supplied to a region by all
183 # final products (sum of imports plus internal
184 # shipments from plants) must meet requirements
186 subject to mbdb {c in c_final, r in region: cf75[r,c] > 0}:
188 sum {po in port} Vf[c,r,po] +
189 sum {pl in cp_pos[c]} Xf[c,pl,r] >= cf75[r,c];
191 # Total of each final product supplied to each
192 # region (as in previous constraint) must meet
195 subject to mb {c in commod, pl in plant}:
197 sum {pr in p_pos[pl]} io[c,pr] * Z[pl,pr]
199 + ( if c in c_ship then
200 ( if pl in cp_pos[c] then sum {p2 in cc_pos[c]} Xi[c,pl,p2] )
201 - ( if pl in cc_pos[c] then sum {p2 in cp_pos[c]} Xi[c,p2,pl] ))
203 + ( if (c in c_raw and pl in cc_pos[c]) then
204 (( if p_imp[c] > 0 then Vr[c,pl] )
205 + ( if p_dom[pl,c] > 0 then U[c,pl] )))
207 >= if (c in c_final and pl in cp_pos[c]) then sum {r in region} Xf[c,pl,r];
209 # For each commodity at each plant: sum of
210 # (1) production or consumption at plant,
211 # (2) inter-plant shipments in or out,
212 # (3) import and domestic purchases (raw only)
213 # is >= 0 for raw materials and intermediates;
214 # is >= the total shipped for final products
216 subject to cc {pl in plant, u in m_pos[pl]}:
218 sum {pr in p_pos[pl]} util[u,pr] * Z[pl,pr] <= util_pct * icap[u,pl];
220 # For each productive unit at each plant,
221 # total utilization by all processes
222 # may not exceed the unit's capacity
226 Psip = sum {c in c_raw, pl in cc_pos[c]} p_dom[pl,c] * U[c,pl];
228 # Psip is the cost of domestic raw materials,
229 # summed over all plants that consume them
233 Psil = sum {c in c_final} (
235 sum {pl in cp_pos[c], r in region}
236 tran_final[pl,r] * Xf[c,pl,r]
238 + sum {po in port, r in region} tran_import[r,po] * Vf[c,r,po] )
240 + sum {c in c_ship, p1 in cp_pos[c], p2 in cc_pos[c]}
241 tran_inter[p1,p2] * Xi[c,p1,p2]
243 + sum {c in c_raw, pl in cc_pos[c]: p_imp[c] > 0}
244 tran_raw[pl] * Vr[c,pl];
246 # Total transport cost is sum of shipping costs for
247 # (1) all final products from all plants,
248 # (2) all imports of final products,
249 # (3) all intermediates shipped between plants,
250 # (4) all imports of raw materials
254 Psii / exch = sum {c in c_final, r in region, po in port}
255 p_imp[c] * Vf[c,r,po]
257 + sum {c in c_raw, pl in cc_pos[c]} p_imp[c] * Vr[c,pl];
259 # Total import cost -- at exchange rate --
260 # is sum of import costs for final products
261 # in each region and raw materials at each plant
267 set center := ASWAN HELWAN ASSIOUT KAFR_EL_ZT ABU_ZAABAL ABU_KIR TALKHA SUEZ ;
269 set port := ABU_KIR ;
271 set plant := ASWAN HELWAN ASSIOUT KAFR_EL_ZT ABU_ZAABAL ;
273 set region := ALEXANDRIA BEHERA GHARBIA KAFR_EL_SH DAKAHLIA DAMIETTA
274 SHARKIA ISMAILIA SUEZ MENOUFIA KALUBIA GIZA BENI_SUEF FAYOUM
275 MINIA ASSIOUT NEW_VALLEY SOHAG QUENA ASWAN ;
277 set unit := SULF_A_S SULF_A_P NITR_ACID AMM_ELEC AMM_C_GAS C_AMM_NITR
280 set proc := SULF_A_S SULF_A_P NITR_ACID AMM_ELEC AMM_C_GAS CAN_310 CAN_335
285 set c_final := UREA CAN_260 CAN_310 CAN_335 AMM_SULF DAP SSP_155 C_250_55
288 set c_inter := AMMONIA NITR_ACID SULF_ACID ;
290 set c_ship := AMMONIA SULF_ACID ;
292 set c_raw := EL_ASWAN COKE_GAS PHOS_ROCK LIMESTONE EL_SULFUR PYRITES
293 ELECTRIC BF_GAS WATER STEAM BAGS ;
295 set p_except[ASWAN] := CAN_335 ;
296 set p_except[HELWAN] := CAN_310 ;
297 set p_except[ASSIOUT] := ;
298 set p_except[KAFR_EL_ZT] := ;
299 set p_except[ABU_ZAABAL] := ;
301 param cf75 default 0.0 :
303 CAN_260 CAN_310 CAN_335 AMM_SULF UREA :=
305 ALEXANDRIA . . 5.0 3.0 1.0
306 ASSIOUT 1.0 20.0 26.0 1.0 27.0
308 BEHERA 1.0 . 25.0 90.0 35.0
309 BENI_SUEF 1.0 . 15.0 1.0 20.0
310 DAKAHLIA 1.0 . 26.0 60.0 20.0
311 DAMIETTA . . 2.0 15.0 8.0
312 FAYOUM 1.0 . 20.0 6.0 20.0
313 GHARBIA . . 17.0 60.0 28.0
314 GIZA . . 40.0 6.0 2.0
315 ISMAILIA . . 4.0 6.0 2.0
316 KAFR_EL_SH 1.0 . 10.0 45.0 22.0
317 KALUBIA . . 25.0 16.0 7.0
318 MENOUFIA 1.0 . 24.0 21.0 30.0
319 MINIA 2.0 15.0 35.0 1.0 41.0
320 NEW_VALLEY . . . . 1.0
321 QUENA . 95.0 2.0 . 3.0
322 SHARKIA 1.0 . 31.0 50.0 28.0
323 SOHAG . 65.0 3.0 . 7.0
326 : SSP_155 C_250_55 C_300_100 DAP :=
329 ASSIOUT 35.0 5.0 .1 .
331 BEHERA 64.0 1.0 .1 .1
332 BENI_SUEF 13.0 3.0 . .
333 DAKAHLIA 52.0 1.0 . .
336 GHARBIA 57.0 1.0 .2 .1
339 KAFR_EL_SH 25.0 2.0 .1 .
340 KALUBIA 22.0 1.0 . .1
341 MENOUFIA 33.0 2.0 .1 .1
345 SHARKIA 43.0 1.0 .1 .
349 param fn default 0.0 : N P205 :=
361 param road default 0.0 :
363 ABU_KIR ABU_ZAABAL ASSIOUT ASWAN HELWAN KAFR_EL_ZT SUEZ TALKHA :=
365 ALEXANDRIA 16 210 607 1135 244 119 362 187
366 ASSIOUT 616 420 . 518 362 504 527 518
367 ASWAN 1134 938 518 . 880 1022 1045 1036
368 BEHERA 76 50 547 1065 184 42 288 120
369 BENI_SUEF 359 163 257 775 105 248 270 261
370 DAKAHLIA 208 138 515 1033 152 58 219 3
371 DAMIETTA 267 216 596 1114 233 131 286 66
372 FAYOUM 341 145 308 826 88 230 252 243
373 GHARBIA 150 65 485 1003 122 20 226 55
374 GIZA 287 48 372 890 .9 133 169 146
375 ISMAILIA 365 142 536 1054 173 241 89 146
376 KAFR_EL_SH 145 105 525 1043 162 20 266 35
377 KALUBIA 190 97 439 957 76 66 180 81
378 MENOUFIA 157 154 472 990 109 33 213 90
379 MINIA 384 288 132 650 230 372 394 386
380 NEW_VALLEY 815 619 199 519 561 703 726 717
381 QUENA 858 662 242 276 604 746 769 760
382 SHARKIA 240 60 473 991 110 78 214 58
383 SOHAG 715 519 99 419 461 603 626 617
384 SUEZ 370 224 541 1059 178 246 . 298 ;
386 param rail_half default 0 :
388 KAFR_EL_ZT ABU_ZAABAL HELWAN ASSIOUT :=
392 ASSIOUT 504 420 362 .
393 ASWAN 1022 938 880 518 ;
395 param : impd_barg impd_road :=
403 param io default 0.0 :=
405 [*,AMM_C_GAS] AMMONIA 1.0
412 [*,AMM_ELEC] AMMONIA 1.0
415 [*,AMM_SULF] AMMONIA -.26
422 [*,CAN_310] AMMONIA -.20
430 [*,CAN_335] AMMONIA -.21
438 [*,NITR_ACID] AMMONIA -.292
443 [*,SSP_155] BAGS -22.
450 [*,SULF_A_P] ELECTRIC -75.
455 [*,SULF_A_S] ELECTRIC -50.
460 param util default 0 :=
462 [*,*] SULF_A_S SULF_A_S 1 SULF_A_P SULF_A_P 1
463 NITR_ACID NITR_ACID 1 AMM_ELEC AMM_ELEC 1
464 AMM_C_GAS AMM_C_GAS 1 SSP SSP_155 1
465 C_AMM_NITR CAN_310 1 C_AMM_NITR CAN_335 1
466 AMM_SULF AMM_SULF 1 ;
468 param p_imp default 0.0 :=
470 PYRITES 17.5 AMM_SULF 75.
471 EL_SULFUR 55. DAP 175.
472 UREA 150. SSP_155 80.
473 CAN_260 75. C_250_55 100.
474 CAN_310 90. C_300_100 130.
477 param p_r default 0.0 :=
485 param p_pr default 0.0 :=
487 [HELWAN,COKE_GAS] 16.0
490 [*,LIMESTONE] ASWAN 1.2
493 [*,PHOS_ROCK] ABU_ZAABAL 4.0
497 param dcap default 0.0 :=
499 [ABU_ZAABAL,*] SSP 600
506 [ASWAN,*] AMM_ELEC 450
510 [HELWAN,*] AMM_C_GAS 172
515 [KAFR_EL_ZT,*] SSP 600