mirror of
https://github.com/ANL-CEEESA/RELOG.git
synced 2025-12-06 07:48:50 -06:00
Switch from Euclidean to approximate driving distance
This commit is contained in:
@@ -11,6 +11,10 @@ All notable changes to this project will be documented in this file.
|
|||||||
[semver]: https://semver.org/spec/v2.0.0.html
|
[semver]: https://semver.org/spec/v2.0.0.html
|
||||||
[pkjjl]: https://pkgdocs.julialang.org/v1/compatibility/#compat-pre-1.0
|
[pkjjl]: https://pkgdocs.julialang.org/v1/compatibility/#compat-pre-1.0
|
||||||
|
|
||||||
|
# [0.6.0] -- 2022-12-15
|
||||||
|
### Changed
|
||||||
|
- Switch from Euclidean distance to approximate driving distance
|
||||||
|
|
||||||
## [0.5.2] -- 2022-08-26
|
## [0.5.2] -- 2022-08-26
|
||||||
### Changed
|
### Changed
|
||||||
- Update to JuMP 1.x
|
- Update to JuMP 1.x
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
name = "RELOG"
|
name = "RELOG"
|
||||||
uuid = "a2afcdf7-cf04-4913-85f9-c0d81ddf2008"
|
uuid = "a2afcdf7-cf04-4913-85f9-c0d81ddf2008"
|
||||||
authors = ["Alinson S Xavier <axavier@anl.gov>"]
|
authors = ["Alinson S Xavier <axavier@anl.gov>"]
|
||||||
version = "0.5.2"
|
version = "0.6.0"
|
||||||
|
|
||||||
[deps]
|
[deps]
|
||||||
CRC = "44b605c4-b955-5f2b-9b6d-d2bd01d3d205"
|
CRC = "44b605c4-b955-5f2b-9b6d-d2bd01d3d205"
|
||||||
@@ -18,6 +18,7 @@ JSONSchema = "7d188eb4-7ad8-530c-ae41-71a32a6d4692"
|
|||||||
JuMP = "4076af6c-e467-56ae-b986-b466b2749572"
|
JuMP = "4076af6c-e467-56ae-b986-b466b2749572"
|
||||||
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
|
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
|
||||||
MathOptInterface = "b8f27783-ece8-5eb3-8dc8-9495eed66fee"
|
MathOptInterface = "b8f27783-ece8-5eb3-8dc8-9495eed66fee"
|
||||||
|
NearestNeighbors = "b8a86587-4115-5ab1-83bc-aa920d37bbce"
|
||||||
OrderedCollections = "bac558e1-5e72-5ebc-8fee-abe8a469f55d"
|
OrderedCollections = "bac558e1-5e72-5ebc-8fee-abe8a469f55d"
|
||||||
Printf = "de0858da-6303-5e67-8744-51eddeeeb8d7"
|
Printf = "de0858da-6303-5e67-8744-51eddeeeb8d7"
|
||||||
ProgressBars = "49802e3a-d2f1-5c88-81d8-b72133a6f568"
|
ProgressBars = "49802e3a-d2f1-5c88-81d8-b72133a6f568"
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ To use RELOG, the first step is to install the [Julia programming language](http
|
|||||||
|
|
||||||
```julia
|
```julia
|
||||||
using Pkg
|
using Pkg
|
||||||
Pkg.add(name="RELOG", version="0.5")
|
Pkg.add(name="RELOG", version="0.6")
|
||||||
```
|
```
|
||||||
|
|
||||||
After the package and all its dependencies have been installed, please run the RELOG test suite, as shown below, to make sure that the package has been correctly installed:
|
After the package and all its dependencies have been installed, please run the RELOG test suite, as shown below, to make sure that the package has been correctly installed:
|
||||||
|
|||||||
@@ -5,19 +5,19 @@
|
|||||||
module RELOG
|
module RELOG
|
||||||
|
|
||||||
include("instance/structs.jl")
|
include("instance/structs.jl")
|
||||||
|
|
||||||
include("graph/structs.jl")
|
include("graph/structs.jl")
|
||||||
|
|
||||||
|
include("instance/geodb.jl")
|
||||||
|
include("graph/dist.jl")
|
||||||
include("graph/build.jl")
|
include("graph/build.jl")
|
||||||
include("graph/csv.jl")
|
include("graph/csv.jl")
|
||||||
include("instance/compress.jl")
|
include("instance/compress.jl")
|
||||||
include("instance/geodb.jl")
|
|
||||||
include("instance/parse.jl")
|
include("instance/parse.jl")
|
||||||
include("instance/validate.jl")
|
include("instance/validate.jl")
|
||||||
include("model/build.jl")
|
include("model/build.jl")
|
||||||
include("model/getsol.jl")
|
include("model/getsol.jl")
|
||||||
include("model/solve.jl")
|
|
||||||
include("model/resolve.jl")
|
include("model/resolve.jl")
|
||||||
|
include("model/solve.jl")
|
||||||
include("reports/plant_emissions.jl")
|
include("reports/plant_emissions.jl")
|
||||||
include("reports/plant_outputs.jl")
|
include("reports/plant_outputs.jl")
|
||||||
include("reports/plants.jl")
|
include("reports/plants.jl")
|
||||||
|
|||||||
@@ -2,14 +2,6 @@
|
|||||||
# Copyright (C) 2020, UChicago Argonne, LLC. All rights reserved.
|
# Copyright (C) 2020, UChicago Argonne, LLC. All rights reserved.
|
||||||
# Released under the modified BSD license. See COPYING.md for more details.
|
# Released under the modified BSD license. See COPYING.md for more details.
|
||||||
|
|
||||||
using Geodesy
|
|
||||||
|
|
||||||
function calculate_distance(source_lat, source_lon, dest_lat, dest_lon)::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 = 2)
|
|
||||||
end
|
|
||||||
|
|
||||||
function build_graph(instance::Instance)::Graph
|
function build_graph(instance::Instance)::Graph
|
||||||
arcs = []
|
arcs = []
|
||||||
next_index = 0
|
next_index = 0
|
||||||
@@ -48,13 +40,15 @@ function build_graph(instance::Instance)::Graph
|
|||||||
end
|
end
|
||||||
|
|
||||||
# Build arcs from collection centers to plants, and from one plant to another
|
# Build arcs from collection centers to plants, and from one plant to another
|
||||||
|
metric = _KnnDrivingDistance()
|
||||||
for source in [collection_shipping_nodes; plant_shipping_nodes]
|
for source in [collection_shipping_nodes; plant_shipping_nodes]
|
||||||
for dest in process_nodes_by_input_product[source.product]
|
for dest in process_nodes_by_input_product[source.product]
|
||||||
distance = calculate_distance(
|
distance = _calculate_distance(
|
||||||
source.location.latitude,
|
source.location.latitude,
|
||||||
source.location.longitude,
|
source.location.longitude,
|
||||||
dest.location.latitude,
|
dest.location.latitude,
|
||||||
dest.location.longitude,
|
dest.location.longitude,
|
||||||
|
metric,
|
||||||
)
|
)
|
||||||
values = Dict("distance" => distance)
|
values = Dict("distance" => distance)
|
||||||
arc = Arc(source, dest, values)
|
arc = Arc(source, dest, values)
|
||||||
|
|||||||
69
src/graph/dist.jl
Normal file
69
src/graph/dist.jl
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
# RELOG: Reverse Logistics Optimization
|
||||||
|
# Copyright (C) 2020, UChicago Argonne, LLC. All rights reserved.
|
||||||
|
# Released under the modified BSD license. See COPYING.md for more details.
|
||||||
|
|
||||||
|
using Geodesy
|
||||||
|
using NearestNeighbors
|
||||||
|
using DataFrames
|
||||||
|
|
||||||
|
Base.@kwdef mutable struct _KnnDrivingDistance
|
||||||
|
tree = nothing
|
||||||
|
ratios = nothing
|
||||||
|
end
|
||||||
|
|
||||||
|
mutable struct _EuclideanDistance 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 _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))
|
||||||
|
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])
|
||||||
|
return round(dist_euclidean * ratio_pred, digits = 3)
|
||||||
|
end
|
||||||
@@ -21,7 +21,7 @@ using RELOG
|
|||||||
@test node.outgoing_arcs[1].source.location.name == "C1"
|
@test node.outgoing_arcs[1].source.location.name == "C1"
|
||||||
@test node.outgoing_arcs[1].dest.location.plant_name == "F1"
|
@test node.outgoing_arcs[1].dest.location.plant_name == "F1"
|
||||||
@test node.outgoing_arcs[1].dest.location.location_name == "L1"
|
@test node.outgoing_arcs[1].dest.location.location_name == "L1"
|
||||||
@test node.outgoing_arcs[1].values["distance"] == 1095.62
|
@test node.outgoing_arcs[1].values["distance"] == 1695.364
|
||||||
|
|
||||||
node = process_node_by_location_name["L1"]
|
node = process_node_by_location_name["L1"]
|
||||||
@test node.location.plant_name == "F1"
|
@test node.location.plant_name == "F1"
|
||||||
|
|||||||
25
test/graph/dist_test.jl
Normal file
25
test/graph/dist_test.jl
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
# RELOG: Reverse Logistics Optimization
|
||||||
|
# Copyright (C) 2020, UChicago Argonne, LLC. All rights reserved.
|
||||||
|
# Released under the modified BSD license. See COPYING.md for more details.
|
||||||
|
|
||||||
|
using RELOG
|
||||||
|
|
||||||
|
@testset "KnnDrivingDistance" begin
|
||||||
|
# Euclidean distance between Chicago and Indianapolis
|
||||||
|
@test RELOG._calculate_distance(
|
||||||
|
41.866,
|
||||||
|
-87.656,
|
||||||
|
39.764,
|
||||||
|
-86.148,
|
||||||
|
RELOG._EuclideanDistance(),
|
||||||
|
) == 265.818
|
||||||
|
|
||||||
|
# Approximate driving distance between Chicago and Indianapolis
|
||||||
|
@test RELOG._calculate_distance(
|
||||||
|
41.866,
|
||||||
|
-87.656,
|
||||||
|
39.764,
|
||||||
|
-86.148,
|
||||||
|
RELOG._KnnDrivingDistance(),
|
||||||
|
) == 316.43
|
||||||
|
end
|
||||||
@@ -11,6 +11,7 @@ using Test
|
|||||||
end
|
end
|
||||||
@testset "Graph" begin
|
@testset "Graph" begin
|
||||||
include("graph/build_test.jl")
|
include("graph/build_test.jl")
|
||||||
|
include("graph/dist_test.jl")
|
||||||
end
|
end
|
||||||
@testset "Model" begin
|
@testset "Model" begin
|
||||||
include("model/build_test.jl")
|
include("model/build_test.jl")
|
||||||
|
|||||||
Reference in New Issue
Block a user