commit 6b1b62c658b1ad12a2654b27a78527bf2ebef0a1 Author: Alinson S. Xavier Date: Wed Mar 20 10:05:49 2024 -0500 Prototype composition model diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..1269488 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +data diff --git a/Manifest.toml b/Manifest.toml new file mode 100644 index 0000000..a032d8c --- /dev/null +++ b/Manifest.toml @@ -0,0 +1,608 @@ +# This file is machine-generated - editing it directly is not advised + +julia_version = "1.9.0" +manifest_format = "2.0" +project_hash = "6050446040717864eaea84cf3a5f066d959d36dd" + +[[deps.ArgTools]] +uuid = "0dad84c5-d112-42e6-8d28-ef12dabb789f" +version = "1.1.1" + +[[deps.Artifacts]] +uuid = "56f22d72-fd6d-98f1-02f0-08ddc0907c33" + +[[deps.Base64]] +uuid = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f" + +[[deps.BenchmarkTools]] +deps = ["JSON", "Logging", "Printf", "Profile", "Statistics", "UUIDs"] +git-tree-sha1 = "f1f03a9fa24271160ed7e73051fba3c1a759b53f" +uuid = "6e4b80f9-dd63-53aa-95a3-0cdb28fa8baf" +version = "1.4.0" + +[[deps.Bzip2_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "9e2a6b69137e6969bab0152632dcb3bc108c8bdd" +uuid = "6e34b625-4abd-537c-b88f-471c36dfa7a0" +version = "1.0.8+1" + +[[deps.CRC]] +git-tree-sha1 = "b7ba7f0d727433c961909b329c4d2263268da4c9" +uuid = "44b605c4-b955-5f2b-9b6d-d2bd01d3d205" +version = "4.0.0" + +[[deps.CSV]] +deps = ["CodecZlib", "Dates", "FilePathsBase", "InlineStrings", "Mmap", "Parsers", "PooledArrays", "PrecompileTools", "SentinelArrays", "Tables", "Unicode", "WeakRefStrings", "WorkerUtilities"] +git-tree-sha1 = "679e69c611fff422038e9e21e270c4197d49d918" +uuid = "336ed68f-0bac-5ca0-87d4-7b16caf5d00b" +version = "0.10.12" + +[[deps.CodeTracking]] +deps = ["InteractiveUtils", "UUIDs"] +git-tree-sha1 = "c0216e792f518b39b22212127d4a84dc31e4e386" +uuid = "da1fd8a2-8d9e-5ec2-8556-3022fb5608a2" +version = "1.3.5" + +[[deps.CodecBzip2]] +deps = ["Bzip2_jll", "Libdl", "TranscodingStreams"] +git-tree-sha1 = "9b1ca1aa6ce3f71b3d1840c538a8210a043625eb" +uuid = "523fee87-0ab8-5b00-afb7-3ecf72e48cfd" +version = "0.8.2" + +[[deps.CodecZlib]] +deps = ["TranscodingStreams", "Zlib_jll"] +git-tree-sha1 = "59939d8a997469ee05c4b4944560a820f9ba0d73" +uuid = "944b1d66-785c-5afd-91f1-9de20f533193" +version = "0.7.4" + +[[deps.CommonSubexpressions]] +deps = ["MacroTools", "Test"] +git-tree-sha1 = "7b8a93dba8af7e3b42fecabf646260105ac373f7" +uuid = "bbf7d656-a473-5ed7-a52c-81e309532950" +version = "0.3.0" + +[[deps.Compat]] +deps = ["TOML", "UUIDs"] +git-tree-sha1 = "c955881e3c981181362ae4088b35995446298b80" +uuid = "34da2185-b29b-5c13-b0c7-acf172513d20" +version = "4.14.0" +weakdeps = ["Dates", "LinearAlgebra"] + + [deps.Compat.extensions] + CompatLinearAlgebraExt = "LinearAlgebra" + +[[deps.CompilerSupportLibraries_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "e66e0078-7015-5450-92f7-15fbd957f2ae" +version = "1.0.2+0" + +[[deps.CoordinateTransformations]] +deps = ["LinearAlgebra", "StaticArrays"] +git-tree-sha1 = "f9d7112bfff8a19a3a4ea4e03a8e6a91fe8456bf" +uuid = "150eb455-5306-5404-9cee-2592286d6298" +version = "0.6.3" + +[[deps.Crayons]] +git-tree-sha1 = "249fe38abf76d48563e2f4556bebd215aa317e15" +uuid = "a8cc5b0e-0ffa-5ad4-8c14-923d3ee1735f" +version = "4.1.1" + +[[deps.DataAPI]] +git-tree-sha1 = "abe83f3a2f1b857aac70ef8b269080af17764bbe" +uuid = "9a962f9c-6df0-11e9-0e5d-c546b8b5ee8a" +version = "1.16.0" + +[[deps.DataFrames]] +deps = ["Compat", "DataAPI", "DataStructures", "Future", "InlineStrings", "InvertedIndices", "IteratorInterfaceExtensions", "LinearAlgebra", "Markdown", "Missings", "PooledArrays", "PrecompileTools", "PrettyTables", "Printf", "REPL", "Random", "Reexport", "SentinelArrays", "SortingAlgorithms", "Statistics", "TableTraits", "Tables", "Unicode"] +git-tree-sha1 = "04c738083f29f86e62c8afc341f0967d8717bdb8" +uuid = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0" +version = "1.6.1" + +[[deps.DataStructures]] +deps = ["Compat", "InteractiveUtils", "OrderedCollections"] +git-tree-sha1 = "1fb174f0d48fe7d142e1109a10636bc1d14f5ac2" +uuid = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8" +version = "0.18.17" + +[[deps.DataValueInterfaces]] +git-tree-sha1 = "bfc1187b79289637fa0ef6d4436ebdfe6905cbd6" +uuid = "e2d170a0-9d28-54be-80f0-106bbe20a464" +version = "1.0.0" + +[[deps.Dates]] +deps = ["Printf"] +uuid = "ade2ca70-3891-5945-98fb-dc099432e06a" + +[[deps.DiffResults]] +deps = ["StaticArraysCore"] +git-tree-sha1 = "782dd5f4561f5d267313f23853baaaa4c52ea621" +uuid = "163ba53b-c6d8-5494-b064-1a9d43ac40c5" +version = "1.1.0" + +[[deps.DiffRules]] +deps = ["IrrationalConstants", "LogExpFunctions", "NaNMath", "Random", "SpecialFunctions"] +git-tree-sha1 = "23163d55f885173722d1e4cf0f6110cdbaf7e272" +uuid = "b552c78f-8df3-52c6-915a-8e097449b14b" +version = "1.15.1" + +[[deps.Distances]] +deps = ["LinearAlgebra", "Statistics", "StatsAPI"] +git-tree-sha1 = "66c4c81f259586e8f002eacebc177e1fb06363b0" +uuid = "b4f34e82-e78d-54a5-968a-f98e89d6e8f7" +version = "0.10.11" + + [deps.Distances.extensions] + DistancesChainRulesCoreExt = "ChainRulesCore" + DistancesSparseArraysExt = "SparseArrays" + + [deps.Distances.weakdeps] + ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" + SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" + +[[deps.Distributed]] +deps = ["Random", "Serialization", "Sockets"] +uuid = "8ba89e20-285c-5b6f-9357-94700520ee1b" + +[[deps.DocStringExtensions]] +deps = ["LibGit2"] +git-tree-sha1 = "2fb1e02f2b635d0845df5d7c167fec4dd739b00d" +uuid = "ffbed154-4ef7-542d-bbb7-c09d3a79fcae" +version = "0.9.3" + +[[deps.Downloads]] +deps = ["ArgTools", "FileWatching", "LibCURL", "NetworkOptions"] +uuid = "f43a241f-c20a-4ad4-852c-f6b1247861c6" +version = "1.6.0" + +[[deps.FilePathsBase]] +deps = ["Compat", "Dates", "Mmap", "Printf", "Test", "UUIDs"] +git-tree-sha1 = "9f00e42f8d99fdde64d40c8ea5d14269a2e2c1aa" +uuid = "48062228-2e41-5def-b9a4-89aafe57970f" +version = "0.9.21" + +[[deps.FileWatching]] +uuid = "7b1f6079-737a-58dc-b8bc-7a2ca5c1b5ee" + +[[deps.ForwardDiff]] +deps = ["CommonSubexpressions", "DiffResults", "DiffRules", "LinearAlgebra", "LogExpFunctions", "NaNMath", "Preferences", "Printf", "Random", "SpecialFunctions"] +git-tree-sha1 = "cf0fe81336da9fb90944683b8c41984b08793dad" +uuid = "f6369f11-7733-5829-9624-2563aa707210" +version = "0.10.36" +weakdeps = ["StaticArrays"] + + [deps.ForwardDiff.extensions] + ForwardDiffStaticArraysExt = "StaticArrays" + +[[deps.Future]] +deps = ["Random"] +uuid = "9fa8497b-333b-5362-9e8d-4d0656e87820" + +[[deps.Geodesy]] +deps = ["CoordinateTransformations", "Dates", "LinearAlgebra", "StaticArrays"] +git-tree-sha1 = "ed98a4429bf0a033ccc5e036120181dd52f06d31" +uuid = "0ef565a4-170c-5f04-8de2-149903a85f3d" +version = "1.1.0" + +[[deps.Gurobi]] +deps = ["LazyArtifacts", "Libdl", "MathOptInterface"] +git-tree-sha1 = "5995b72d385235f3fe55f8f0c4ad61049f867814" +uuid = "2e9cd046-0924-5485-92f1-d5272153d98b" +version = "1.2.1" + +[[deps.InlineStrings]] +deps = ["Parsers"] +git-tree-sha1 = "9cc2baf75c6d09f9da536ddf58eb2f29dedaf461" +uuid = "842dd82b-1e85-43dc-bf29-5d0ee9dffc48" +version = "1.4.0" + +[[deps.InteractiveUtils]] +deps = ["Markdown"] +uuid = "b77e0a4c-d291-57a0-90e8-8db25a27a240" + +[[deps.InvertedIndices]] +git-tree-sha1 = "0dc7b50b8d436461be01300fd8cd45aa0274b038" +uuid = "41ab1584-1d38-5bbf-9106-f11c6c58b48f" +version = "1.3.0" + +[[deps.IrrationalConstants]] +git-tree-sha1 = "630b497eafcc20001bba38a4651b327dcfc491d2" +uuid = "92d709cd-6900-40b7-9082-c6be49f344b6" +version = "0.2.2" + +[[deps.IteratorInterfaceExtensions]] +git-tree-sha1 = "a3f24677c21f5bbe9d2a714f95dcd58337fb2856" +uuid = "82899510-4779-5014-852e-03e436cf321d" +version = "1.0.0" + +[[deps.JLLWrappers]] +deps = ["Artifacts", "Preferences"] +git-tree-sha1 = "7e5d6779a1e09a36db2a7b6cff50942a0a7d0fca" +uuid = "692b3bcd-3c85-4b1f-b108-f13ce0eb3210" +version = "1.5.0" + +[[deps.JSON]] +deps = ["Dates", "Mmap", "Parsers", "Unicode"] +git-tree-sha1 = "31e996f0a15c7b280ba9f76636b3ff9e2ae58c9a" +uuid = "682c06a0-de6a-54ab-a142-c8b1cf79cde6" +version = "0.21.4" + +[[deps.JuMP]] +deps = ["LinearAlgebra", "MacroTools", "MathOptInterface", "MutableArithmetics", "OrderedCollections", "PrecompileTools", "Printf", "SparseArrays"] +git-tree-sha1 = "4e44cff1595c6c02cdbca4e87ce376e63c33a584" +uuid = "4076af6c-e467-56ae-b986-b466b2749572" +version = "1.20.0" + + [deps.JuMP.extensions] + JuMPDimensionalDataExt = "DimensionalData" + + [deps.JuMP.weakdeps] + DimensionalData = "0703355e-b756-11e9-17c0-8b28908087d0" + +[[deps.JuliaInterpreter]] +deps = ["CodeTracking", "InteractiveUtils", "Random", "UUIDs"] +git-tree-sha1 = "7b762d81887160169ddfc93a47e5fd7a6a3e78ef" +uuid = "aa1ae85d-cabe-5617-a682-6adf51b2e16a" +version = "0.9.29" + +[[deps.LaTeXStrings]] +git-tree-sha1 = "50901ebc375ed41dbf8058da26f9de442febbbec" +uuid = "b964fa9f-0449-5b57-a5c2-d3ea65f4040f" +version = "1.3.1" + +[[deps.LazyArtifacts]] +deps = ["Artifacts", "Pkg"] +uuid = "4af54fe1-eca0-43a8-85a7-787d91b784e3" + +[[deps.LibCURL]] +deps = ["LibCURL_jll", "MozillaCACerts_jll"] +uuid = "b27032c2-a3e7-50c8-80cd-2d36dbcbfd21" +version = "0.6.3" + +[[deps.LibCURL_jll]] +deps = ["Artifacts", "LibSSH2_jll", "Libdl", "MbedTLS_jll", "Zlib_jll", "nghttp2_jll"] +uuid = "deac9b47-8bc7-5906-a0fe-35ac56dc84c0" +version = "7.84.0+0" + +[[deps.LibGit2]] +deps = ["Base64", "NetworkOptions", "Printf", "SHA"] +uuid = "76f85450-5226-5b5a-8eaa-529ad045b433" + +[[deps.LibSSH2_jll]] +deps = ["Artifacts", "Libdl", "MbedTLS_jll"] +uuid = "29816b5a-b9ab-546f-933c-edad1886dfa8" +version = "1.10.2+0" + +[[deps.Libdl]] +uuid = "8f399da3-3557-5675-b5ff-fb832c97cbdb" + +[[deps.LinearAlgebra]] +deps = ["Libdl", "OpenBLAS_jll", "libblastrampoline_jll"] +uuid = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" + +[[deps.LogExpFunctions]] +deps = ["DocStringExtensions", "IrrationalConstants", "LinearAlgebra"] +git-tree-sha1 = "18144f3e9cbe9b15b070288eef858f71b291ce37" +uuid = "2ab3a3ac-af41-5b50-aa03-7779005ae688" +version = "0.3.27" + + [deps.LogExpFunctions.extensions] + LogExpFunctionsChainRulesCoreExt = "ChainRulesCore" + LogExpFunctionsChangesOfVariablesExt = "ChangesOfVariables" + LogExpFunctionsInverseFunctionsExt = "InverseFunctions" + + [deps.LogExpFunctions.weakdeps] + ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" + ChangesOfVariables = "9e997f8a-9a97-42d5-a9f1-ce6bfc15e2c0" + InverseFunctions = "3587e190-3f89-42d0-90ee-14403ec27112" + +[[deps.Logging]] +uuid = "56ddb016-857b-54e1-b83d-db4d58db5568" + +[[deps.LoweredCodeUtils]] +deps = ["JuliaInterpreter"] +git-tree-sha1 = "31e27f0b0bf0df3e3e951bfcc43fe8c730a219f6" +uuid = "6f1432cf-f94c-5a45-995e-cdbf5db27b0b" +version = "2.4.5" + +[[deps.MacroTools]] +deps = ["Markdown", "Random"] +git-tree-sha1 = "2fa9ee3e63fd3a4f7a9a4f4744a52f4856de82df" +uuid = "1914dd2f-81c6-5fcd-8719-6d5c9610ff09" +version = "0.5.13" + +[[deps.Markdown]] +deps = ["Base64"] +uuid = "d6f4376e-aef5-505a-96c1-9c027394607a" + +[[deps.MathOptInterface]] +deps = ["BenchmarkTools", "CodecBzip2", "CodecZlib", "DataStructures", "ForwardDiff", "JSON", "LinearAlgebra", "MutableArithmetics", "NaNMath", "OrderedCollections", "PrecompileTools", "Printf", "SparseArrays", "SpecialFunctions", "Test", "Unicode"] +git-tree-sha1 = "e8b98c868029d007102dc5f98986c81f33b0ec37" +uuid = "b8f27783-ece8-5eb3-8dc8-9495eed66fee" +version = "1.26.0" + +[[deps.MbedTLS_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "c8ffd9c3-330d-5841-b78e-0817d7145fa1" +version = "2.28.2+0" + +[[deps.Missings]] +deps = ["DataAPI"] +git-tree-sha1 = "f66bdc5de519e8f8ae43bdc598782d35a25b1272" +uuid = "e1d29d7a-bbdc-5cf2-9ac0-f12de2c33e28" +version = "1.1.0" + +[[deps.Mmap]] +uuid = "a63ad114-7e13-5084-954f-fe012c677804" + +[[deps.MozillaCACerts_jll]] +uuid = "14a3606d-f60d-562e-9121-12d972cd8159" +version = "2022.10.11" + +[[deps.MutableArithmetics]] +deps = ["LinearAlgebra", "SparseArrays", "Test"] +git-tree-sha1 = "302fd161eb1c439e4115b51ae456da4e9984f130" +uuid = "d8a4904e-b15c-11e9-3269-09a3773c0cb0" +version = "1.4.1" + +[[deps.NaNMath]] +deps = ["OpenLibm_jll"] +git-tree-sha1 = "0877504529a3e5c3343c6f8b4c0381e57e4387e4" +uuid = "77ba4419-2d1f-58cd-9bb1-8ffee604a2e3" +version = "1.0.2" + +[[deps.NearestNeighbors]] +deps = ["Distances", "StaticArrays"] +git-tree-sha1 = "ded64ff6d4fdd1cb68dfcbb818c69e144a5b2e4c" +uuid = "b8a86587-4115-5ab1-83bc-aa920d37bbce" +version = "0.4.16" + +[[deps.NetworkOptions]] +uuid = "ca575930-c2e3-43a9-ace4-1e988b2c1908" +version = "1.2.0" + +[[deps.OpenBLAS_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "Libdl"] +uuid = "4536629a-c528-5b80-bd46-f80d51c5b363" +version = "0.3.21+4" + +[[deps.OpenLibm_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "05823500-19ac-5b8b-9628-191a04bc5112" +version = "0.8.1+0" + +[[deps.OpenSpecFun_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "13652491f6856acfd2db29360e1bbcd4565d04f1" +uuid = "efe28fd5-8261-553b-a9e1-b2916fc3738e" +version = "0.5.5+0" + +[[deps.OrderedCollections]] +git-tree-sha1 = "dfdf5519f235516220579f949664f1bf44e741c5" +uuid = "bac558e1-5e72-5ebc-8fee-abe8a469f55d" +version = "1.6.3" + +[[deps.Parsers]] +deps = ["Dates", "PrecompileTools", "UUIDs"] +git-tree-sha1 = "8489905bcdbcfac64d1daa51ca07c0d8f0283821" +uuid = "69de0a69-1ddd-5017-9359-2bf0b02dc9f0" +version = "2.8.1" + +[[deps.Pkg]] +deps = ["Artifacts", "Dates", "Downloads", "FileWatching", "LibGit2", "Libdl", "Logging", "Markdown", "Printf", "REPL", "Random", "SHA", "Serialization", "TOML", "Tar", "UUIDs", "p7zip_jll"] +uuid = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f" +version = "1.9.0" + +[[deps.PooledArrays]] +deps = ["DataAPI", "Future"] +git-tree-sha1 = "36d8b4b899628fb92c2749eb488d884a926614d3" +uuid = "2dfb63ee-cc39-5dd5-95bd-886bf059d720" +version = "1.4.3" + +[[deps.PrecompileTools]] +deps = ["Preferences"] +git-tree-sha1 = "03b4c25b43cb84cee5c90aa9b5ea0a78fd848d2f" +uuid = "aea7be01-6a6a-4083-8856-8a6e6704d82a" +version = "1.2.0" + +[[deps.Preferences]] +deps = ["TOML"] +git-tree-sha1 = "00805cd429dcb4870060ff49ef443486c262e38e" +uuid = "21216c6a-2e73-6563-6e65-726566657250" +version = "1.4.1" + +[[deps.PrettyTables]] +deps = ["Crayons", "LaTeXStrings", "Markdown", "PrecompileTools", "Printf", "Reexport", "StringManipulation", "Tables"] +git-tree-sha1 = "88b895d13d53b5577fd53379d913b9ab9ac82660" +uuid = "08abe8d2-0d0c-5749-adfa-8a2ac140af0d" +version = "2.3.1" + +[[deps.Printf]] +deps = ["Unicode"] +uuid = "de0858da-6303-5e67-8744-51eddeeeb8d7" + +[[deps.Profile]] +deps = ["Printf"] +uuid = "9abbd945-dff8-562f-b5e8-e1ebf5ef1b79" + +[[deps.REPL]] +deps = ["InteractiveUtils", "Markdown", "Sockets", "Unicode"] +uuid = "3fa0cd96-eef1-5676-8a61-b3b8758bbffb" + +[[deps.Random]] +deps = ["SHA", "Serialization"] +uuid = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" + +[[deps.Reexport]] +git-tree-sha1 = "45e428421666073eab6f2da5c9d310d99bb12f9b" +uuid = "189a3867-3050-52da-a836-e630ba90ab69" +version = "1.2.2" + +[[deps.Requires]] +deps = ["UUIDs"] +git-tree-sha1 = "838a3a4188e2ded87a4f9f184b4b0d78a1e91cb7" +uuid = "ae029012-a4dd-5104-9daa-d747884805df" +version = "1.3.0" + +[[deps.Revise]] +deps = ["CodeTracking", "Distributed", "FileWatching", "JuliaInterpreter", "LibGit2", "LoweredCodeUtils", "OrderedCollections", "Pkg", "REPL", "Requires", "UUIDs", "Unicode"] +git-tree-sha1 = "12aa2d7593df490c407a3bbd8b86b8b515017f3e" +uuid = "295af30f-e4ad-537b-8983-00126c2a3abe" +version = "3.5.14" + +[[deps.SHA]] +uuid = "ea8e919c-243c-51af-8825-aaa63cd721ce" +version = "0.7.0" + +[[deps.SentinelArrays]] +deps = ["Dates", "Random"] +git-tree-sha1 = "0e7508ff27ba32f26cd459474ca2ede1bc10991f" +uuid = "91c51154-3ec4-41a3-a24f-3f23e20d615c" +version = "1.4.1" + +[[deps.Serialization]] +uuid = "9e88b42a-f829-5b0c-bbe9-9e923198166b" + +[[deps.Sockets]] +uuid = "6462fe0b-24de-5631-8697-dd941f90decc" + +[[deps.SortingAlgorithms]] +deps = ["DataStructures"] +git-tree-sha1 = "66e0a8e672a0bdfca2c3f5937efb8538b9ddc085" +uuid = "a2af1166-a08f-5f64-846c-94a0d3cef48c" +version = "1.2.1" + +[[deps.SparseArrays]] +deps = ["Libdl", "LinearAlgebra", "Random", "Serialization", "SuiteSparse_jll"] +uuid = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" + +[[deps.SpecialFunctions]] +deps = ["IrrationalConstants", "LogExpFunctions", "OpenLibm_jll", "OpenSpecFun_jll"] +git-tree-sha1 = "e2cfc4012a19088254b3950b85c3c1d8882d864d" +uuid = "276daf66-3868-5448-9aa4-cd146d93841b" +version = "2.3.1" + + [deps.SpecialFunctions.extensions] + SpecialFunctionsChainRulesCoreExt = "ChainRulesCore" + + [deps.SpecialFunctions.weakdeps] + ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" + +[[deps.StaticArrays]] +deps = ["LinearAlgebra", "PrecompileTools", "Random", "StaticArraysCore"] +git-tree-sha1 = "bf074c045d3d5ffd956fa0a461da38a44685d6b2" +uuid = "90137ffa-7385-5640-81b9-e52037218182" +version = "1.9.3" + + [deps.StaticArrays.extensions] + StaticArraysChainRulesCoreExt = "ChainRulesCore" + StaticArraysStatisticsExt = "Statistics" + + [deps.StaticArrays.weakdeps] + ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" + Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" + +[[deps.StaticArraysCore]] +git-tree-sha1 = "36b3d696ce6366023a0ea192b4cd442268995a0d" +uuid = "1e83bf80-4336-4d27-bf5d-d5a4f845583c" +version = "1.4.2" + +[[deps.Statistics]] +deps = ["LinearAlgebra", "SparseArrays"] +uuid = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" +version = "1.9.0" + +[[deps.StatsAPI]] +deps = ["LinearAlgebra"] +git-tree-sha1 = "1ff449ad350c9c4cbc756624d6f8a8c3ef56d3ed" +uuid = "82ae8749-77ed-4fe6-ae5f-f523153014b0" +version = "1.7.0" + +[[deps.StringManipulation]] +deps = ["PrecompileTools"] +git-tree-sha1 = "a04cabe79c5f01f4d723cc6704070ada0b9d46d5" +uuid = "892a3eda-7b42-436c-8928-eab12a02cf0e" +version = "0.3.4" + +[[deps.SuiteSparse_jll]] +deps = ["Artifacts", "Libdl", "Pkg", "libblastrampoline_jll"] +uuid = "bea87d4a-7f5b-5778-9afe-8cc45184846c" +version = "5.10.1+6" + +[[deps.TOML]] +deps = ["Dates"] +uuid = "fa267f1f-6049-4f14-aa54-33bafae1ed76" +version = "1.0.3" + +[[deps.TableTraits]] +deps = ["IteratorInterfaceExtensions"] +git-tree-sha1 = "c06b2f539df1c6efa794486abfb6ed2022561a39" +uuid = "3783bdb8-4a98-5b6b-af9a-565f29a5fe9c" +version = "1.0.1" + +[[deps.Tables]] +deps = ["DataAPI", "DataValueInterfaces", "IteratorInterfaceExtensions", "LinearAlgebra", "OrderedCollections", "TableTraits"] +git-tree-sha1 = "cb76cf677714c095e535e3501ac7954732aeea2d" +uuid = "bd369af6-aec1-5ad0-b16a-f7cc5008161c" +version = "1.11.1" + +[[deps.Tar]] +deps = ["ArgTools", "SHA"] +uuid = "a4e569a6-e804-4fa4-b0f3-eef7a1d5b13e" +version = "1.10.0" + +[[deps.Test]] +deps = ["InteractiveUtils", "Logging", "Random", "Serialization"] +uuid = "8dfed614-e22c-5e08-85e1-65c5234f0b40" + +[[deps.TranscodingStreams]] +git-tree-sha1 = "54194d92959d8ebaa8e26227dbe3cdefcdcd594f" +uuid = "3bb67fe8-82b1-5028-8e26-92a6c54297fa" +version = "0.10.3" +weakdeps = ["Random", "Test"] + + [deps.TranscodingStreams.extensions] + TestExt = ["Test", "Random"] + +[[deps.UUIDs]] +deps = ["Random", "SHA"] +uuid = "cf7118a7-6976-5b1a-9a39-7adc72f591a4" + +[[deps.Unicode]] +uuid = "4ec0a83e-493e-50e2-b9ac-8f72acf5a8f5" + +[[deps.WeakRefStrings]] +deps = ["DataAPI", "InlineStrings", "Parsers"] +git-tree-sha1 = "b1be2855ed9ed8eac54e5caff2afcdb442d52c23" +uuid = "ea10d353-3f73-51f8-a26c-33c1cb351aa5" +version = "1.4.2" + +[[deps.WorkerUtilities]] +git-tree-sha1 = "cd1659ba0d57b71a464a29e64dbc67cfe83d54e7" +uuid = "76eceee3-57b5-4d4a-8e66-0e911cebbf60" +version = "1.6.1" + +[[deps.ZipFile]] +deps = ["Libdl", "Printf", "Zlib_jll"] +git-tree-sha1 = "f492b7fe1698e623024e873244f10d89c95c340a" +uuid = "a5390f91-8eb1-5f08-bee0-b1d1ffed6cea" +version = "0.10.1" + +[[deps.Zlib_jll]] +deps = ["Libdl"] +uuid = "83775a58-1f1d-513f-b197-d71354ab007a" +version = "1.2.13+0" + +[[deps.libblastrampoline_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "8e850b90-86db-534c-a0d3-1478176c7d93" +version = "5.7.0+0" + +[[deps.nghttp2_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "8e850ede-7688-5339-a07c-302acd2aaf8d" +version = "1.48.0+0" + +[[deps.p7zip_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "3f19e933-33d8-53b3-aaab-bd5110c3b7a0" +version = "17.4.0+0" diff --git a/Project.toml b/Project.toml new file mode 100644 index 0000000..b0d9bb3 --- /dev/null +++ b/Project.toml @@ -0,0 +1,13 @@ +[deps] +CRC = "44b605c4-b955-5f2b-9b6d-d2bd01d3d205" +CSV = "336ed68f-0bac-5ca0-87d4-7b16caf5d00b" +DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0" +Geodesy = "0ef565a4-170c-5f04-8de2-149903a85f3d" +Gurobi = "2e9cd046-0924-5485-92f1-d5272153d98b" +JSON = "682c06a0-de6a-54ab-a142-c8b1cf79cde6" +JuMP = "4076af6c-e467-56ae-b986-b466b2749572" +NearestNeighbors = "b8a86587-4115-5ab1-83bc-aa920d37bbce" +OrderedCollections = "bac558e1-5e72-5ebc-8fee-abe8a469f55d" +Printf = "de0858da-6303-5e67-8744-51eddeeeb8d7" +Revise = "295af30f-e4ad-537b-8983-00126c2a3abe" +ZipFile = "a5390f91-8eb1-5f08-bee0-b1d1ffed6cea" diff --git a/dist.jl b/dist.jl new file mode 100644 index 0000000..1008650 --- /dev/null +++ b/dist.jl @@ -0,0 +1,107 @@ +# RELOG: Reverse Logistics Optimization +# Copyright (C) 2020-2024, UChicago Argonne, LLC. All rights reserved. +# Released under the modified BSD license. See COPYING.md for more details. + +using Geodesy +using NearestNeighbors +using DataFrames +using CRC +using ZipFile +using Statistics + +crc32 = crc(CRC_32) + +abstract type DistanceMetric end + +Base.@kwdef mutable struct KnnDrivingDistance <: DistanceMetric + tree = nothing + ratios = nothing +end + +mutable struct EuclideanDistance <: DistanceMetric end + +function _calculate_distance( + source_lat, + source_lon, + dest_lat, + dest_lon, + ::EuclideanDistance, +)::Float64 + x = LLA(source_lat, source_lon, 0.0) + y = LLA(dest_lat, dest_lon, 0.0) + return round(euclidean_distance(x, y) / 1000.0, digits=3) +end + +function _download_file(url, output, expected_crc32)::Nothing + if isfile(output) + return + end + mkpath(dirname(output)) + @info "Downloading: $url" + fname = download(url) + actual_crc32 = open(crc32, fname) + expected_crc32 == actual_crc32 || error("CRC32 mismatch") + cp(fname, output) + return +end + +function _download_zip(url, outputdir, expected_output_file, expected_crc32)::Nothing + if isfile(expected_output_file) + return + end + mkpath(outputdir) + @info "Downloading: $url" + zip_filename = download(url) + actual_crc32 = open(crc32, zip_filename) + expected_crc32 == actual_crc32 || error("CRC32 mismatch") + open(zip_filename) do zip_file + zr = ZipFile.Reader(zip_file) + for file in zr.files + open(joinpath(outputdir, file.name), "w") do output_file + write(output_file, read(file)) + end + end + end + return +end + +function _calculate_distance( + source_lat, + source_lon, + dest_lat, + dest_lon, + metric::KnnDrivingDistance, +)::Float64 + if metric.tree === nothing + basedir = joinpath(dirname(@__FILE__), "data") + csv_filename = joinpath(basedir, "dist_driving.csv") + + # Download pre-computed driving data + if !isfile(csv_filename) + _download_zip( + "https://axavier.org/RELOG/0.6/data/dist_driving_0b9a6ad6.zip", + basedir, + csv_filename, + 0x0b9a6ad6, + ) + end + + # Fit kNN model + df = DataFrame(CSV.File(csv_filename, missingstring="NaN")) + dropmissing!(df) + coords = Matrix(df[!, [:source_lat, :source_lon, :dest_lat, :dest_lon]])' + metric.ratios = Matrix(df[!, [:ratio]]) + metric.tree = KDTree(coords) + end + + # Compute Euclidean distance + dist_euclidean = + _calculate_distance(source_lat, source_lon, dest_lat, dest_lon, EuclideanDistance()) + + # Predict ratio + idxs, _ = knn(metric.tree, [source_lat, source_lon, dest_lat, dest_lon], 5) + ratio_pred = mean(metric.ratios[idxs]) + dist_pred = round(dist_euclidean * ratio_pred, digits=3) + isfinite(dist_pred) || error("non-finite distance detected: $dist_pred") + return dist_pred +end diff --git a/jumpext.jl b/jumpext.jl new file mode 100644 index 0000000..5ac3ac4 --- /dev/null +++ b/jumpext.jl @@ -0,0 +1,48 @@ +# This file extends some JuMP functions so that decision variables can be safely +# replaced by (constant) floating point numbers. + +using Printf +using JuMP +using OrderedCollections + +import JuMP: value, fix, set_name + +function value(x::Float64) + return x +end + +function fix(x::Float64, v::Float64; force) + return abs(x - v) < 1e-6 || error("Value mismatch: $x != $v") +end + +function set_name(x::Number, n::String) + # nop +end + +function _init(model::JuMP.Model, key::Symbol)::OrderedDict + if !(key in keys(object_dictionary(model))) + model[key] = OrderedDict() + end + return model[key] +end + +function _set_names!(model::JuMP.Model) + @info "Setting variable and constraint names..." + time_varnames = @elapsed begin + _set_names!(object_dictionary(model)) + end + @info @sprintf("Set names in %.2f seconds", time_varnames) +end + +function _set_names!(dict::Dict) + for name in keys(dict) + dict[name] isa AbstractDict || continue + for idx in keys(dict[name]) + if dict[name][idx] isa AffExpr + continue + end + idx_str = join(map(string, idx), ",") + set_name(dict[name][idx], "$name[$idx_str]") + end + end +end diff --git a/model-1.jl b/model-1.jl new file mode 100644 index 0000000..03d94cb --- /dev/null +++ b/model-1.jl @@ -0,0 +1,159 @@ +using JuMP +using OrderedCollections +using Gurobi +using Random +using Printf + +dict = OrderedDict + +macro pprint(var) + quote + println(string($(QuoteNode(var)))) + v = round.($(esc(var)), digits=2) + display(v) + println() + end +end + +macro pprint_jump(var) + quote + println(string($(QuoteNode(var)))) + v = round.(value.($(esc(var))), digits=2) + display(v) + println() + end +end + +function model1() + Random.seed!(42) + + model = Model( + optimizer_with_attributes( + Gurobi.Optimizer, + "NonConvex" => 2, + ), + ) + + # Data + # ------------------------------------------------------------------------- + n_plants = 5 + n_components = 2 + plants = 1:n_plants + components = 1:n_components + initial_amount = [rand(1:1000) for _ in plants, _ in components] + revenue = [rand(1:1000) for _ in plants] + tr_cost = [ + rand(1:50) + for _ in plants, _ in plants + ] + + @show plants + @show components + @show initial_amount + @show revenue + + # Decision variables + # ------------------------------------------------------------------------- + @variable(model, y_total[plants, plants], lower_bound = 0) + @variable(model, y[plants, plants, components], lower_bound = 0) + @variable(model, z_disp_total[plants], lower_bound = 0) + @variable(model, z_disp[plants, components], lower_bound = 0) + @variable(model, z_avail_total[plants]) + @variable(model, z_avail[plants, components]) + @variable(model, alpha[plants, components]) + + # Objective + # ------------------------------------------------------------------------- + @objective( + model, + Max, + sum( + z_disp_total[p] * revenue[p] + for p in plants + ) + - + sum( + y_total[p, q] * tr_cost[p, q] + for p in plants, q in plants + ) + ) + + # Constraints + # ------------------------------------------------------------------------- + + # Definition of total sent + @constraint( + model, + eq_y_total_def[p in plants, q in plants], + y_total[p, q] == sum(y[p, q, c] for c in components) + ) + + # Definition of total disposed + @constraint( + model, + eq_z_disp_total_def[p in plants], z_disp_total[p] == sum(z_disp[p, c] for c in components) + ) + + # Definition of available amount + @constraint( + model, + eq_z_avail_total[p in plants], + z_avail_total[p] == sum(z_avail[p, c] for c in components) + ) + + # Definition of available component + @constraint( + model, + eq_z_avail[p in plants, c in components], + z_avail[p, c] == initial_amount[p, c] + sum(y[q, p, c] for q in plants) + ) + + # Mass balance + @constraint( + model, + eq_balance[p in plants], + z_avail_total[p] == z_disp_total[p] + sum(y_total[p, q] for q in plants) + ) + + # Available proportion + @constraint( + model, + eq_alpha_avail[p in plants, c in components], + z_avail[p, c] == alpha[p, c] * z_avail_total[p] + ) + + # Sending proportion + @constraint( + model, + eq_alpha_send[p in plants, q in plants, c in components], + y[p, q, c] == alpha[p, c] * y_total[p, q] + ) + + # Disposal proportion + @constraint( + model, + eq_alpha_disp[p in plants, c in components], + z_disp[p, c] == alpha[p, c] * z_disp_total[p] + ) + + # Run + # ------------------------------------------------------------------------- + print(model) + optimize!(model) + + # Print solution + # ------------------------------------------------------------------------- + @pprint initial_amount + @pprint revenue + @pprint tr_cost + + @pprint_jump y_total + @pprint_jump y + @pprint_jump z_disp_total + @pprint_jump z_disp + @pprint_jump z_avail_total + @pprint_jump z_avail + @pprint_jump alpha +end + +model1() \ No newline at end of file diff --git a/model-2.jl b/model-2.jl new file mode 100644 index 0000000..8c706ce --- /dev/null +++ b/model-2.jl @@ -0,0 +1,282 @@ +using JuMP +using OrderedCollections +using Gurobi +using Random +using Printf +using DataFrames +using CSV + +dict = OrderedDict + +function model2() + Random.seed!(42) + + model = Model( + optimizer_with_attributes( + Gurobi.Optimizer, + ), + ) + + # Data + # ------------------------------------------------------------------------- + components = ["film", "paper", "cardboard"] + centers = [ + "Chicago", + "New York City", + "Los Angeles", + "Houston", + "Phoenix", + "Philadelphia", + "San Antonio", + "San Diego", + "Dallas", + "San Jose", + ] + plants = [ + "Chicago", + "Phoenix", + "Dallas", + ] + products = [ + "film bale", + "cardboard bale" + ] + initial_amount = dict( + (q, c) => rand(1:1000) + for q in centers, c in components + ) + cost_tr = dict( + (q, p) => rand(1:10) + for q in centers, p in plants + ) + cost_open = dict( + p => rand(5000:10000) + for p in plants + ) + cost_var = dict( + p => rand(5:10) + for p in plants + ) + revenue = dict( + (p, m) => rand(10:20) + for p in plants, m in products + ) + alpha = dict( + "film bale" => dict( + "film" => dict( + "film" => 0.98, + "paper" => 0, + "cardboard" => 0, + ), + "paper" => dict( + "film" => 0, + "paper" => 0.02, + "cardboard" => 0, + ), + "cardboard" => dict( + "film" => 0, + "paper" => 0, + "cardboard" => 0.02, + ), + ), + "cardboard bale" => dict( + "film" => dict( + "film" => 0.0, + "paper" => 0.0, + "cardboard" => 0.0, + ), + "paper" => dict( + "film" => 0.0, + "paper" => 0.02, + "cardboard" => 0.0, + ), + "cardboard" => dict( + "film" => 0.0, + "paper" => 0.0, + "cardboard" => 0.75, + ), + ), + ) + capacity = dict( + p => rand(10000:50000) + for p in plants + ) + + # Variables + # ------------------------------------------------------------------------- + @variable(model, y[centers, plants, components] >= 0) + @variable(model, y_total[centers, plants]) + @variable(model, x[plants], Bin) + @variable(model, z_avail[plants, components]) + @variable(model, z_prod[plants, products, components]) + + + # Objective + # ------------------------------------------------------------------------- + @objective( + model, + Min, + + # Transportation cost + + sum( + cost_tr[q, p] * y[q, p, c] + for p in plants, q in centers, c in components + ) + + # Opening cost + + sum( + cost_open[p] * x[p] + for p in plants + ) + + # Variable operating cost + + sum( + cost_var[p] * y[q,p,c] + for q in centers, p in plants, c in components + ) + + # Revenue + + sum( + revenue[p,m] * z_prod[p,m,c] + for p in plants, m in products, c in components + ) + ) + + + # Constraints + # ------------------------------------------------------------------------- + + # Flow balance at centers: + @constraint( + model, + eq_flow_balance[q in centers, c in components], + sum(y[q,p,c] for p in plants) == initial_amount[q, c] + ) + + # Total flow: + @constraint( + model, + eq_total_flow[q in centers, p in plants], + y_total[q,p] == sum(y[q,p,c] for c in components) + ) + + # Center balance mix: + @constraint( + model, + eq_mix[q in centers, p in plants, c in components], + y[q,p,c] == initial_amount[q,c] / sum(initial_amount[q,d] for d in components) * y_total[q,p] + ) + + # Plant capacity + @constraint( + model, + eq_capacity[p in plants], + sum(y_total[q,p] for q in centers) <= capacity[p] * x[p] + ) + + # Amount available + @constraint( + model, + eq_z_avail[p in plants, c in components], + z_avail[p,c] == sum(y[q,p,c] for q in centers) + ) + + # Amount produced + @constraint( + model, + eq_z_prod[p in plants, m in products, c in components], + z_prod[p,m,c] == + sum( + alpha[m][c][d] * + z_avail[p,c] + for d in components + ) + ) + + + # Run + # ------------------------------------------------------------------------- + print(model) + optimize!(model) + + # Report: Transportation + # ------------------------------------------------------------------------- + df = DataFrame() + df."center" = String[] + df."plant" = String[] + df."component" = String[] + df."amount sent (tonne)" = Float64[] + df."transportation cost (\$)" = Float64[] + df."variable operating cost (\$)" = Float64[] + for q in centers, p in plants, c in components + if value(y[q, p, c]) ≈ 0 + continue + end + push!( + df, + [ + q, + p, + c, + value(y[q, p, c]), + cost_tr[q, p] * value(y[q, p, c]), + cost_var[p] * value(y[q,p,c]) + ] + ) + end + CSV.write("output-2/tr.csv", df) + + + # Report: Plant + # ------------------------------------------------------------------------- + df = DataFrame() + df."plant" = String[] + df."is open?" = Float64[] + df."capacity (tonne)" = Float64[] + df."utilization (tonne)" = Float64[] + df."opening cost (\$)" = Float64[] + for p in plants + if value(x[p]) ≈ 0 + continue + end + push!( + df, + [ + p, + value(x[p]), + capacity[p], + sum(value(y_total[q,p]) for q in centers), + cost_open[p] * value(x[p]) + ] + ) + end + CSV.write("output-2/plant.csv", df) + + # Report: Plant Outputs + # ------------------------------------------------------------------------- + df = DataFrame() + df."plant" = String[] + df."product" = String[] + df."component" = String[] + df."amount produced (tonne)" = Float64[] + df."revenue (\$)" = Float64[] + for p in plants, m in products, c in components + if value(z_prod[p, m, c]) ≈ 0 + continue + end + push!( + df, + [ + p, + m, + c, + value(z_prod[p, m, c]), + revenue[p,m] * value(z_prod[p,m,c]) + ] + ) + end + CSV.write("output-2/plant-outputs.csv", df) + +end + +model2() diff --git a/model-3.jl b/model-3.jl new file mode 100644 index 0000000..59ad962 --- /dev/null +++ b/model-3.jl @@ -0,0 +1,1197 @@ +# RELOG: Reverse Logistics Optimization +# Copyright (C) 2020-2024, UChicago Argonne, LLC. All rights reserved. +# Released under the modified BSD license. See COPYING.md for more details. + +using CSV +using DataFrames +using Gurobi +using JSON +using JuMP +using OrderedCollections +using Random + +include("jumpext.jl") +include("dist.jl") + +dict = OrderedDict +Time = Int +Random.seed!(42) + +# Structs +# ========================================================================= + +Base.@kwdef struct Component + name::String +end + +Base.@kwdef struct Product + name::String + comp::Vector{Component} +end + +Base.@kwdef struct Center + name::String + latitude::Float64 + longitude::Float64 + prod_out::Vector{Product} +end + +Base.@kwdef struct Plant + name::String + latitude::Float64 + longitude::Float64 + prod_out::Vector{Product} + prod_in::Product +end + +Base.@kwdef struct Emission + name::String +end + +Base.show( + io::IO, + p::Union{Component,Product,Center,Plant,Emission}, +) = print(io, p.name) + +Base.@kwdef struct Instance + T::UnitRange{Int} + centers::Vector{Center} + plants::Vector{Plant} + products::Vector{Product} + emissions::Vector{Emission} + alpha_mix::dict{Tuple{Plant,Product,Component,Component},Float64} + alpha_plant_emission::dict{Tuple{Plant,Emission,Time},Float64} + alpha_tr_emission::dict{Tuple{Product,Emission,Time},Float64} + c_acq::dict{Tuple{Center,Product,Time},Float64} + c_center_disp::dict{Tuple{Center,Product,Time},Float64} + c_emission::dict{Tuple{Emission,Time},Float64} + c_fix::dict{Tuple{Plant,Time},Float64} + c_open::dict{Tuple{Plant,Time},Float64} + c_plant_disp::dict{Tuple{Plant,Product,Time},Float64} + c_store::dict{Tuple{Center,Product,Time},Float64} + c_tr::dict{Tuple{Product,Time},Float64} + c_var::dict{Tuple{Plant,Time},Float64} + m_cap::dict{Plant,Float64} + m_center_disp::dict{Tuple{Product,Time},Float64} + m_dist::dict{Tuple{Union{Center,Plant},Plant},Float64} + m_emission::dict{Tuple{Emission,Time},Float64} + m_init::dict{Tuple{Center,Product,Component,Time},Float64} + m_plant_disp::dict{Tuple{Plant,Product,Time},Float64} + m_store::dict{Tuple{Center,Product,Time},Float64} +end + + +# Generate +# ============================================================================== + +function generate_data() + # Time window + T = 1:2 + + # Cities + cities_a = dict( + "Chicago" => [41.881832, -87.623177], + "New York City" => [40.712776, -74.005974], + "Los Angeles" => [34.052235, -118.243683], + "Houston" => [29.760427, -95.369804], + "Phoenix" => [33.448376, -112.074036], + "Philadelphia" => [39.952583, -75.165222], + "San Antonio" => [29.424122, -98.493629], + "San Diego" => [32.715736, -117.161087], + "Dallas" => [32.776664, -96.796988], + "San Jose" => [37.338208, -121.886329], + ) + + cities_b = dict( + "Chicago" => [41.881832, -87.623177], + "Phoenix" => [33.448376, -112.074036], + "Dallas" => [32.776664, -96.796988], + ) + + # Components + film = Component("Film") + paper = Component("Paper") + cardboard = Component("Cardboard") + + # Products + waste = Product( + name="Waste", + comp=[film, paper, cardboard], + ) + film_bale = Product( + name="Film bale", + comp=[film, paper, cardboard], + ) + cardboard_bale = Product( + name="Cardboard bale", + comp=[paper, cardboard], + ) + cardboard_sheets = Product( + name="Cardboard sheets", + comp=[cardboard], + ) + products = [waste, film_bale, cardboard_bale, cardboard_sheets] + + # Centers + centers = [ + Center( + name="Collection ($city_name)", + latitude=city_lat, + longitude=city_lon, + prod_out=[waste], + ) + for (city_name, (city_lat, city_lon)) in cities_a + ] + + # Plants + plants_a = [ + Plant( + name="MRF ($city_name)", + latitude=city_lat, + longitude=city_lon, + prod_in=waste, + prod_out=[film_bale, cardboard_bale], + ) + for (city_name, (city_lat, city_lon)) in cities_b + ] + plants_b = [ + Plant( + name="Paper Mill ($city_name)", + latitude=city_lat, + longitude=city_lon, + prod_in=cardboard_bale, + prod_out=[cardboard_sheets], + ) + for (city_name, (city_lat, city_lon)) in cities_b + ] + plants = [plants_a; plants_b] + + # Emissions + emissions = [ + Emission("CO2"), + ] + + alpha_mix = dict( + (p, r, cin, cout) => 0.0 + for p in plants + for cin in p.prod_in.comp + for r in p.prod_out + for cout in r.comp + ) + for p in plants_a + alpha_mix[p, film_bale, film, film] = 0.98 + alpha_mix[p, film_bale, paper, paper] = 0.02 + alpha_mix[p, film_bale, cardboard, cardboard] = 0.02 + alpha_mix[p, cardboard_bale, paper, paper] = 0.02 + alpha_mix[p, cardboard_bale, cardboard, cardboard] = 0.75 + end + for p in plants_b + alpha_mix[p, cardboard_sheets, cardboard, cardboard] = 0.95 + end + alpha_plant_emission = dict( + (p, s, t) => 0.01 + for p in plants, s in emissions, t in T + ) + alpha_tr_emission = dict( + (r, s, t) => 0.01 + for r in products, s in emissions, t in T + ) + c_acq = dict( + (q, r, t) => 1.0 + for q in centers + for r in q.prod_out, t in T + ) + c_center_disp = dict( + (q, r, t) => 0 + for q in centers + for r in q.prod_out + for t in T + ) + c_emission = dict( + (s, t) => 0.01 + for s in emissions, t in T + ) + c_fix = dict( + (p, t) => 1_000.0 + for p in plants, t in T + ) + c_open = dict( + (p, t) => 10_000.0 + for p in plants, t in T + ) + c_plant_disp = dict( + (p, r, t) => (r == cardboard_sheets ? -100.0 : -10.0) + for p in plants + for r in p.prod_out, t in T + ) + c_store = dict( + (q, r, t) => 1.0 + for q in centers + for r in q.prod_out, t in T + ) + c_tr = dict( + (r, t) => 0.05 + for r in products, t in T + ) + c_var = dict( + (p, t) => 1.0 + for p in plants, t in T + ) + m_cap = dict( + p => 50000.0 + for p in plants + ) + m_center_disp = dict( + (r, t) => 0.0 + for r in products, t in T + ) + metric = KnnDrivingDistance() + m_dist = dict( + (p, q) => _calculate_distance( + p.latitude, + p.longitude, + q.latitude, + q.longitude, + metric, + ) + for p in [plants; centers], q in plants + ) + m_emission = dict( + (s, t) => 1_000_000 + for s in emissions, t in T + ) + m_init = dict() + for q in centers, r in q.prod_out + ratio = dict( + c => rand(1:10) + for c in r.comp + ) + total = dict( + t => rand(1:1000) + for t in T + ) + for c in r.comp, t in T + m_init[q, r, c, t] = ratio[c] * total[t] + end + end + m_plant_disp = dict( + (p, r, t) => 1_000_000 + for p in plants + for r in p.prod_out + for t in T + ) + m_store = dict( + (q, r, t) => 1_000 + for q in centers + for r in q.prod_out, t in T + ) + + return Instance(; + T, + centers, + plants, + products, + emissions, + alpha_mix, + alpha_plant_emission, + alpha_tr_emission, + c_acq, + c_center_disp, + c_emission, + c_fix, + c_open, + c_plant_disp, + c_store, + c_tr, + c_var, + m_cap, + m_center_disp, + m_dist, + m_emission, + m_init, + m_plant_disp, + m_store + ) +end + +# Write +# ============================================================================== + +function write_json(data, filename) + json = dict() + json["parameters"] = dict( + "time horizon (years)" => data.T.stop, + ) + json["products"] = dict( + r.name => dict( + "components" => [c.name for c in r.comp], + "disposal limit (tonne)" => [ + data.m_center_disp[r, t] + for t in data.T + ], + "transportation cost (\$/km/tonne)" => [ + data.c_tr[r, t] + for t in data.T + ], + "transportation emissions (tonne/km/tonne)" => dict( + s => [ + data.alpha_tr_emission[r, s, t] + for t in data.T + ] + for s in data.emissions + ) + ) + for r in data.products + ) + json["centers"] = dict( + q.name => dict( + "latitude" => q.latitude, + "longitude" => q.longitude, + "output" => dict( + r.name => dict( + "initial amount (tonne)" => [ + data.m_init[q, r, c, t] + for c in r.comp, t in data.T + ], + "disposal cost (\$/tonne)" => [ + data.c_center_disp[q, r, t] + for t in data.T + ], + "storage cost (\$/tonne)" => [ + data.c_store[q, r, t] + for t in data.T + ], + "storage limit (tonne)" => [ + data.m_store[q, r, t] + for t in data.T + ], + "acquisition cost (\$/tonne)" => [ + data.c_acq[q, r, t] + for t in data.T + ], + ) + for r in q.prod_out + ) + ) + for q in data.centers + ) + json["plants"] = dict( + p.name => dict( + "latitude" => p.latitude, + "longitude" => p.longitude, + "input" => p.prod_in.name, + "output" => dict( + r.name => dict( + "output matrix" => [ + data.alpha_mix[p, r, c_in, c_out] + for c_in in p.prod_in.comp, c_out in r.comp + ], + "disposal limit (tonne)" => [ + data.m_plant_disp[p, r, t] + for t in data.T + ], + "disposal cost (\$/tonne)" => [ + data.c_plant_disp[p, r, t] + for t in data.T + ], + ) + for r in p.prod_out + ), + "fixed operating cost (\$)" => [ + data.c_fix[p, t] + for t in data.T + ], + "variable operating cost (\$/tonne)" => [ + data.c_var[p, t] + for t in data.T + ], + "opening cost (\$)" => [ + data.c_open[p, t] + for t in data.T + ], + "capacity (tonne)" => data.m_cap[p], + "emissions (tonne/tonne)" => dict( + s => [ + data.alpha_plant_emission[p, s, t] + for t in data.T + ] + for s in data.emissions + ) + ) + for p in data.plants + ) + json["emissions"] = dict( + s.name => dict( + "penalty (\$/tonne)" => [ + data.c_emission[s, t] + for t in data.T + ], + "limit (tonne)" => [ + data.m_emission[s, t] + for t in data.T + ] + ) + for s in data.emissions + ) + open(filename, "w") do io + JSON.print(io, json, 2) + end +end + +# Read +# ============================================================================== +function read_json(filename) + json = JSON.parsefile(filename) + T = 1:json["parameters"]["time horizon (years)"] + centers = [] + components_by_name = dict() + emissions = [] + emissions_by_name = dict() + plants = [] + products = [] + products_by_name = dict() + alpha_mix = dict() + alpha_plant_emission = dict() + alpha_tr_emission = dict() + c_acq = dict() + c_center_disp = dict() + c_emission = dict() + c_fix = dict() + c_open = dict() + c_plant_disp = dict() + c_store = dict() + c_tr = dict() + c_var = dict() + m_cap = dict() + m_center_disp = dict() + m_emission = dict() + m_init = dict() + m_plant_disp = dict() + m_store = dict() + + for (emission_name, emission_data) in json["emissions"] + s = Emission(emission_name) + emissions_by_name[emission_name] = s + push!(emissions, s) + for t in T + c_emission[s, t] = emission_data["penalty (\$/tonne)"][t] + m_emission[s, t] = emission_data["limit (tonne)"][t] + end + end + + for (name, prod_data) in json["products"] + comp = [] + for (comp_name) in prod_data["components"] + if comp_name ∉ keys(components_by_name) + components_by_name[comp_name] = Component(comp_name) + end + push!(comp, components_by_name[comp_name]) + end + r = Product(name, comp) + products_by_name[name] = r + push!(products, r) + for t in T + m_center_disp[r, t] = prod_data["disposal limit (tonne)"][t] + c_tr[r, t] = prod_data["transportation cost (\$/km/tonne)"][t] + end + for (s_name, s_data) in prod_data["transportation emissions (tonne/km/tonne)"] + s = emissions_by_name[s_name] + for t in T + alpha_tr_emission[r, s, t] = s_data[t] + end + end + end + + for (name, center_data) in json["centers"] + latitude = center_data["latitude"] + longitude = center_data["longitude"] + prod_out = [products_by_name[r] for r in keys(center_data["output"])] + q = Center(; name, latitude, longitude, prod_out) + push!(centers, q) + for r in prod_out, t in T + c_acq[q, r, t] = center_data["output"][r.name]["acquisition cost (\$/tonne)"][t] + c_center_disp[q, r, t] = center_data["output"][r.name]["disposal cost (\$/tonne)"][t] + c_store[q, r, t] = center_data["output"][r.name]["storage cost (\$/tonne)"][t] + m_store[q, r, t] = center_data["output"][r.name]["storage limit (tonne)"][t] + for (c_idx, c) in enumerate(r.comp) + m_init[q, r, c, t] = center_data["output"][r.name]["initial amount (tonne)"][t][c_idx] + end + end + end + + for (plant_name, plant_data) in json["plants"] + latitude = plant_data["latitude"] + longitude = plant_data["longitude"] + prod_in = products_by_name[plant_data["input"]] + prod_out = [products_by_name[r] for r in keys(plant_data["output"])] + p = Plant(plant_name, latitude, longitude, prod_out, prod_in) + push!(plants, p) + m_cap[p] = plant_data["capacity (tonne)"] + for t in T + c_fix[p, t] = plant_data["fixed operating cost (\$)"][t] + c_var[p, t] = plant_data["variable operating cost (\$/tonne)"][t] + c_open[p, t] = plant_data["opening cost (\$)"][t] + end + for r in prod_out, + (cin_idx, c_in) in enumerate(prod_in.comp), + (cout_idx, c_out) in enumerate(r.comp) + + alpha_mix[p, r, c_in, c_out] = + plant_data["output"][r.name]["output matrix"][cout_idx][cin_idx] + end + for r in prod_out, t in T + c_plant_disp[p, r, t] = plant_data["output"][r.name]["disposal cost (\$/tonne)"][t] + m_plant_disp[p, r, t] = plant_data["output"][r.name]["disposal limit (tonne)"][t] + end + for (s_name, s_data) in plant_data["emissions (tonne/tonne)"] + s = emissions_by_name[s_name] + for t in T + alpha_plant_emission[p, s, t] = s_data[t] + end + end + end + + metric = KnnDrivingDistance() + m_dist = dict( + (p, q) => _calculate_distance( + p.latitude, + p.longitude, + q.latitude, + q.longitude, + metric, + ) + for p in [plants; centers], q in plants + ) + + return Instance(; + T, + centers, + plants, + products, + emissions, + alpha_mix, + alpha_plant_emission, + alpha_tr_emission, + c_acq, + c_center_disp, + c_emission, + c_fix, + c_open, + c_plant_disp, + c_store, + c_tr, + c_var, + m_cap, + m_center_disp, + m_dist, + m_emission, + m_init, + m_plant_disp, + m_store + ) +end + + +# Run +# ============================================================================== + +function generate_json() + @info "Generating data" + data = generate_data() + + @info "Writing JSON file" + write_json(data, "output-3/case.json") +end + +function solve() + @info "Reading JSON file" + data = read_json("output-3/case.json") + + T = data.T + centers = data.centers + plants = data.plants + products = data.products + emissions = data.emissions + + model = Model(Gurobi.Optimizer) + + # Graph + # ------------------------------------------------------------------------- + E = [] + E_in = dict(src => [] for src in plants) + E_out = dict(src => [] for src in plants ∪ centers) + function push_edge!(src, dst, r) + push!(E, (src, dst, r)) + push!(E_out[src], (dst, r)) + push!(E_in[dst], (src, r)) + end + for r in products + # Plant to plant + for p1 in plants + r ∈ p1.prod_out || continue + for p2 in plants + p1 != p2 || continue + r == p2.prod_in || continue + push_edge!(p1, p2, r) + end + end + # Center to plant + for q in centers + r ∈ q.prod_out || continue + for p in plants + r == p.prod_in || continue + push_edge!(q, p, r) + end + end + end + + # Decision variables + # ------------------------------------------------------------------------- + y = _init(model, :y) + for (q, p, r) in E, c in r.comp, t in T + y[q, p, r, c, t] = @variable(model, lower_bound = 0) + end + + y_total = _init(model, :y_total) + for (q, p, r) in E, t in T + y_total[q, p, r, t] = @variable(model, lower_bound = 0) + end + + z_center_disp = _init(model, :z_center_disp) + for q in centers, r in q.prod_out, c in r.comp, t in T + z_center_disp[q, r, c, t] = @variable(model, lower_bound = 0) + end + + z_center_disp_total = _init(model, :z_center_disp_total) + for q in centers, r in q.prod_out, t in T + z_center_disp_total[q, r, t] = @variable(model, lower_bound = 0) + end + + z_store = _init(model, :z_store) + for q in centers, r in q.prod_out, c in r.comp, t in T + if t == T.stop + z_store[q, r, c, t] = 0.0 + else + z_store[q, r, c, t] = @variable(model, lower_bound = 0) + end + end + + z_store_total = _init(model, :z_store_total) + for q in centers, r in q.prod_out + z_store_total[q, r, 0] = 0.0 + for t in T + if t == T.stop + z_store_total[q, r, t] = 0.0 + else + z_store_total[q, r, t] = @variable(model, lower_bound = 0) + end + end + end + + x_open = _init(model, :x_open) + for p in plants + x_open[p, 0] = 0 + for t in T + x_open[p, t] = @variable(model, binary = true) + end + end + + x_send = _init(model, :x_send) + for p in plants, (q, r) in E_out[p], t in T + x_send[p, q, r, t] = @variable(model, binary = true) + end + + x_disp = _init(model, :x_disp) + for p in plants, r in p.prod_out, t in T + x_disp[p, r, t] = @variable(model, binary = true) + end + + z_prod = _init(model, :z_prod) + for p in plants, r in p.prod_out, c in r.comp, t in T + z_prod[p, r, c, t] = @variable(model, lower_bound = 0) + end + + z_plant_disp = _init(model, :z_plant_disp) + for p in plants, r in p.prod_out, c in r.comp, t in T + z_plant_disp[p, r, c, t] = @variable(model, lower_bound = 0) + end + + z_tr_emissions = _init(model, :z_tr_emissions) + for (q, p, r) in E, s in emissions, t in T + z_tr_emissions[q, p, r, s, t] = @variable(model, lower_bound = 0) + end + + z_plant_emissions = _init(model, :z_plant_emissions) + for p in plants, s in emissions, t in T + z_plant_emissions[p, s, t] = @variable(model, lower_bound = 0) + end + + # Objective function + # ------------------------------------------------------------------------- + obj = AffExpr() + + # Center disposal + for q in centers, r in q.prod_out, t in T + add_to_expression!( + obj, + data.c_center_disp[q, r, t], + z_center_disp_total[q, r, t] + ) + end + + # Center acquisition + for q in centers, r in q.prod_out, c in r.comp, t in T + add_to_expression!( + obj, + data.m_init[q, r, c, t] * data.c_acq[q, r, t] + ) + end + + # Center storage + for q in centers, r in q.prod_out, t in T + add_to_expression!( + obj, + data.c_store[q, r, t], + z_store_total[q, r, t], + ) + end + + # Transportation + for (q, p, r) in E, c in r.comp, t in T + add_to_expression!( + obj, + data.m_dist[q, p] * data.c_tr[r, t], + y[q, p, r, c, t] + ) + end + + # Transportation emissions + for (q, p, r) in E, s in emissions, t in T + add_to_expression!( + obj, + data.c_emission[s, t], + z_tr_emissions[q, p, r, s, t] + ) + end + + # Fixed cost + for p in plants, t in T + add_to_expression!( + obj, + data.c_fix[p, t], + x_open[p, t] + ) + end + + # Opening cost + for p in plants, t in T + add_to_expression!( + obj, + data.c_open[p, t], + x_open[p, t] - x_open[p, t-1] + ) + end + + # Variable operating cost + for (q, p, r) in E, c in r.comp, t in T + add_to_expression!( + obj, + data.c_var[p, t], + y[q, p, r, c, t] + ) + end + + # Plant disposal + for p in plants, r in p.prod_out, c in r.comp, t in T + add_to_expression!( + obj, + data.c_plant_disp[p, r, t], + z_plant_disp[p, r, c, t] + ) + end + + # Plant emissions + for p in plants, s in emissions, t in T + add_to_expression!( + obj, + data.c_emission[s, t], + z_plant_emissions[p, s, t] + ) + end + + @objective(model, Min, obj) + + # Constraints + # ------------------------------------------------------------------------- + eq_balance = _init(model, :eq_balance) + for q in centers, r in q.prod_out, t in T + eq_balance[q, r, t] = @constraint( + model, + sum( + y_total[q, p, r2, t] + for (p, r2) in E_out[q] if r == r2 + ) + z_store_total[q, r, t] == + sum(data.m_init[q, r, c, t] for c in r.comp) + + z_store_total[q, r, t-1] + ) + end + + ratio(q, r, c, t) = ( + data.m_init[q, r, c, t] / + sum(data.m_init[q, r, d, t] for d in r.comp) + ) + + eq_y_total = _init(model, :eq_y_total) + for (q, p, r) in E, t in T + eq_y_total[q, p, r, t] = @constraint( + model, + y_total[q, p, r, t] == sum(y[q, p, r, c, t] for c in r.comp) + ) + end + + eq_split_y = _init(model, :eq_split_y) + for (q, p, r) in E, c in r.comp, t in T + if q ∉ centers + continue + end + eq_split_y[q, p, r, c, t] = @constraint( + model, + y[q, p, r, c, t] == ratio(q, r, c, t) * y_total[q, p, r, t] + ) + end + + eq_split_center_disp = _init(model, :eq_split_center_disp) + for q in centers, r in q.prod_out, c in r.comp, t in T + eq_split_center_disp[q, r, c, t] = @constraint( + model, + z_center_disp[q, r, c, t] == ratio(q, r, c, t) * z_center_disp_total[q, r, t] + ) + end + + eq_split_store = _init(model, :eq_split_store) + for q in centers, r in q.prod_out, c in r.comp, t in T + eq_split_store[q, r, c, t] = @constraint( + model, + z_store[q, r, c, t] == ratio(q, r, c, t) * z_store_total[q, r, t] + ) + end + + eq_center_disposal = _init(model, :eq_center_disposal) + for r in products, t in T + centers_r = [q for q in centers if r ∈ q.prod_out] + if isempty(centers_r) + continue + end + eq_center_disposal[r, t] = @constraint( + model, + sum(z_center_disp_total[q, r, t] for q in centers_r) <= data.m_center_disp[r, t] + ) + end + + eq_center_storage = _init(model, :eq_center_storage) + for q in centers, r in q.prod_out, t in T + eq_center_storage[q, r, t] = @constraint( + model, + z_store_total[q, r, t] <= data.m_store[q, r, t] + ) + end + + eq_tr_emissions = _init(model, :eq_tr_emissions) + for (q, p, r) in E, s in emissions, t in T + eq_tr_emissions[q, p, r, s, t] = @constraint( + model, + z_tr_emissions[q, p, r, s, t] == + data.m_dist[q, p] * data.alpha_tr_emission[r, s, t] * y_total[q, p, r, t] + ) + end + + eq_plant_capacity = _init(model, :eq_plant_capacity) + for p in plants, t in T + eq_plant_capacity[p, t] = @constraint( + model, + sum(y_total[q, p, r, t] for (q, r) in E_in[p]) <= + data.m_cap[p] * x_open[p, t] + ) + end + + eq_plant_prod = _init(model, :eq_plant_prod) + for p in plants, r_out in p.prod_out, c_out in r_out.comp, t in T + eq_plant_prod[p, r_out, c_out, t] = @constraint( + model, + z_prod[p, r_out, c_out, t] == + sum( + data.alpha_mix[p, r_out, c_in, c_out] * y[q, p, r_in, c_in, t] + for (q, r_in) in E_in[p] + for c_in in r_in.comp + ) + ) + end + + eq_plant_disp = _init(model, :eq_plant_disp) + for p in plants, r in p.prod_out, t in T + eq_plant_disp[p, r, t] = @constraint( + model, + sum( + z_plant_disp[p, r, c, t] + for c in r.comp + ) <= data.m_plant_disp[p, r, t] * x_disp[p, r, t] + ) + end + + eq_plant_emissions = _init(model, :eq_plant_emissions) + for p in plants, s in emissions, t in T + eq_plant_emissions[p, s, t] = @constraint( + model, + z_plant_emissions[p, s, t] == + sum( + y_total[q, p, r, t] + for (q, r,) in E_in[p] + ) * data.alpha_plant_emission[p, s, t] + ) + end + + eq_emissions_limit = _init(model, :eq_emissions_limit) + for s in emissions, t in T + eq_emissions_limit[s, t] = @constraint( + model, + sum(z_plant_emissions[p, s, t] for p in plants) + + + sum( + z_tr_emissions[q, p, r, s, t] + for (q, p, r) in E + ) <= data.m_emission[s, t] + ) + end + + eq_plant_remains_open = _init(model, :eq_plant_remains_open) + for p in plants, t in T + eq_plant_remains_open[p, t] = @constraint( + model, + x_open[p, t] >= x_open[p, t-1] + ) + end + + eq_plant_single_dest = _init(model, :eq_plant_single_dest) + for p in plants, r in p.prod_out, t in T + eq_plant_single_dest[p, r, t] = @constraint( + model, + sum( + x_send[p, q, r, t] + for (q, r2) in E_out[p] + if r == r2 + ) + x_disp[p, r, t] <= 1 + ) + end + + eq_plant_send_limit = _init(model, :eq_plant_send_limit) + for p in plants, (q, r) in E_out[p], t in T + eq_plant_send_limit[p, q, r, t] = @constraint( + model, + y_total[p, q, r, t] <= data.m_cap[q] * x_send[p, q, r, t] + ) + end + + eq_plant_balance = _init(model, :eq_plant_balance) + for p in plants, r in p.prod_out, c in r.comp, t in T + eq_plant_balance[p, r, c, t] = @constraint( + model, + z_prod[p, r, c, t] == + z_plant_disp[p, r, c, t] + + sum( + y[p, q, r, c, t] + for (q, r2) in E_out[p] + if r == r2 + ) + ) + end + + # Optimize + # ------------------------------------------------------------------------- + _set_names!(model) + optimize!(model) + + # Report: Transportation + # ------------------------------------------------------------------------- + df = DataFrame() + df."source" = String[] + df."destination" = String[] + df."product" = String[] + df."component" = String[] + df."time" = Int[] + df."distance (km)" = Float64[] + df."amount sent (tonne)" = Float64[] + df."transportation cost (\$)" = Float64[] + df."variable operating cost (\$)" = Float64[] + for (q, p, r) in E, c in r.comp, t in T + if value(y[q, p, r, c, t]) ≈ 0 + continue + end + push!( + df, + [ + q.name, + p.name, + r.name, + c.name, + t, + data.m_dist[q, p], + value(y[q, p, r, c, t]), + data.m_dist[q, p] * data.c_tr[r, t] * value(y[q, p, r, c, t]), + data.c_var[p, t] * value(y[q, p, r, c, t]) + ] + ) + end + CSV.write("output-3/transp.csv", df) + + # Report: Centers + # ------------------------------------------------------------------------- + df = DataFrame() + df."center" = String[] + df."product" = String[] + df."component" = String[] + df."time" = Int[] + df."amount available (tonne)" = Float64[] + df."amount sent (tonne)" = Float64[] + df."amount stored (tonne)" = Float64[] + df."amount disposed (tonne)" = Float64[] + df."acquisition cost (\$)" = Float64[] + df."storage cost (\$)" = Float64[] + df."disposal cost (\$)" = Float64[] + for q in centers, r in q.prod_out, c in r.comp, t in T + push!( + df, + [ + q.name, + r.name, + c.name, + t, + data.m_init[q, r, c, t], + sum( + value(y[q, p, r, c, t]) + for (p, r2) in E_out[q] + if r == r2 + ), + value(z_store[q, r, c, t]), + value(z_center_disp[q, r, c, t]), + data.m_init[q, r, c, t] * data.c_acq[q, r, t], + data.c_store[q, r, t] * value(z_store[q, r, c, t]), + data.c_center_disp[q, r, t] * value(z_center_disp[q, r, c, t]), + ] + ) + end + CSV.write("output-3/centers.csv", df) + + # Report: Plants + # ------------------------------------------------------------------------- + df = DataFrame() + df."plant" = String[] + df."time" = Int[] + df."is open?" = Float64[] + df."opening cost (\$)" = Float64[] + df."fixed operating cost (\$)" = Float64[] + for p in plants, t in T + push!( + df, + [ + p.name, + t, + value(x_open[p, t]), + data.c_open[p, t] * (value(x_open[p, t]) - value(x_open[p, t-1])), + data.c_fix[p, t] * value(x_open[p, t]), + ] + ) + end + CSV.write("output-3/plants.csv", df) + + # Report: Plant Outputs + # ------------------------------------------------------------------------- + df = DataFrame() + df."plant" = String[] + df."product" = String[] + df."component" = String[] + df."time" = Int[] + df."amount produced (tonne)" = Float64[] + df."amount disposed (tonne)" = Float64[] + df."amount sent (tonne)" = Float64[] + df."disposal cost (\$)" = Float64[] + for p in plants, r in p.prod_out, c in r.comp, t in T + if value(z_prod[p, r, c, t]) ≈ 0 + continue + end + push!( + df, + [ + p.name, + r.name, + c.name, + t, + value(z_prod[p, r, c, t]), + value(z_plant_disp[p, r, c, t]), + sum( + value(y[p, q, r, c, t]) + for (q, r2) in E_out[p] + if r == r2; + init=0.0 + ), + data.c_plant_disp[p, r, t] * value(z_plant_disp[p, r, c, t]), + ] + ) + end + CSV.write("output-3/plant-outputs.csv", df) + + # Report: Plant Emissions + # ------------------------------------------------------------------------- + df = DataFrame() + df."plant" = String[] + df."emission" = String[] + df."time" = Int[] + df."amount emitted (tonne)" = Float64[] + df."emission cost (\$)" = Float64[] + for p in plants, s in emissions, t in T + push!( + df, + [ + p.name, + s.name, + t, + value(z_plant_emissions[p, s, t]), + data.c_emission[s, t] * value(z_plant_emissions[p, s, t]), + ] + ) + end + CSV.write("output-3/plant-emissions.csv", df) + + # Report: Transportation Emissions + # ------------------------------------------------------------------------- + df = DataFrame() + df."source" = String[] + df."destination" = String[] + df."product" = String[] + df."emission" = String[] + df."time" = Int[] + df."distance (km)" = Float64[] + df."amount sent (tonne)" = Float64[] + df."amount emitted (tonne)" = Float64[] + df."emission cost (\$)" = Float64[] + for (q, p, r) in E, s in emissions, t in T + if value(y_total[q, p, r, t]) ≈ 0 + continue + end + push!( + df, + [ + q.name, + p.name, + r.name, + s.name, + t, + data.m_dist[q, p], + value(y_total[q, p, r, t]), + value(z_tr_emissions[q, p, r, s, t]), + data.c_emission[s, t] * value(z_tr_emissions[q, p, r, s, t]), + ] + ) + end + CSV.write("output-3/transp-emissions.csv", df) +end + diff --git a/output-2/plant-outputs.csv b/output-2/plant-outputs.csv new file mode 100644 index 0000000..39e3bea --- /dev/null +++ b/output-2/plant-outputs.csv @@ -0,0 +1,11 @@ +plant,product,component,amount produced (tonne),revenue ($) +Phoenix,film bale,film,2896.88,28968.800000000003 +Phoenix,film bale,paper,40.800000000000004,408.00000000000006 +Phoenix,film bale,cardboard,53.88,538.8000000000001 +Phoenix,cardboard bale,paper,40.800000000000004,530.4000000000001 +Phoenix,cardboard bale,cardboard,2020.5,26266.5 +Dallas,film bale,film,2144.24,25730.879999999997 +Dallas,film bale,paper,37.08,444.96 +Dallas,film bale,cardboard,31.86,382.32 +Dallas,cardboard bale,paper,37.08,667.4399999999999 +Dallas,cardboard bale,cardboard,1194.75,21505.5 diff --git a/output-2/plant.csv b/output-2/plant.csv new file mode 100644 index 0000000..9bbcd1c --- /dev/null +++ b/output-2/plant.csv @@ -0,0 +1,3 @@ +plant,is open?,capacity (tonne),utilization (tonne),opening cost ($) +Phoenix,1.0,41670.0,7690.0,6405.0 +Dallas,1.0,12957.0,5635.0,6824.0 diff --git a/output-2/tr.csv b/output-2/tr.csv new file mode 100644 index 0000000..d3a9cd0 --- /dev/null +++ b/output-2/tr.csv @@ -0,0 +1,31 @@ +center,plant,component,amount sent (tonne),transportation cost ($),variable operating cost ($) +Chicago,Dallas,film,630.0,1890.0,5670.0 +Chicago,Dallas,paper,662.0000000000001,1986.0000000000005,5958.000000000001 +Chicago,Dallas,cardboard,81.0,243.0,729.0 +New York City,Phoenix,film,451.00000000000006,2255.0000000000005,4059.0000000000005 +New York City,Phoenix,paper,640.0000000000001,3200.0000000000005,5760.000000000001 +New York City,Phoenix,cardboard,516.0000000000001,2580.0000000000005,4644.000000000001 +Los Angeles,Dallas,film,478.0,2868.0,4302.0 +Los Angeles,Dallas,paper,342.99999999999994,2057.9999999999995,3086.9999999999995 +Los Angeles,Dallas,cardboard,197.0,1182.0,1773.0 +Houston,Phoenix,film,703.9999999999998,1407.9999999999995,6335.999999999998 +Houston,Phoenix,paper,268.0,536.0,2412.0 +Houston,Phoenix,cardboard,600.9999999999999,1201.9999999999998,5408.999999999999 +Phoenix,Phoenix,film,674.0,2022.0,6066.0 +Phoenix,Phoenix,paper,515.9999999999999,1547.9999999999995,4643.999999999999 +Phoenix,Phoenix,cardboard,398.0,1194.0,3582.0 +Philadelphia,Dallas,film,165.99999999999997,331.99999999999994,1493.9999999999998 +Philadelphia,Dallas,paper,91.0,182.0,819.0 +Philadelphia,Dallas,cardboard,315.99999999999994,631.9999999999999,2843.9999999999995 +San Antonio,Dallas,film,614.0000000000001,614.0000000000001,5526.000000000001 +San Antonio,Dallas,paper,273.0,273.0,2457.0 +San Antonio,Dallas,cardboard,435.00000000000006,435.00000000000006,3915.0000000000005 +San Diego,Phoenix,film,669.0000000000001,5352.000000000001,6021.000000000001 +San Diego,Phoenix,paper,192.0,1536.0,1728.0 +San Diego,Phoenix,cardboard,859.0000000000001,6872.000000000001,7731.000000000001 +Dallas,Phoenix,film,458.00000000000006,3664.0000000000005,4122.000000000001 +Dallas,Phoenix,paper,424.0000000000001,3392.000000000001,3816.000000000001 +Dallas,Phoenix,cardboard,320.0,2560.0,2880.0 +San Jose,Dallas,film,300.0,900.0,2700.0 +San Jose,Dallas,paper,484.99999999999994,1454.9999999999998,4364.999999999999 +San Jose,Dallas,cardboard,563.9999999999999,1691.9999999999995,5075.999999999999 diff --git a/output-3/case.json b/output-3/case.json new file mode 100644 index 0000000..ccf74ae --- /dev/null +++ b/output-3/case.json @@ -0,0 +1,815 @@ +{ + "parameters": { + "time horizon (years)": 2 + }, + "products": { + "Waste": { + "components": [ + "Film", + "Paper", + "Cardboard" + ], + "disposal limit (tonne)": [ + 0.0, + 0.0 + ], + "transportation cost ($/km/tonne)": [ + 0.05, + 0.05 + ], + "transportation emissions (tonne/km/tonne)": { + "CO2": [ + 0.01, + 0.01 + ] + } + }, + "Film bale": { + "components": [ + "Film", + "Paper", + "Cardboard" + ], + "disposal limit (tonne)": [ + 0.0, + 0.0 + ], + "transportation cost ($/km/tonne)": [ + 0.05, + 0.05 + ], + "transportation emissions (tonne/km/tonne)": { + "CO2": [ + 0.01, + 0.01 + ] + } + }, + "Cardboard bale": { + "components": [ + "Paper", + "Cardboard" + ], + "disposal limit (tonne)": [ + 0.0, + 0.0 + ], + "transportation cost ($/km/tonne)": [ + 0.05, + 0.05 + ], + "transportation emissions (tonne/km/tonne)": { + "CO2": [ + 0.01, + 0.01 + ] + } + }, + "Cardboard sheets": { + "components": [ + "Cardboard" + ], + "disposal limit (tonne)": [ + 0.0, + 0.0 + ], + "transportation cost ($/km/tonne)": [ + 0.05, + 0.05 + ], + "transportation emissions (tonne/km/tonne)": { + "CO2": [ + 0.01, + 0.01 + ] + } + } + }, + "centers": { + "Collection (Chicago)": { + "latitude": 41.881832, + "longitude": -87.623177, + "output": { + "Waste": { + "initial amount (tonne)": [ + [ + 716.0, + 2864.0, + 1074.0 + ], + [ + 1394.0, + 5576.0, + 2091.0 + ] + ], + "disposal cost ($/tonne)": [ + 0.0, + 0.0 + ], + "storage cost ($/tonne)": [ + 1.0, + 1.0 + ], + "storage limit (tonne)": [ + 1000.0, + 1000.0 + ], + "acquisition cost ($/tonne)": [ + 1.0, + 1.0 + ] + } + } + }, + "Collection (New York City)": { + "latitude": 40.712776, + "longitude": -74.005974, + "output": { + "Waste": { + "initial amount (tonne)": [ + [ + 990.0, + 891.0, + 297.0 + ], + [ + 6450.0, + 5805.0, + 1935.0 + ] + ], + "disposal cost ($/tonne)": [ + 0.0, + 0.0 + ], + "storage cost ($/tonne)": [ + 1.0, + 1.0 + ], + "storage limit (tonne)": [ + 1000.0, + 1000.0 + ], + "acquisition cost ($/tonne)": [ + 1.0, + 1.0 + ] + } + } + }, + "Collection (Los Angeles)": { + "latitude": 34.052235, + "longitude": -118.243683, + "output": { + "Waste": { + "initial amount (tonne)": [ + [ + 4160.0, + 3640.0, + 5200.0 + ], + [ + 5704.0, + 4991.0, + 7130.0 + ] + ], + "disposal cost ($/tonne)": [ + 0.0, + 0.0 + ], + "storage cost ($/tonne)": [ + 1.0, + 1.0 + ], + "storage limit (tonne)": [ + 1000.0, + 1000.0 + ], + "acquisition cost ($/tonne)": [ + 1.0, + 1.0 + ] + } + } + }, + "Collection (Houston)": { + "latitude": 29.760427, + "longitude": -95.369804, + "output": { + "Waste": { + "initial amount (tonne)": [ + [ + 2668.0, + 4669.0, + 6670.0 + ], + [ + 1852.0, + 3241.0, + 4630.0 + ] + ], + "disposal cost ($/tonne)": [ + 0.0, + 0.0 + ], + "storage cost ($/tonne)": [ + 1.0, + 1.0 + ], + "storage limit (tonne)": [ + 1000.0, + 1000.0 + ], + "acquisition cost ($/tonne)": [ + 1.0, + 1.0 + ] + } + } + }, + "Collection (Phoenix)": { + "latitude": 33.448376, + "longitude": -112.074036, + "output": { + "Waste": { + "initial amount (tonne)": [ + [ + 3635.0, + 6543.0, + 5089.0 + ], + [ + 2275.0, + 4095.0, + 3185.0 + ] + ], + "disposal cost ($/tonne)": [ + 0.0, + 0.0 + ], + "storage cost ($/tonne)": [ + 1.0, + 1.0 + ], + "storage limit (tonne)": [ + 1000.0, + 1000.0 + ], + "acquisition cost ($/tonne)": [ + 1.0, + 1.0 + ] + } + } + }, + "Collection (Philadelphia)": { + "latitude": 39.952583, + "longitude": -75.165222, + "output": { + "Waste": { + "initial amount (tonne)": [ + [ + 220.0, + 880.0, + 880.0 + ], + [ + 962.0, + 3848.0, + 3848.0 + ] + ], + "disposal cost ($/tonne)": [ + 0.0, + 0.0 + ], + "storage cost ($/tonne)": [ + 1.0, + 1.0 + ], + "storage limit (tonne)": [ + 1000.0, + 1000.0 + ], + "acquisition cost ($/tonne)": [ + 1.0, + 1.0 + ] + } + } + }, + "Collection (San Antonio)": { + "latitude": 29.424122, + "longitude": -98.493629, + "output": { + "Waste": { + "initial amount (tonne)": [ + [ + 288.0, + 252.0, + 324.0 + ], + [ + 4240.0, + 3710.0, + 4770.0 + ] + ], + "disposal cost ($/tonne)": [ + 0.0, + 0.0 + ], + "storage cost ($/tonne)": [ + 1.0, + 1.0 + ], + "storage limit (tonne)": [ + 1000.0, + 1000.0 + ], + "acquisition cost ($/tonne)": [ + 1.0, + 1.0 + ] + } + } + }, + "Collection (San Diego)": { + "latitude": 32.715736, + "longitude": -117.161087, + "output": { + "Waste": { + "initial amount (tonne)": [ + [ + 6690.0, + 1338.0, + 4014.0 + ], + [ + 8460.0, + 1692.0, + 5076.0 + ] + ], + "disposal cost ($/tonne)": [ + 0.0, + 0.0 + ], + "storage cost ($/tonne)": [ + 1.0, + 1.0 + ], + "storage limit (tonne)": [ + 1000.0, + 1000.0 + ], + "acquisition cost ($/tonne)": [ + 1.0, + 1.0 + ] + } + } + }, + "Collection (Dallas)": { + "latitude": 32.776664, + "longitude": -96.796988, + "output": { + "Waste": { + "initial amount (tonne)": [ + [ + 5096.0, + 728.0, + 5824.0 + ], + [ + 4354.0, + 622.0, + 4976.0 + ] + ], + "disposal cost ($/tonne)": [ + 0.0, + 0.0 + ], + "storage cost ($/tonne)": [ + 1.0, + 1.0 + ], + "storage limit (tonne)": [ + 1000.0, + 1000.0 + ], + "acquisition cost ($/tonne)": [ + 1.0, + 1.0 + ] + } + } + }, + "Collection (San Jose)": { + "latitude": 37.338208, + "longitude": -121.886329, + "output": { + "Waste": { + "initial amount (tonne)": [ + [ + 1255.0, + 2510.0, + 251.0 + ], + [ + 4650.0, + 9300.0, + 930.0 + ] + ], + "disposal cost ($/tonne)": [ + 0.0, + 0.0 + ], + "storage cost ($/tonne)": [ + 1.0, + 1.0 + ], + "storage limit (tonne)": [ + 1000.0, + 1000.0 + ], + "acquisition cost ($/tonne)": [ + 1.0, + 1.0 + ] + } + } + } + }, + "plants": { + "MRF (Chicago)": { + "latitude": 41.881832, + "longitude": -87.623177, + "input": "Waste", + "output": { + "Film bale": { + "output matrix": [ + [ + 0.98, + 0.0, + 0.0 + ], + [ + 0.0, + 0.02, + 0.0 + ], + [ + 0.0, + 0.0, + 0.02 + ] + ], + "disposal limit (tonne)": [ + 1.0e6, + 1.0e6 + ], + "disposal cost ($/tonne)": [ + -10.0, + -10.0 + ] + }, + "Cardboard bale": { + "output matrix": [ + [ + 0.0, + 0.02, + 0.0 + ], + [ + 0.0, + 0.0, + 0.75 + ] + ], + "disposal limit (tonne)": [ + 1.0e6, + 1.0e6 + ], + "disposal cost ($/tonne)": [ + -10.0, + -10.0 + ] + } + }, + "fixed operating cost ($)": [ + 1000.0, + 1000.0 + ], + "variable operating cost ($/tonne)": [ + 1.0, + 1.0 + ], + "opening cost ($)": [ + 10000.0, + 10000.0 + ], + "capacity (tonne)": 50000.0, + "emissions (tonne/tonne)": { + "CO2": [ + 0.01, + 0.01 + ] + } + }, + "MRF (Phoenix)": { + "latitude": 33.448376, + "longitude": -112.074036, + "input": "Waste", + "output": { + "Film bale": { + "output matrix": [ + [ + 0.98, + 0.0, + 0.0 + ], + [ + 0.0, + 0.02, + 0.0 + ], + [ + 0.0, + 0.0, + 0.02 + ] + ], + "disposal limit (tonne)": [ + 1.0e6, + 1.0e6 + ], + "disposal cost ($/tonne)": [ + -10.0, + -10.0 + ] + }, + "Cardboard bale": { + "output matrix": [ + [ + 0.0, + 0.02, + 0.0 + ], + [ + 0.0, + 0.0, + 0.75 + ] + ], + "disposal limit (tonne)": [ + 1.0e6, + 1.0e6 + ], + "disposal cost ($/tonne)": [ + -10.0, + -10.0 + ] + } + }, + "fixed operating cost ($)": [ + 1000.0, + 1000.0 + ], + "variable operating cost ($/tonne)": [ + 1.0, + 1.0 + ], + "opening cost ($)": [ + 10000.0, + 10000.0 + ], + "capacity (tonne)": 50000.0, + "emissions (tonne/tonne)": { + "CO2": [ + 0.01, + 0.01 + ] + } + }, + "MRF (Dallas)": { + "latitude": 32.776664, + "longitude": -96.796988, + "input": "Waste", + "output": { + "Film bale": { + "output matrix": [ + [ + 0.98, + 0.0, + 0.0 + ], + [ + 0.0, + 0.02, + 0.0 + ], + [ + 0.0, + 0.0, + 0.02 + ] + ], + "disposal limit (tonne)": [ + 1.0e6, + 1.0e6 + ], + "disposal cost ($/tonne)": [ + -10.0, + -10.0 + ] + }, + "Cardboard bale": { + "output matrix": [ + [ + 0.0, + 0.02, + 0.0 + ], + [ + 0.0, + 0.0, + 0.75 + ] + ], + "disposal limit (tonne)": [ + 1.0e6, + 1.0e6 + ], + "disposal cost ($/tonne)": [ + -10.0, + -10.0 + ] + } + }, + "fixed operating cost ($)": [ + 1000.0, + 1000.0 + ], + "variable operating cost ($/tonne)": [ + 1.0, + 1.0 + ], + "opening cost ($)": [ + 10000.0, + 10000.0 + ], + "capacity (tonne)": 50000.0, + "emissions (tonne/tonne)": { + "CO2": [ + 0.01, + 0.01 + ] + } + }, + "Paper Mill (Chicago)": { + "latitude": 41.881832, + "longitude": -87.623177, + "input": "Cardboard bale", + "output": { + "Cardboard sheets": { + "output matrix": [ + [ + 0.0, + 0.95 + ] + ], + "disposal limit (tonne)": [ + 1.0e6, + 1.0e6 + ], + "disposal cost ($/tonne)": [ + -100.0, + -100.0 + ] + } + }, + "fixed operating cost ($)": [ + 1000.0, + 1000.0 + ], + "variable operating cost ($/tonne)": [ + 1.0, + 1.0 + ], + "opening cost ($)": [ + 10000.0, + 10000.0 + ], + "capacity (tonne)": 50000.0, + "emissions (tonne/tonne)": { + "CO2": [ + 0.01, + 0.01 + ] + } + }, + "Paper Mill (Phoenix)": { + "latitude": 33.448376, + "longitude": -112.074036, + "input": "Cardboard bale", + "output": { + "Cardboard sheets": { + "output matrix": [ + [ + 0.0, + 0.95 + ] + ], + "disposal limit (tonne)": [ + 1.0e6, + 1.0e6 + ], + "disposal cost ($/tonne)": [ + -100.0, + -100.0 + ] + } + }, + "fixed operating cost ($)": [ + 1000.0, + 1000.0 + ], + "variable operating cost ($/tonne)": [ + 1.0, + 1.0 + ], + "opening cost ($)": [ + 10000.0, + 10000.0 + ], + "capacity (tonne)": 50000.0, + "emissions (tonne/tonne)": { + "CO2": [ + 0.01, + 0.01 + ] + } + }, + "Paper Mill (Dallas)": { + "latitude": 32.776664, + "longitude": -96.796988, + "input": "Cardboard bale", + "output": { + "Cardboard sheets": { + "output matrix": [ + [ + 0.0, + 0.95 + ] + ], + "disposal limit (tonne)": [ + 1.0e6, + 1.0e6 + ], + "disposal cost ($/tonne)": [ + -100.0, + -100.0 + ] + } + }, + "fixed operating cost ($)": [ + 1000.0, + 1000.0 + ], + "variable operating cost ($/tonne)": [ + 1.0, + 1.0 + ], + "opening cost ($)": [ + 10000.0, + 10000.0 + ], + "capacity (tonne)": 50000.0, + "emissions (tonne/tonne)": { + "CO2": [ + 0.01, + 0.01 + ] + } + } + }, + "emissions": { + "CO2": { + "penalty ($/tonne)": [ + 0.01, + 0.01 + ], + "limit (tonne)": [ + 1.0e6, + 1.0e6 + ] + } + } +} diff --git a/output-3/centers.csv b/output-3/centers.csv new file mode 100644 index 0000000..a6dc7b6 --- /dev/null +++ b/output-3/centers.csv @@ -0,0 +1,61 @@ +center,product,component,time,amount available (tonne),amount sent (tonne),amount stored (tonne),amount disposed (tonne),acquisition cost ($),storage cost ($),disposal cost ($) +Collection (San Antonio),Waste,Film,1,288.0,288.0,0.0,0.0,288.0,0.0,0.0 +Collection (San Antonio),Waste,Film,2,4240.0,4240.0,0.0,0.0,4240.0,0.0,0.0 +Collection (San Antonio),Waste,Paper,1,252.0,252.00000000000003,0.0,0.0,252.0,0.0,0.0 +Collection (San Antonio),Waste,Paper,2,3710.0,3710.0000000000005,0.0,0.0,3710.0,0.0,0.0 +Collection (San Antonio),Waste,Cardboard,1,324.0,324.0,0.0,0.0,324.0,0.0,0.0 +Collection (San Antonio),Waste,Cardboard,2,4770.0,4770.0,0.0,0.0,4770.0,0.0,0.0 +Collection (San Jose),Waste,Film,1,1255.0,1255.0,0.0,0.0,1255.0,0.0,0.0 +Collection (San Jose),Waste,Film,2,4650.0,4650.0,0.0,0.0,4650.0,0.0,0.0 +Collection (San Jose),Waste,Paper,1,2510.0,2510.0,0.0,0.0,2510.0,0.0,0.0 +Collection (San Jose),Waste,Paper,2,9300.0,9300.0,0.0,0.0,9300.0,0.0,0.0 +Collection (San Jose),Waste,Cardboard,1,251.0,251.0,0.0,0.0,251.0,0.0,0.0 +Collection (San Jose),Waste,Cardboard,2,930.0,930.0,0.0,0.0,930.0,0.0,0.0 +Collection (New York City),Waste,Film,1,990.0,990.0,0.0,0.0,990.0,0.0,0.0 +Collection (New York City),Waste,Film,2,6450.0,6450.0,0.0,0.0,6450.0,0.0,0.0 +Collection (New York City),Waste,Paper,1,891.0,891.0,0.0,0.0,891.0,0.0,0.0 +Collection (New York City),Waste,Paper,2,5805.0,5805.0,0.0,0.0,5805.0,0.0,0.0 +Collection (New York City),Waste,Cardboard,1,297.0,297.0,0.0,0.0,297.0,0.0,0.0 +Collection (New York City),Waste,Cardboard,2,1935.0,1934.9999999999998,0.0,0.0,1935.0,0.0,0.0 +Collection (Los Angeles),Waste,Film,1,4160.0,4160.0,0.0,0.0,4160.0,0.0,0.0 +Collection (Los Angeles),Waste,Film,2,5704.0,5704.0,0.0,0.0,5704.0,0.0,0.0 +Collection (Los Angeles),Waste,Paper,1,3640.0,3640.0000000000005,0.0,0.0,3640.0,0.0,0.0 +Collection (Los Angeles),Waste,Paper,2,4991.0,4991.000000000001,0.0,0.0,4991.0,0.0,0.0 +Collection (Los Angeles),Waste,Cardboard,1,5200.0,5200.0,0.0,0.0,5200.0,0.0,0.0 +Collection (Los Angeles),Waste,Cardboard,2,7130.0,7130.0,0.0,0.0,7130.0,0.0,0.0 +Collection (Chicago),Waste,Film,1,716.0,716.0,0.0,0.0,716.0,0.0,0.0 +Collection (Chicago),Waste,Film,2,1394.0,1394.0,0.0,0.0,1394.0,0.0,0.0 +Collection (Chicago),Waste,Paper,1,2864.0,2864.0,0.0,0.0,2864.0,0.0,0.0 +Collection (Chicago),Waste,Paper,2,5576.0,5576.0,0.0,0.0,5576.0,0.0,0.0 +Collection (Chicago),Waste,Cardboard,1,1074.0,1074.0,0.0,0.0,1074.0,0.0,0.0 +Collection (Chicago),Waste,Cardboard,2,2091.0,2091.0,0.0,0.0,2091.0,0.0,0.0 +Collection (Dallas),Waste,Film,1,5096.0,5096.0,0.0,0.0,5096.0,0.0,0.0 +Collection (Dallas),Waste,Film,2,4354.0,4354.0,0.0,0.0,4354.0,0.0,0.0 +Collection (Dallas),Waste,Paper,1,728.0,728.0,0.0,0.0,728.0,0.0,0.0 +Collection (Dallas),Waste,Paper,2,622.0,622.0,0.0,0.0,622.0,0.0,0.0 +Collection (Dallas),Waste,Cardboard,1,5824.0,5824.0,0.0,0.0,5824.0,0.0,0.0 +Collection (Dallas),Waste,Cardboard,2,4976.0,4976.0,0.0,0.0,4976.0,0.0,0.0 +Collection (Phoenix),Waste,Film,1,3635.0,3635.0,0.0,0.0,3635.0,0.0,0.0 +Collection (Phoenix),Waste,Film,2,2275.0,2275.0,0.0,0.0,2275.0,0.0,0.0 +Collection (Phoenix),Waste,Paper,1,6543.0,6543.0,0.0,0.0,6543.0,0.0,0.0 +Collection (Phoenix),Waste,Paper,2,4095.0,4095.0,0.0,0.0,4095.0,0.0,0.0 +Collection (Phoenix),Waste,Cardboard,1,5089.0,5089.0,0.0,0.0,5089.0,0.0,0.0 +Collection (Phoenix),Waste,Cardboard,2,3185.0,3185.0,0.0,0.0,3185.0,0.0,0.0 +Collection (San Diego),Waste,Film,1,6690.0,6690.0,0.0,0.0,6690.0,0.0,0.0 +Collection (San Diego),Waste,Film,2,8460.0,8460.0,0.0,0.0,8460.0,0.0,0.0 +Collection (San Diego),Waste,Paper,1,1338.0,1338.0,0.0,0.0,1338.0,0.0,0.0 +Collection (San Diego),Waste,Paper,2,1692.0,1692.0,0.0,0.0,1692.0,0.0,0.0 +Collection (San Diego),Waste,Cardboard,1,4014.0,4014.0,0.0,0.0,4014.0,0.0,0.0 +Collection (San Diego),Waste,Cardboard,2,5076.0,5076.0,0.0,0.0,5076.0,0.0,0.0 +Collection (Philadelphia),Waste,Film,1,220.0,220.0,0.0,0.0,220.0,0.0,0.0 +Collection (Philadelphia),Waste,Film,2,962.0,962.0,0.0,0.0,962.0,0.0,0.0 +Collection (Philadelphia),Waste,Paper,1,880.0,880.0,0.0,0.0,880.0,0.0,0.0 +Collection (Philadelphia),Waste,Paper,2,3848.0,3848.0,0.0,0.0,3848.0,0.0,0.0 +Collection (Philadelphia),Waste,Cardboard,1,880.0,880.0,0.0,0.0,880.0,0.0,0.0 +Collection (Philadelphia),Waste,Cardboard,2,3848.0,3848.0,0.0,0.0,3848.0,0.0,0.0 +Collection (Houston),Waste,Film,1,2668.0,2668.0,0.0,0.0,2668.0,0.0,0.0 +Collection (Houston),Waste,Film,2,1852.0,1852.0,0.0,0.0,1852.0,0.0,0.0 +Collection (Houston),Waste,Paper,1,4669.0,4669.0,0.0,0.0,4669.0,0.0,0.0 +Collection (Houston),Waste,Paper,2,3241.0,3241.0,0.0,0.0,3241.0,0.0,0.0 +Collection (Houston),Waste,Cardboard,1,6670.0,6670.0,0.0,0.0,6670.0,0.0,0.0 +Collection (Houston),Waste,Cardboard,2,4630.0,4630.0,0.0,0.0,4630.0,0.0,0.0 diff --git a/output-3/plant-emissions.csv b/output-3/plant-emissions.csv new file mode 100644 index 0000000..23e54f4 --- /dev/null +++ b/output-3/plant-emissions.csv @@ -0,0 +1,13 @@ +plant,emission,time,amount emitted (tonne),emission cost ($) +MRF (Chicago),CO2,1,88.11999999999999,0.8811999999999999 +MRF (Chicago),CO2,2,319.09,3.1908999999999996 +Paper Mill (Phoenix),CO2,1,111.96120000000002,1.1196120000000003 +Paper Mill (Phoenix),CO2,2,121.9771,1.219771 +Paper Mill (Dallas),CO2,1,97.26479999999998,0.9726479999999998 +Paper Mill (Dallas),CO2,2,113.78059999999999,1.1378059999999999 +MRF (Phoenix),CO2,1,443.25000000000006,4.432500000000001 +MRF (Phoenix),CO2,2,500.0,5.0 +MRF (Dallas),CO2,1,265.19,2.6519 +MRF (Dallas),CO2,2,398.83,3.9882999999999997 +Paper Mill (Chicago),CO2,1,17.8095,0.178095 +Paper Mill (Chicago),CO2,2,62.10079999999999,0.6210079999999999 diff --git a/output-3/plant-outputs.csv b/output-3/plant-outputs.csv new file mode 100644 index 0000000..770ce5e --- /dev/null +++ b/output-3/plant-outputs.csv @@ -0,0 +1,37 @@ +plant,product,component,time,amount produced (tonne),amount disposed (tonne),amount sent (tonne),disposal cost ($) +MRF (Chicago),Film bale,Film,1,1887.4799999999998,1887.4799999999998,0.0,-18874.8 +MRF (Chicago),Film bale,Film,2,8629.88,8629.88,0.0,-86298.79999999999 +MRF (Chicago),Film bale,Paper,1,92.70000000000002,92.70000000000002,0.0,-927.0000000000002 +MRF (Chicago),Film bale,Paper,2,304.58,304.58,0.0,-3045.7999999999997 +MRF (Chicago),Film bale,Cardboard,1,45.02,45.02,0.0,-450.20000000000005 +MRF (Chicago),Film bale,Cardboard,2,157.48000000000002,157.48000000000002,0.0,-1574.8000000000002 +MRF (Chicago),Cardboard bale,Paper,1,92.70000000000002,0.0,92.70000000000002,-0.0 +MRF (Chicago),Cardboard bale,Paper,2,304.579999999999,0.0,304.579999999999,-0.0 +MRF (Chicago),Cardboard bale,Cardboard,1,1688.25,0.0,1688.25,-0.0 +MRF (Chicago),Cardboard bale,Cardboard,2,5905.5,0.0,5905.5,-0.0 +Paper Mill (Phoenix),Cardboard sheets,Cardboard,1,10369.725,10369.725,0.0,-1.0369725e6 +Paper Mill (Phoenix),Cardboard sheets,Cardboard,2,11295.262499999999,11295.262499999999,0.0,-1.12952625e6 +Paper Mill (Dallas),Cardboard sheets,Cardboard,1,9132.824999999999,9132.824999999999,0.0,-913282.4999999999 +Paper Mill (Dallas),Cardboard sheets,Cardboard,2,10576.35,10576.35,0.0,-1.057635e6 +MRF (Phoenix),Film bale,Film,1,15425.2,15425.2,0.0,-154252.0 +MRF (Phoenix),Film bale,Film,2,18374.02,18374.02,0.0,-183740.2 +MRF (Phoenix),Film bale,Paper,1,280.62,280.62,0.0,-2806.2 +MRF (Phoenix),Film bale,Paper,2,307.96000000000004,307.96000000000004,0.0,-3079.6000000000004 +MRF (Phoenix),Film bale,Cardboard,1,291.08,291.08,0.0,-2910.7999999999997 +MRF (Phoenix),Film bale,Cardboard,2,317.06,317.06,0.0,-3170.6 +MRF (Phoenix),Cardboard bale,Paper,1,280.6200000000026,0.0,280.6200000000026,-0.0 +MRF (Phoenix),Cardboard bale,Paper,2,307.96000000000004,0.0,307.96000000000004,-0.0 +MRF (Phoenix),Cardboard bale,Cardboard,1,10915.5,0.0,10915.5,-0.0 +MRF (Phoenix),Cardboard bale,Cardboard,2,11889.75,0.0,11889.75,-0.0 +MRF (Dallas),Film bale,Film,1,7890.959999999999,7890.959999999999,0.0,-78909.59999999999 +MRF (Dallas),Film bale,Film,2,12530.279999999999,12530.279999999999,0.0,-125302.79999999999 +MRF (Dallas),Film bale,Paper,1,112.97999999999999,112.97999999999999,0.0,-1129.8 +MRF (Dallas),Film bale,Paper,2,245.06,245.06,0.0,-2450.6 +MRF (Dallas),Film bale,Cardboard,1,256.36,256.36,0.0,-2563.6000000000004 +MRF (Dallas),Film bale,Cardboard,2,296.88,296.88,0.0,-2968.8 +MRF (Dallas),Cardboard bale,Paper,1,112.97999999999774,0.0,112.97999999999774,-0.0 +MRF (Dallas),Cardboard bale,Paper,2,245.06,0.0,245.06,-0.0 +MRF (Dallas),Cardboard bale,Cardboard,1,9613.5,0.0,9613.5,-0.0 +MRF (Dallas),Cardboard bale,Cardboard,2,11133.0,0.0,11133.0,-0.0 +Paper Mill (Chicago),Cardboard sheets,Cardboard,1,1603.8374999999999,1603.8374999999999,0.0,-160383.75 +Paper Mill (Chicago),Cardboard sheets,Cardboard,2,5610.224999999999,5610.224999999999,0.0,-561022.5 diff --git a/output-3/plants.csv b/output-3/plants.csv new file mode 100644 index 0000000..16b0a7c --- /dev/null +++ b/output-3/plants.csv @@ -0,0 +1,13 @@ +plant,time,is open?,opening cost ($),fixed operating cost ($) +MRF (Chicago),1,1.0,10000.0,1000.0 +MRF (Chicago),2,1.0,0.0,1000.0 +Paper Mill (Phoenix),1,1.0,10000.0,1000.0 +Paper Mill (Phoenix),2,1.0,0.0,1000.0 +Paper Mill (Dallas),1,1.0,10000.0,1000.0 +Paper Mill (Dallas),2,1.0,0.0,1000.0 +MRF (Phoenix),1,1.0,10000.0,1000.0 +MRF (Phoenix),2,1.0,0.0,1000.0 +MRF (Dallas),1,1.0,10000.0,1000.0 +MRF (Dallas),2,1.0,0.0,1000.0 +Paper Mill (Chicago),1,1.0,10000.0,1000.0 +Paper Mill (Chicago),2,1.0,0.0,1000.0 diff --git a/output-3/transp-emissions.csv b/output-3/transp-emissions.csv new file mode 100644 index 0000000..9eb5ac7 --- /dev/null +++ b/output-3/transp-emissions.csv @@ -0,0 +1,28 @@ +source,destination,product,emission,time,distance (km),amount sent (tonne),amount emitted (tonne),emission cost ($) +MRF (Chicago),Paper Mill (Chicago),Cardboard bale,CO2,1,0.0,1780.95,0.0,0.0 +MRF (Chicago),Paper Mill (Chicago),Cardboard bale,CO2,2,0.0,6210.079999999999,0.0,0.0 +MRF (Phoenix),Paper Mill (Phoenix),Cardboard bale,CO2,1,0.0,11196.120000000003,0.0,0.0 +MRF (Phoenix),Paper Mill (Phoenix),Cardboard bale,CO2,2,0.0,12197.71,0.0,0.0 +MRF (Dallas),Paper Mill (Dallas),Cardboard bale,CO2,1,0.0,9726.479999999998,0.0,0.0 +MRF (Dallas),Paper Mill (Dallas),Cardboard bale,CO2,2,0.0,11378.06,0.0,0.0 +Collection (San Antonio),MRF (Dallas),Waste,CO2,1,476.098,864.0,4113.48672,41.1348672 +Collection (San Antonio),MRF (Dallas),Waste,CO2,2,476.098,12720.0,60559.6656,605.596656 +Collection (San Jose),MRF (Phoenix),Waste,CO2,1,1173.985,4016.0,47147.23759999999,471.47237599999994 +Collection (San Jose),MRF (Phoenix),Waste,CO2,2,1173.985,7392.0,86780.97119999999,867.8097119999999 +Collection (San Jose),MRF (Dallas),Waste,CO2,2,2705.116,7488.0,202559.08608,2025.5908608000002 +Collection (New York City),MRF (Chicago),Waste,CO2,1,1293.755,2178.0,28177.983900000003,281.77983900000004 +Collection (New York City),MRF (Chicago),Waste,CO2,2,1293.755,14190.0,183583.83450000003,1835.8383450000003 +Collection (Los Angeles),MRF (Phoenix),Waste,CO2,1,668.923,13000.0,86959.99,869.5999 +Collection (Los Angeles),MRF (Phoenix),Waste,CO2,2,668.923,17825.0,119235.52475,1192.3552475 +Collection (Chicago),MRF (Chicago),Waste,CO2,1,0.0,4654.0,0.0,0.0 +Collection (Chicago),MRF (Chicago),Waste,CO2,2,0.0,9061.0,0.0,0.0 +Collection (Dallas),MRF (Dallas),Waste,CO2,1,0.0,11648.0,0.0,0.0 +Collection (Dallas),MRF (Dallas),Waste,CO2,2,0.0,9952.0,0.0,0.0 +Collection (Phoenix),MRF (Phoenix),Waste,CO2,1,0.0,15267.0,0.0,0.0 +Collection (Phoenix),MRF (Phoenix),Waste,CO2,2,0.0,9555.0,0.0,0.0 +Collection (San Diego),MRF (Phoenix),Waste,CO2,1,567.242,12042.0,68307.28164,683.0728164000001 +Collection (San Diego),MRF (Phoenix),Waste,CO2,2,567.242,15228.0,86379.61176,863.7961176 +Collection (Philadelphia),MRF (Chicago),Waste,CO2,1,1244.116,1980.0,24633.4968,246.334968 +Collection (Philadelphia),MRF (Chicago),Waste,CO2,2,1244.116,8658.0,107715.56328,1077.1556328000001 +Collection (Houston),MRF (Dallas),Waste,CO2,1,411.89,14007.0,57693.4323,576.9343230000001 +Collection (Houston),MRF (Dallas),Waste,CO2,2,411.89,9723.0,40048.0647,400.48064700000003 diff --git a/output-3/transp.csv b/output-3/transp.csv new file mode 100644 index 0000000..2d18070 --- /dev/null +++ b/output-3/transp.csv @@ -0,0 +1,76 @@ +source,destination,product,component,time,distance (km),amount sent (tonne),transportation cost ($),variable operating cost ($) +MRF (Chicago),Paper Mill (Chicago),Cardboard bale,Paper,1,0.0,92.70000000000002,0.0,92.70000000000002 +MRF (Chicago),Paper Mill (Chicago),Cardboard bale,Paper,2,0.0,304.579999999999,0.0,304.579999999999 +MRF (Chicago),Paper Mill (Chicago),Cardboard bale,Cardboard,1,0.0,1688.25,0.0,1688.25 +MRF (Chicago),Paper Mill (Chicago),Cardboard bale,Cardboard,2,0.0,5905.5,0.0,5905.5 +MRF (Phoenix),Paper Mill (Phoenix),Cardboard bale,Paper,1,0.0,280.6200000000026,0.0,280.6200000000026 +MRF (Phoenix),Paper Mill (Phoenix),Cardboard bale,Paper,2,0.0,307.96000000000004,0.0,307.96000000000004 +MRF (Phoenix),Paper Mill (Phoenix),Cardboard bale,Cardboard,1,0.0,10915.5,0.0,10915.5 +MRF (Phoenix),Paper Mill (Phoenix),Cardboard bale,Cardboard,2,0.0,11889.75,0.0,11889.75 +MRF (Dallas),Paper Mill (Dallas),Cardboard bale,Paper,1,0.0,112.97999999999774,0.0,112.97999999999774 +MRF (Dallas),Paper Mill (Dallas),Cardboard bale,Paper,2,0.0,245.06,0.0,245.06 +MRF (Dallas),Paper Mill (Dallas),Cardboard bale,Cardboard,1,0.0,9613.5,0.0,9613.5 +MRF (Dallas),Paper Mill (Dallas),Cardboard bale,Cardboard,2,0.0,11133.0,0.0,11133.0 +Collection (San Antonio),MRF (Dallas),Waste,Film,1,476.098,288.0,6855.811200000001,288.0 +Collection (San Antonio),MRF (Dallas),Waste,Film,2,476.098,4240.0,100932.77600000001,4240.0 +Collection (San Antonio),MRF (Dallas),Waste,Paper,1,476.098,252.00000000000003,5998.834800000001,252.00000000000003 +Collection (San Antonio),MRF (Dallas),Waste,Paper,2,476.098,3710.0000000000005,88316.17900000002,3710.0000000000005 +Collection (San Antonio),MRF (Dallas),Waste,Cardboard,1,476.098,324.0,7712.7876000000015,324.0 +Collection (San Antonio),MRF (Dallas),Waste,Cardboard,2,476.098,4770.0,113549.37300000002,4770.0 +Collection (San Jose),MRF (Phoenix),Waste,Film,1,1173.985,1255.0,73667.55875,1255.0 +Collection (San Jose),MRF (Phoenix),Waste,Film,2,1173.985,2310.0,135595.2675,2310.0 +Collection (San Jose),MRF (Phoenix),Waste,Paper,1,1173.985,2510.0,147335.1175,2510.0 +Collection (San Jose),MRF (Phoenix),Waste,Paper,2,1173.985,4620.0,271190.535,4620.0 +Collection (San Jose),MRF (Phoenix),Waste,Cardboard,1,1173.985,251.0,14733.51175,251.0 +Collection (San Jose),MRF (Phoenix),Waste,Cardboard,2,1173.985,462.0,27119.053499999998,462.0 +Collection (San Jose),MRF (Dallas),Waste,Film,2,2705.116,2340.0,316498.572,2340.0 +Collection (San Jose),MRF (Dallas),Waste,Paper,2,2705.116,4680.0,632997.144,4680.0 +Collection (San Jose),MRF (Dallas),Waste,Cardboard,2,2705.116,468.0,63299.7144,468.0 +Collection (New York City),MRF (Chicago),Waste,Film,1,1293.755,990.0,64040.872500000005,990.0 +Collection (New York City),MRF (Chicago),Waste,Film,2,1293.755,6450.0,417235.98750000005,6450.0 +Collection (New York City),MRF (Chicago),Waste,Paper,1,1293.755,891.0,57636.78525000001,891.0 +Collection (New York City),MRF (Chicago),Waste,Paper,2,1293.755,5805.0,375512.38875000004,5805.0 +Collection (New York City),MRF (Chicago),Waste,Cardboard,1,1293.755,297.0,19212.26175,297.0 +Collection (New York City),MRF (Chicago),Waste,Cardboard,2,1293.755,1934.9999999999998,125170.79625,1934.9999999999998 +Collection (Los Angeles),MRF (Phoenix),Waste,Film,1,668.923,4160.0,139135.98400000003,4160.0 +Collection (Los Angeles),MRF (Phoenix),Waste,Film,2,668.923,5704.0,190776.8396,5704.0 +Collection (Los Angeles),MRF (Phoenix),Waste,Paper,1,668.923,3640.0000000000005,121743.98600000002,3640.0000000000005 +Collection (Los Angeles),MRF (Phoenix),Waste,Paper,2,668.923,4991.000000000001,166929.73465000006,4991.000000000001 +Collection (Los Angeles),MRF (Phoenix),Waste,Cardboard,1,668.923,5200.0,173919.98,5200.0 +Collection (Los Angeles),MRF (Phoenix),Waste,Cardboard,2,668.923,7130.0,238471.04950000002,7130.0 +Collection (Chicago),MRF (Chicago),Waste,Film,1,0.0,716.0,0.0,716.0 +Collection (Chicago),MRF (Chicago),Waste,Film,2,0.0,1394.0,0.0,1394.0 +Collection (Chicago),MRF (Chicago),Waste,Paper,1,0.0,2864.0,0.0,2864.0 +Collection (Chicago),MRF (Chicago),Waste,Paper,2,0.0,5576.0,0.0,5576.0 +Collection (Chicago),MRF (Chicago),Waste,Cardboard,1,0.0,1074.0,0.0,1074.0 +Collection (Chicago),MRF (Chicago),Waste,Cardboard,2,0.0,2091.0,0.0,2091.0 +Collection (Dallas),MRF (Dallas),Waste,Film,1,0.0,5096.0,0.0,5096.0 +Collection (Dallas),MRF (Dallas),Waste,Film,2,0.0,4354.0,0.0,4354.0 +Collection (Dallas),MRF (Dallas),Waste,Paper,1,0.0,728.0,0.0,728.0 +Collection (Dallas),MRF (Dallas),Waste,Paper,2,0.0,622.0,0.0,622.0 +Collection (Dallas),MRF (Dallas),Waste,Cardboard,1,0.0,5824.0,0.0,5824.0 +Collection (Dallas),MRF (Dallas),Waste,Cardboard,2,0.0,4976.0,0.0,4976.0 +Collection (Phoenix),MRF (Phoenix),Waste,Film,1,0.0,3635.0,0.0,3635.0 +Collection (Phoenix),MRF (Phoenix),Waste,Film,2,0.0,2275.0,0.0,2275.0 +Collection (Phoenix),MRF (Phoenix),Waste,Paper,1,0.0,6543.0,0.0,6543.0 +Collection (Phoenix),MRF (Phoenix),Waste,Paper,2,0.0,4095.0,0.0,4095.0 +Collection (Phoenix),MRF (Phoenix),Waste,Cardboard,1,0.0,5089.0,0.0,5089.0 +Collection (Phoenix),MRF (Phoenix),Waste,Cardboard,2,0.0,3185.0,0.0,3185.0 +Collection (San Diego),MRF (Phoenix),Waste,Film,1,567.242,6690.0,189742.449,6690.0 +Collection (San Diego),MRF (Phoenix),Waste,Film,2,567.242,8460.0,239943.36599999998,8460.0 +Collection (San Diego),MRF (Phoenix),Waste,Paper,1,567.242,1338.0,37948.489799999996,1338.0 +Collection (San Diego),MRF (Phoenix),Waste,Paper,2,567.242,1692.0,47988.6732,1692.0 +Collection (San Diego),MRF (Phoenix),Waste,Cardboard,1,567.242,4014.0,113845.46939999999,4014.0 +Collection (San Diego),MRF (Phoenix),Waste,Cardboard,2,567.242,5076.0,143966.0196,5076.0 +Collection (Philadelphia),MRF (Chicago),Waste,Film,1,1244.116,220.0,13685.276000000002,220.0 +Collection (Philadelphia),MRF (Chicago),Waste,Film,2,1244.116,962.0,59841.979600000006,962.0 +Collection (Philadelphia),MRF (Chicago),Waste,Paper,1,1244.116,880.0,54741.10400000001,880.0 +Collection (Philadelphia),MRF (Chicago),Waste,Paper,2,1244.116,3848.0,239367.91840000002,3848.0 +Collection (Philadelphia),MRF (Chicago),Waste,Cardboard,1,1244.116,880.0,54741.10400000001,880.0 +Collection (Philadelphia),MRF (Chicago),Waste,Cardboard,2,1244.116,3848.0,239367.91840000002,3848.0 +Collection (Houston),MRF (Dallas),Waste,Film,1,411.89,2668.0,54946.126,2668.0 +Collection (Houston),MRF (Dallas),Waste,Film,2,411.89,1852.0,38141.014,1852.0 +Collection (Houston),MRF (Dallas),Waste,Paper,1,411.89,4669.0,96155.7205,4669.0 +Collection (Houston),MRF (Dallas),Waste,Paper,2,411.89,3241.0,66746.7745,3241.0 +Collection (Houston),MRF (Dallas),Waste,Cardboard,1,411.89,6670.0,137365.315,6670.0 +Collection (Houston),MRF (Dallas),Waste,Cardboard,2,411.89,4630.0,95352.535,4630.0