From 6dae3a825f4a0bb75f806df20111a1153cf0007f Mon Sep 17 00:00:00 2001 From: "Alinson S. Xavier" Date: Fri, 8 Dec 2023 09:57:39 -0600 Subject: [PATCH] Convert boat example to Julia --- test/Project.toml | 1 + test/fixtures/boat_example.ipynb | 238 ------------------------------- test/fixtures/boat_example.jl | 172 ++++++++++++++++++++++ test/fixtures/boat_example.json | 2 +- test/src/RELOGT.jl | 2 + 5 files changed, 176 insertions(+), 239 deletions(-) delete mode 100644 test/fixtures/boat_example.ipynb create mode 100644 test/fixtures/boat_example.jl diff --git a/test/Project.toml b/test/Project.toml index ee48dc3..036e368 100644 --- a/test/Project.toml +++ b/test/Project.toml @@ -5,6 +5,7 @@ version = "0.1.0" [deps] HiGHS = "87dc4568-4c63-4d18-b0c0-bb2238e4078b" +JSON = "682c06a0-de6a-54ab-a142-c8b1cf79cde6" JuMP = "4076af6c-e467-56ae-b986-b466b2749572" JuliaFormatter = "98e50ef6-434e-11e9-1051-2b60c6c9e899" OrderedCollections = "bac558e1-5e72-5ebc-8fee-abe8a469f55d" diff --git a/test/fixtures/boat_example.ipynb b/test/fixtures/boat_example.ipynb deleted file mode 100644 index 777752b..0000000 --- a/test/fixtures/boat_example.ipynb +++ /dev/null @@ -1,238 +0,0 @@ -{ - "cells": [ - { - "cell_type": "code", - "execution_count": 115, - "metadata": {}, - "outputs": [], - "source": [ - "import json\n", - "\n", - "cities_a = {\n", - " \"Chicago\": [41.881832, -87.623177],\n", - " \"New York City\": [40.712776, -74.005974],\n", - " \"Los Angeles\": [34.052235, -118.243683],\n", - " \"Houston\": [29.760427, -95.369804],\n", - " \"Phoenix\": [33.448376, -112.074036],\n", - " \"Philadelphia\": [39.952583, -75.165222],\n", - " \"San Antonio\": [29.424122, -98.493629],\n", - " \"San Diego\": [32.715736, -117.161087],\n", - " \"Dallas\": [32.776664, -96.796988],\n", - " \"San Jose\": [37.338208, -121.886329],\n", - "}\n", - "\n", - "cities_b = {\n", - " \"Chicago\": [41.881832, -87.623177],\n", - " \"Phoenix\": [33.448376, -112.074036],\n", - " \"Dallas\": [32.776664, -96.796988],\n", - "}\n", - "\n", - "parameters = {\n", - " \"time horizon (years)\": 5,\n", - " \"building period (years)\": [1],\n", - " \"distance metric\": \"Euclidean\",\n", - "}\n", - "\n", - "nail_factory = {\n", - " \"input\": None,\n", - " \"outputs\": [\"Nail\"],\n", - " \"fixed output (tonne)\": {\"Nail\": 5},\n", - " \"variable output (tonne/tonne)\": {\"Nail\": 0},\n", - " \"revenue ($/tonne)\": None,\n", - " \"collection cost ($/tonne)\": {\"Nail\": 1000},\n", - " \"operating cost ($)\": 0,\n", - " \"disposal limit (tonne)\": {\"Nail\": None},\n", - " \"disposal cost ($/tonne)\": {\"Nail\": 0},\n", - "}\n", - "\n", - "forest = {\n", - " \"input\": None,\n", - " \"outputs\": [\"Wood\"],\n", - " \"fixed output (tonne)\": {\"Wood\": 95},\n", - " \"variable output (tonne/tonne)\": {\"Wood\": 0},\n", - " \"revenue ($/tonne)\": None,\n", - " \"collection cost ($/tonne)\": {\"Wood\": 250},\n", - " \"operating cost ($)\": 0,\n", - " \"disposal limit (tonne)\": {\"Wood\": None},\n", - " \"disposal cost ($/tonne)\": {\"Wood\": 0},\n", - "}\n", - "\n", - "retail = {\n", - " \"input\": \"NewBoat\",\n", - " \"outputs\": [\"UsedBoat\"],\n", - " \"fixed output (tonne)\": {\"UsedBoat\": 0},\n", - " \"variable output (tonne/tonne)\": {\"UsedBoat\": [0.10, 0.25, 0.10]},\n", - " \"revenue ($/tonne)\": 12_000,\n", - " \"collection cost ($/tonne)\": {\"UsedBoat\": 100},\n", - " \"operating cost ($)\": 125_000,\n", - " \"disposal limit (tonne)\": {\"UsedBoat\": None},\n", - " \"disposal cost ($/tonne)\": {\"UsedBoat\": 0},\n", - "}\n", - "\n", - "prod = {\n", - " \"transportation cost ($/km/tonne)\": 0.30,\n", - " \"transportation energy (J/km/tonne)\": 7_500,\n", - " \"transportation emissions (tonne/km/tonne)\": {\n", - " \"CO2\": 2.68,\n", - " },\n", - "}\n", - "\n", - "boat_factory = {\n", - " \"input mix (%)\": {\n", - " \"Wood\": 95,\n", - " \"Nail\": 5,\n", - " },\n", - " \"output (tonne)\": {\"NewBoat\": 1.0},\n", - " \"processing emissions (tonne)\": {\"CO2\": 5},\n", - " \"storage cost ($/tonne)\": {\n", - " \"Wood\": 500,\n", - " \"Nail\": 200,\n", - " },\n", - " \"storage limit (tonne)\": {\"Wood\": 5, \"Nail\": 1},\n", - " \"disposal cost ($/tonne)\": {\n", - " \"NewBoat\": 0,\n", - " },\n", - " \"disposal limit (tonne)\": {\n", - " \"NewBoat\": 0,\n", - " },\n", - " \"capacities\": [\n", - " {\n", - " \"size (tonne)\": 500,\n", - " \"opening cost ($)\": 1_000_000,\n", - " \"fixed operating cost ($)\": 250_000,\n", - " \"variable operating cost ($/tonne)\": 5,\n", - " },\n", - " {\n", - " \"size (tonne)\": 1000,\n", - " \"opening cost ($)\": 2_000_000,\n", - " \"fixed operating cost ($)\": 500_000,\n", - " \"variable operating cost ($/tonne)\": 5,\n", - " },\n", - " ],\n", - " \"initial capacity (tonne)\": 0,\n", - "}\n", - "\n", - "recycling_plant = {\n", - " \"input mix (%)\": {\n", - " \"UsedBoat\": 100,\n", - " },\n", - " \"output (tonne)\": {\"Nail\": 0.025, \"Wood\": 0.475},\n", - " \"processing emissions (tonne)\": {\"CO2\": 5},\n", - " \"storage cost ($/tonne)\": {\n", - " \"UsedBoat\": 0,\n", - " },\n", - " \"storage limit (tonne)\": {\"UsedBoat\": 0},\n", - " \"disposal cost ($/tonne)\": {\n", - " \"Nail\": 0,\n", - " \"Wood\": 0,\n", - " },\n", - " \"disposal limit (tonne)\": {\"Nail\": 0, \"Wood\": 0},\n", - " \"capacities\": [\n", - " {\n", - " \"size (tonne)\": 500,\n", - " \"opening cost ($)\": 500_000,\n", - " \"fixed operating cost ($)\": 125_000,\n", - " \"variable operating cost ($/tonne)\": 2.5,\n", - " },\n", - " {\n", - " \"size (tonne)\": 1000,\n", - " \"opening cost ($)\": 1_000_000,\n", - " \"fixed operating cost ($)\": 250_000,\n", - " \"variable operating cost ($/tonne)\": 2.5,\n", - " },\n", - " ],\n", - " \"initial capacity (tonne)\": 0,\n", - "}" - ] - }, - { - "cell_type": "code", - "execution_count": 116, - "metadata": {}, - "outputs": [], - "source": [ - "data = {\n", - " \"parameters\": parameters,\n", - " \"products\": {\n", - " \"Nail\": prod,\n", - " \"Wood\": prod,\n", - " \"NewBoat\": prod,\n", - " \"UsedBoat\": prod,\n", - " },\n", - " \"centers\": {\n", - " f\"NailFactory ({city_name})\": {\n", - " **nail_factory,\n", - " \"latitude (deg)\": city_location[0],\n", - " \"longitude (deg)\": city_location[1],\n", - " }\n", - " for (city_name, city_location) in cities_b.items()\n", - " } | {\n", - " f\"Forest ({city_name})\": {\n", - " **forest,\n", - " \"latitude (deg)\": city_location[0],\n", - " \"longitude (deg)\": city_location[1],\n", - " }\n", - " for (city_name, city_location) in cities_b.items()\n", - " }\n", - " | {\n", - " f\"Retail ({city_name})\": {\n", - " **retail,\n", - " \"latitude (deg)\": city_location[0],\n", - " \"longitude (deg)\": city_location[1],\n", - " }\n", - " for (city_name, city_location) in cities_a.items()\n", - " }\n", - " ,\n", - " \"plants\":\n", - " {\n", - " f\"BoatFactory ({city_name})\": {\n", - " **boat_factory,\n", - " \"latitude (deg)\": city_location[0],\n", - " \"longitude (deg)\": city_location[1],\n", - " }\n", - " for (city_name, city_location) in cities_a.items()\n", - " }\n", - " | {\n", - " f\"RecyclingPlant ({city_name})\": {\n", - " **recycling_plant,\n", - " \"latitude (deg)\": city_location[0],\n", - " \"longitude (deg)\": city_location[1],\n", - " }\n", - " for (city_name, city_location) in cities_a.items()\n", - " }\n", - "}\n", - "\n", - "with open(\"boat_example.json\", \"w\") as file:\n", - " json.dump(data, file, indent=2)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - } - ], - "metadata": { - "kernelspec": { - "display_name": "base", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.9.12" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} diff --git a/test/fixtures/boat_example.jl b/test/fixtures/boat_example.jl new file mode 100644 index 0000000..2cc707c --- /dev/null +++ b/test/fixtures/boat_example.jl @@ -0,0 +1,172 @@ +using OrderedCollections +using JSON +using RELOG +dict = OrderedDict + +function run_boat_example() + 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], + ) + + parameters = dict( + "time horizon (years)" => 5, + "building period (years)" => [1], + "distance metric" => "Euclidean", + ) + + nail_factory = dict( + "input" => nothing, + "outputs" => ["Nail"], + "fixed output (tonne)" => dict("Nail" => 1), + "variable output (tonne/tonne)" => dict("Nail" => 0), + "revenue (\$/tonne)" => nothing, + "collection cost (\$/tonne)" => dict("Nail" => 1000), + "operating cost (\$)" => 0, + "disposal limit (tonne)" => dict("Nail" => nothing), + "disposal cost (\$/tonne)" => dict("Nail" => 0), + ) + + forest = dict( + "input" => nothing, + "outputs" => ["Wood"], + "fixed output (tonne)" => dict("Wood" => 100), + "variable output (tonne/tonne)" => dict("Wood" => 0), + "revenue (\$/tonne)" => nothing, + "collection cost (\$/tonne)" => dict("Wood" => 250), + "operating cost (\$)" => 0, + "disposal limit (tonne)" => dict("Wood" => nothing), + "disposal cost (\$/tonne)" => dict("Wood" => 0), + ) + + retail = dict( + "input" => "NewBoat", + "outputs" => ["UsedBoat"], + "fixed output (tonne)" => dict("UsedBoat" => 0), + "variable output (tonne/tonne)" => dict("UsedBoat" => [0.10, 0.25, 0.10]), + "revenue (\$/tonne)" => 12_000, + "collection cost (\$/tonne)" => dict("UsedBoat" => 100), + "operating cost (\$)" => 125_000, + "disposal limit (tonne)" => dict("UsedBoat" => 0), + "disposal cost (\$/tonne)" => dict("UsedBoat" => 0), + ) + + prod = dict( + "transportation cost (\$/km/tonne)" => 0.30, + "transportation energy (J/km/tonne)" => 7_500, + "transportation emissions (tonne/km/tonne)" => dict("CO2" => 2.68), + ) + + boat_factory = dict( + "input mix (%)" => dict("Wood" => 95, "Nail" => 5), + "output (tonne)" => dict("NewBoat" => 1.0), + "processing emissions (tonne)" => dict("CO2" => 5), + "storage cost (\$/tonne)" => dict("Wood" => 500, "Nail" => 200), + "storage limit (tonne)" => dict("Wood" => 5, "Nail" => 1), + "disposal cost (\$/tonne)" => dict("NewBoat" => 0), + "disposal limit (tonne)" => dict("NewBoat" => 0), + "capacities" => [ + dict( + "size (tonne)" => 500, + "opening cost (\$)" => 1_00_000, + "fixed operating cost (\$)" => 250_000, + "variable operating cost (\$/tonne)" => 5, + ), + dict( + "size (tonne)" => 1000, + "opening cost (\$)" => 2_000_000, + "fixed operating cost (\$)" => 500_000, + "variable operating cost (\$/tonne)" => 5, + ), + ], + "initial capacity (tonne)" => 0, + ) + + recycling_plant = dict( + "input mix (%)" => dict("UsedBoat" => 100), + "output (tonne)" => dict("Nail" => 0.025, "Wood" => 0.475), + "processing emissions (tonne)" => dict("CO2" => 5), + "storage cost (\$/tonne)" => dict("UsedBoat" => 0), + "storage limit (tonne)" => dict("UsedBoat" => 0), + "disposal cost (\$/tonne)" => dict("Nail" => 0, "Wood" => 0), + "disposal limit (tonne)" => dict("Nail" => 0, "Wood" => 0), + "capacities" => [ + dict( + "size (tonne)" => 500, + "opening cost (\$)" => 500_000, + "fixed operating cost (\$)" => 125_000, + "variable operating cost (\$/tonne)" => 2.5, + ), + dict( + "size (tonne)" => 1000, + "opening cost (\$)" => 1_000_000, + "fixed operating cost (\$)" => 250_000, + "variable operating cost (\$/tonne)" => 2.5, + ), + ], + "initial capacity (tonne)" => 0, + ) + + lat_lon_dict(city_location) = dict( + "latitude (deg)" => city_location[1], + "longitude (deg)" => city_location[2], + ) + + data = dict( + "parameters" => parameters, + "products" => + dict("Nail" => prod, "Wood" => prod, "NewBoat" => prod, "UsedBoat" => prod), + "centers" => merge( + dict( + "NailFactory ($city_name)" => merge( + nail_factory, + lat_lon_dict(city_location) + ) for (city_name, city_location) in cities_b + ), + dict( + "Forest ($city_name)" => merge( + forest, + lat_lon_dict(city_location) + ) for (city_name, city_location) in cities_b + ), + dict( + "Retail ($city_name)" => merge( + retail, + lat_lon_dict(city_location) + ) for (city_name, city_location) in cities_a + ), + ), + "plants" => merge( + dict( + "BoatFactory ($city_name)" => merge( + boat_factory, + lat_lon_dict(city_location) + ) for (city_name, city_location) in cities_a + ), + dict( + "RecyclingPlant ($city_name)" => merge( + recycling_plant, + lat_lon_dict(city_location) + ) for (city_name, city_location) in cities_a + ), + ), + ) + + open(fixture("boat_example.json"), "w") do file + JSON.print(file, data, 2) + end +end \ No newline at end of file diff --git a/test/fixtures/boat_example.json b/test/fixtures/boat_example.json index df7736b..34c1ab4 100644 --- a/test/fixtures/boat_example.json +++ b/test/fixtures/boat_example.json @@ -1340,4 +1340,4 @@ "longitude (deg)": -121.886329 } } -} \ No newline at end of file +} diff --git a/test/src/RELOGT.jl b/test/src/RELOGT.jl index 465485c..d61a7db 100644 --- a/test/src/RELOGT.jl +++ b/test/src/RELOGT.jl @@ -8,6 +8,7 @@ include("instance/parse_test.jl") include("model/build_test.jl") include("model/dist_test.jl") include("reports_test.jl") +include("../fixtures/boat_example.jl") basedir = dirname(@__FILE__) @@ -28,6 +29,7 @@ end function format() JuliaFormatter.format(basedir, verbose = true) JuliaFormatter.format("$basedir/../../src", verbose = true) + JuliaFormatter.format("$basedir/../fixtures", verbose = true) return end end # module RELOGT