The source code and dockerfile for the GSW2024 AI Lab.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
This repo is archived. You can view files and clone it, but cannot push or open issues/pull-requests.

519 lines
18 KiB

2 months ago
  1. # EGYPT, a static model of fertilizer production
  2. #
  3. # References:
  4. # Robert Fourer, David M. Gay and Brian W. Kernighan, "A Modeling Language
  5. # for Mathematical Programming." Management Science 36 (1990) 519-554.
  6. ### SETS ###
  7. set center; # Locations from which final product may be shipped
  8. set port within center; # Locations at which imports can be received
  9. set plant within center; # Locations of plants
  10. set region; # Demand regions
  11. set unit; # Productive units
  12. set proc; # Processes
  13. set nutr; # Nutrients
  14. set c_final; # Final products (fertilizers)
  15. set c_inter; # Intermediate products
  16. set c_ship within c_inter; # Intermediates for shipment
  17. set c_raw; # Domestic raw materials and miscellaneous inputs
  18. set commod := c_final union c_inter union c_raw;
  19. # All commodities
  20. ### PARAMETERS ###
  21. param cf75 {region,c_final} >= 0;
  22. # Consumption of fertilizer 1974-75 (1000 tpy)
  23. param fn {c_final,nutr} >= 0;
  24. # Nutrient content of fertilizers
  25. param cn75 {r in region, n in nutr} := sum {c in c_final} cf75[r,c] * fn[c,n];
  26. # Consumption of nutrients 1974-75 (1000 tpy)
  27. param road {region,center} >= 0;
  28. # Road distances
  29. param rail_half {plant,plant} >= 0;
  30. param rail {p1 in plant, p2 in plant} :=
  31. if rail_half[p1,p2] > 0 then rail_half[p1,p2] else rail_half[p2,p1];
  32. # Interplant rail distances (kms)
  33. param impd_barg {plant} >= 0;
  34. param impd_road {plant} >= 0;
  35. # Import distances (kms) by barge and road
  36. param tran_final {pl in plant, r in region} :=
  37. if road[r,pl] > 0 then .5 + .0144 * road[r,pl] else 0;
  38. param tran_import {r in region, po in port} :=
  39. if road[r,po] > 0 then .5 + .0144 * road[r,po] else 0;
  40. param tran_inter {p1 in plant, p2 in plant} :=
  41. if rail[p1,p2] > 0 then 3.5 + .03 * rail[p1,p2] else 0;
  42. param tran_raw {pl in plant} :=
  43. (if impd_barg[pl] > 0 then 1.0 + .0030 * impd_barg[pl] else 0)
  44. + (if impd_road[pl] > 0 then 0.5 + .0144 * impd_road[pl] else 0);
  45. # Transport cost (le per ton) for:
  46. # final products, imported final products,
  47. # interplant shipment, imported raw materials
  48. param io {commod,proc}; # Input-output coefficients
  49. param util {unit,proc} >= 0;
  50. # Capacity utilization coefficients
  51. param p_imp {commod} >= 0; # Import Price (cif US$ per ton 1975)
  52. param p_r {c_raw} >= 0;
  53. param p_pr {plant,c_raw} >= 0;
  54. param p_dom {pl in plant, c in c_raw} :=
  55. if p_r[c] > 0 then p_r[c] else p_pr[pl,c];
  56. # Domestic raw material prices
  57. param dcap {plant,unit} >= 0;
  58. # Design capacity of plants (t/day)
  59. param icap {u in unit, pl in plant} := 0.33 * dcap[pl,u];
  60. # Initial capacity of plants (t/day)
  61. param exch := 0.4; # Exchange rate
  62. param util_pct := 0.85; # Utilization percent for initial capacity
  63. ### DERIVED SETS OF "POSSIBILITIES" ###
  64. set m_pos {pl in plant} := {u in unit: icap[u,pl] > 0};
  65. # At each plant, set of units for which there is
  66. # initial capacity
  67. set p_cap {pl in plant} :=
  68. {pr in proc: forall {u in unit: util[u,pr] > 0} u in m_pos[pl] };
  69. # At each plant, set of processes for which
  70. # all necessary units have some initial capacity
  71. set p_except {plant} within proc;
  72. # At each plant, list of processes that are
  73. # arbitrarily ruled out
  74. set p_pos {pl in plant} := p_cap[pl] diff p_except[pl];
  75. # At each plant, set of possible processes
  76. set cp_pos {c in commod} := {pl in plant: sum {pr in p_pos[pl]} io[c,pr] > 0};
  77. set cc_pos {c in commod} := {pl in plant: sum {pr in p_pos[pl]} io[c,pr] < 0};
  78. set c_pos {c in commod} := cp_pos[c] union cc_pos[c];
  79. # For each commodity, set of plants that can
  80. # produce it (cp_pos) or consume it (cc_pos),
  81. # and their union (c_pos)
  82. ### VARIABLES ###
  83. var Z {pl in plant, p_pos[pl]} >= 0;
  84. # Z[pl,pr] is level of process pr at plant pl
  85. var Xf {c in c_final, cp_pos[c], region} >= 0;
  86. # Xf[c,pl,r] is amount of final product c
  87. # shipped from plant pl to region r
  88. var Xi {c in c_ship, cp_pos[c], cc_pos[c]} >= 0;
  89. # Xi[c,p1,p2] is amount of intermediate c
  90. # shipped from plant p1 to plant p2
  91. var Vf {c_final,region,port} >= 0;
  92. # Vf[c,r,po] is amount of final product c
  93. # imported by region r from port po
  94. var Vr {c in c_raw, cc_pos[c]} >= 0;
  95. # Vr[c,pl] is amount of raw material c
  96. # imported for use at plant pl
  97. var U {c in c_raw, cc_pos[c]} >= 0;
  98. # U[c,pl] is amount of raw material c
  99. # purchased domestically for use at plant pl
  100. var Psip; # Domestic recurrent cost
  101. var Psil; # Transport cost
  102. var Psii; # Import cost
  103. ### OBJECTIVE ###
  104. minimize Psi: Psip + Psil + Psii;
  105. ### CONSTRAINTS ###
  106. subject to mbd {n in nutr, r in region}:
  107. sum {c in c_final} fn[c,n] *
  108. (sum {po in port} Vf[c,r,po] +
  109. sum {pl in cp_pos[c]} Xf[c,pl,r]) >= cn75[r,n];
  110. # Total nutrients supplied to a region by all
  111. # final products (sum of imports plus internal
  112. # shipments from plants) must meet requirements
  113. subject to mbdb {c in c_final, r in region: cf75[r,c] > 0}:
  114. sum {po in port} Vf[c,r,po] +
  115. sum {pl in cp_pos[c]} Xf[c,pl,r] >= cf75[r,c];
  116. # Total of each final product supplied to each
  117. # region (as in previous constraint) must meet
  118. # requirements
  119. subject to mb {c in commod, pl in plant}:
  120. sum {pr in p_pos[pl]} io[c,pr] * Z[pl,pr]
  121. + ( if c in c_ship then
  122. ( if pl in cp_pos[c] then sum {p2 in cc_pos[c]} Xi[c,pl,p2] )
  123. - ( if pl in cc_pos[c] then sum {p2 in cp_pos[c]} Xi[c,p2,pl] ))
  124. + ( if (c in c_raw and pl in cc_pos[c]) then
  125. (( if p_imp[c] > 0 then Vr[c,pl] )
  126. + ( if p_dom[pl,c] > 0 then U[c,pl] )))
  127. >= if (c in c_final and pl in cp_pos[c]) then sum {r in region} Xf[c,pl,r];
  128. # For each commodity at each plant: sum of
  129. # (1) production or consumption at plant,
  130. # (2) inter-plant shipments in or out,
  131. # (3) import and domestic purchases (raw only)
  132. # is >= 0 for raw materials and intermediates;
  133. # is >= the total shipped for final products
  134. subject to cc {pl in plant, u in m_pos[pl]}:
  135. sum {pr in p_pos[pl]} util[u,pr] * Z[pl,pr] <= util_pct * icap[u,pl];
  136. # For each productive unit at each plant,
  137. # total utilization by all processes
  138. # may not exceed the unit's capacity
  139. subject to ap:
  140. Psip = sum {c in c_raw, pl in cc_pos[c]} p_dom[pl,c] * U[c,pl];
  141. # Psip is the cost of domestic raw materials,
  142. # summed over all plants that consume them
  143. subject to al:
  144. Psil = sum {c in c_final} (
  145. sum {pl in cp_pos[c], r in region}
  146. tran_final[pl,r] * Xf[c,pl,r]
  147. + sum {po in port, r in region} tran_import[r,po] * Vf[c,r,po] )
  148. + sum {c in c_ship, p1 in cp_pos[c], p2 in cc_pos[c]}
  149. tran_inter[p1,p2] * Xi[c,p1,p2]
  150. + sum {c in c_raw, pl in cc_pos[c]: p_imp[c] > 0}
  151. tran_raw[pl] * Vr[c,pl];
  152. # Total transport cost is sum of shipping costs for
  153. # (1) all final products from all plants,
  154. # (2) all imports of final products,
  155. # (3) all intermediates shipped between plants,
  156. # (4) all imports of raw materials
  157. subject to ai:
  158. Psii / exch = sum {c in c_final, r in region, po in port}
  159. p_imp[c] * Vf[c,r,po]
  160. + sum {c in c_raw, pl in cc_pos[c]} p_imp[c] * Vr[c,pl];
  161. # Total import cost -- at exchange rate --
  162. # is sum of import costs for final products
  163. # in each region and raw materials at each plant
  164. ### DATA ###
  165. data;
  166. set center := ASWAN HELWAN ASSIOUT KAFR_EL_ZT ABU_ZAABAL ABU_KIR TALKHA SUEZ ;
  167. set port := ABU_KIR ;
  168. set plant := ASWAN HELWAN ASSIOUT KAFR_EL_ZT ABU_ZAABAL ;
  169. set region := ALEXANDRIA BEHERA GHARBIA KAFR_EL_SH DAKAHLIA DAMIETTA
  170. SHARKIA ISMAILIA SUEZ MENOUFIA KALUBIA GIZA BENI_SUEF FAYOUM
  171. MINIA ASSIOUT NEW_VALLEY SOHAG QUENA ASWAN ;
  172. set unit := SULF_A_S SULF_A_P NITR_ACID AMM_ELEC AMM_C_GAS C_AMM_NITR
  173. AMM_SULF SSP ;
  174. set proc := SULF_A_S SULF_A_P NITR_ACID AMM_ELEC AMM_C_GAS CAN_310 CAN_335
  175. AMM_SULF SSP_155 ;
  176. set nutr := N P205 ;
  177. set c_final := UREA CAN_260 CAN_310 CAN_335 AMM_SULF DAP SSP_155 C_250_55
  178. C_300_100 ;
  179. set c_inter := AMMONIA NITR_ACID SULF_ACID ;
  180. set c_ship := AMMONIA SULF_ACID ;
  181. set c_raw := EL_ASWAN COKE_GAS PHOS_ROCK LIMESTONE EL_SULFUR PYRITES
  182. ELECTRIC BF_GAS WATER STEAM BAGS ;
  183. set p_except[ASWAN] := CAN_335 ;
  184. set p_except[HELWAN] := CAN_310 ;
  185. set p_except[ASSIOUT] := ;
  186. set p_except[KAFR_EL_ZT] := ;
  187. set p_except[ABU_ZAABAL] := ;
  188. param cf75 default 0.0 :
  189. CAN_260 CAN_310 CAN_335 AMM_SULF UREA :=
  190. ALEXANDRIA . . 5.0 3.0 1.0
  191. ASSIOUT 1.0 20.0 26.0 1.0 27.0
  192. ASWAN . 40.0 . . .
  193. BEHERA 1.0 . 25.0 90.0 35.0
  194. BENI_SUEF 1.0 . 15.0 1.0 20.0
  195. DAKAHLIA 1.0 . 26.0 60.0 20.0
  196. DAMIETTA . . 2.0 15.0 8.0
  197. FAYOUM 1.0 . 20.0 6.0 20.0
  198. GHARBIA . . 17.0 60.0 28.0
  199. GIZA . . 40.0 6.0 2.0
  200. ISMAILIA . . 4.0 6.0 2.0
  201. KAFR_EL_SH 1.0 . 10.0 45.0 22.0
  202. KALUBIA . . 25.0 16.0 7.0
  203. MENOUFIA 1.0 . 24.0 21.0 30.0
  204. MINIA 2.0 15.0 35.0 1.0 41.0
  205. NEW_VALLEY . . . . 1.0
  206. QUENA . 95.0 2.0 . 3.0
  207. SHARKIA 1.0 . 31.0 50.0 28.0
  208. SOHAG . 65.0 3.0 . 7.0
  209. SUEZ . . 1.0 . .
  210. : SSP_155 C_250_55 C_300_100 DAP :=
  211. ALEXANDRIA 8.0 . . .
  212. ASSIOUT 35.0 5.0 .1 .
  213. ASWAN 8.0 . . .
  214. BEHERA 64.0 1.0 .1 .1
  215. BENI_SUEF 13.0 3.0 . .
  216. DAKAHLIA 52.0 1.0 . .
  217. DAMIETTA 5.0 . . .
  218. FAYOUM 17.0 1.0 . .
  219. GHARBIA 57.0 1.0 .2 .1
  220. GIZA 14.0 1.0 .1 .
  221. ISMAILIA 4.0 . . .
  222. KAFR_EL_SH 25.0 2.0 .1 .
  223. KALUBIA 22.0 1.0 . .1
  224. MENOUFIA 33.0 2.0 .1 .1
  225. MINIA 50.0 3.0 .2 .1
  226. NEW_VALLEY 1.0 . . .
  227. QUENA 8.0 . . .
  228. SHARKIA 43.0 1.0 .1 .
  229. SOHAG 20.0 1.0 . .
  230. SUEZ 1.0 . . . ;
  231. param fn default 0.0 : N P205 :=
  232. AMM_SULF .206 .
  233. CAN_260 .26 .
  234. CAN_310 .31 .
  235. CAN_335 .335 .
  236. C_250_55 .25 .055
  237. C_300_100 .30 .10
  238. DAP .18 .46
  239. SSP_155 . .15
  240. UREA .46 . ;
  241. param road default 0.0 :
  242. ABU_KIR ABU_ZAABAL ASSIOUT ASWAN HELWAN KAFR_EL_ZT SUEZ TALKHA :=
  243. ALEXANDRIA 16 210 607 1135 244 119 362 187
  244. ASSIOUT 616 420 . 518 362 504 527 518
  245. ASWAN 1134 938 518 . 880 1022 1045 1036
  246. BEHERA 76 50 547 1065 184 42 288 120
  247. BENI_SUEF 359 163 257 775 105 248 270 261
  248. DAKAHLIA 208 138 515 1033 152 58 219 3
  249. DAMIETTA 267 216 596 1114 233 131 286 66
  250. FAYOUM 341 145 308 826 88 230 252 243
  251. GHARBIA 150 65 485 1003 122 20 226 55
  252. GIZA 287 48 372 890 .9 133 169 146
  253. ISMAILIA 365 142 536 1054 173 241 89 146
  254. KAFR_EL_SH 145 105 525 1043 162 20 266 35
  255. KALUBIA 190 97 439 957 76 66 180 81
  256. MENOUFIA 157 154 472 990 109 33 213 90
  257. MINIA 384 288 132 650 230 372 394 386
  258. NEW_VALLEY 815 619 199 519 561 703 726 717
  259. QUENA 858 662 242 276 604 746 769 760
  260. SHARKIA 240 60 473 991 110 78 214 58
  261. SOHAG 715 519 99 419 461 603 626 617
  262. SUEZ 370 224 541 1059 178 246 . 298 ;
  263. param rail_half default 0 :
  264. KAFR_EL_ZT ABU_ZAABAL HELWAN ASSIOUT :=
  265. ABU_ZAABAL 85 . . .
  266. HELWAN 142 57 . .
  267. ASSIOUT 504 420 362 .
  268. ASWAN 1022 938 880 518 ;
  269. param : impd_barg impd_road :=
  270. ABU_ZAABAL 210 .1
  271. ASSIOUT 583 0
  272. ASWAN 1087 10
  273. HELWAN 183 0
  274. KAFR_EL_ZT 104 6 ;
  275. param io default 0.0 :=
  276. [*,AMM_C_GAS] AMMONIA 1.0
  277. BF_GAS -609.
  278. COKE_GAS -2.0
  279. ELECTRIC -1960.
  280. STEAM -4.
  281. WATER -700.
  282. [*,AMM_ELEC] AMMONIA 1.0
  283. EL_ASWAN -12.0
  284. [*,AMM_SULF] AMMONIA -.26
  285. AMM_SULF 1.0
  286. BAGS -22.
  287. ELECTRIC -19.
  288. SULF_ACID -.76
  289. WATER -17.
  290. [*,CAN_310] AMMONIA -.20
  291. BAGS -23.
  292. CAN_310 1.0
  293. LIMESTONE -.12
  294. NITR_ACID -.71
  295. STEAM -.4
  296. WATER -49.
  297. [*,CAN_335] AMMONIA -.21
  298. BAGS -23.
  299. CAN_335 1.0
  300. LIMESTONE -.04
  301. NITR_ACID -.76
  302. STEAM -.4
  303. WATER -49.
  304. [*,NITR_ACID] AMMONIA -.292
  305. ELECTRIC -231.
  306. NITR_ACID 1.0
  307. WATER -.6
  308. [*,SSP_155] BAGS -22.
  309. ELECTRIC -14.
  310. PHOS_ROCK -.62
  311. SSP_155 1.0
  312. SULF_ACID -.41
  313. WATER -6.
  314. [*,SULF_A_P] ELECTRIC -75.
  315. PYRITES -.826
  316. SULF_ACID 1.0
  317. WATER -60.
  318. [*,SULF_A_S] ELECTRIC -50.
  319. EL_SULFUR -.334
  320. SULF_ACID 1.0
  321. WATER -20. ;
  322. param util default 0 :=
  323. [*,*] SULF_A_S SULF_A_S 1 SULF_A_P SULF_A_P 1
  324. NITR_ACID NITR_ACID 1 AMM_ELEC AMM_ELEC 1
  325. AMM_C_GAS AMM_C_GAS 1 SSP SSP_155 1
  326. C_AMM_NITR CAN_310 1 C_AMM_NITR CAN_335 1
  327. AMM_SULF AMM_SULF 1 ;
  328. param p_imp default 0.0 :=
  329. PYRITES 17.5 AMM_SULF 75.
  330. EL_SULFUR 55. DAP 175.
  331. UREA 150. SSP_155 80.
  332. CAN_260 75. C_250_55 100.
  333. CAN_310 90. C_300_100 130.
  334. CAN_335 100. ;
  335. param p_r default 0.0 :=
  336. ELECTRIC .007
  337. BF_GAS .007
  338. WATER .031
  339. STEAM 1.25
  340. BAGS .28 ;
  341. param p_pr default 0.0 :=
  342. [HELWAN,COKE_GAS] 16.0
  343. [ASWAN,EL_ASWAN] 1.0
  344. [*,LIMESTONE] ASWAN 1.2
  345. HELWAN 1.2
  346. [*,PHOS_ROCK] ABU_ZAABAL 4.0
  347. ASSIOUT 3.5
  348. KAFR_EL_ZT 5.0 ;
  349. param dcap default 0.0 :=
  350. [ABU_ZAABAL,*] SSP 600
  351. SULF_A_P 227
  352. SULF_A_S 242
  353. [ASSIOUT,*] SSP 600
  354. SULF_A_S 250
  355. [ASWAN,*] AMM_ELEC 450
  356. C_AMM_NITR 1100
  357. NITR_ACID 800
  358. [HELWAN,*] AMM_C_GAS 172
  359. AMM_SULF 24
  360. C_AMM_NITR 364
  361. NITR_ACID 282
  362. [KAFR_EL_ZT,*] SSP 600
  363. SULF_A_P 50
  364. SULF_A_S 200 ;
  365. end;