mirror of
https://github.com/ANL-CEEESA/RELOG.git
synced 2025-12-06 07:48:50 -06:00
Add new structs for instance
This commit is contained in:
166
src/instance.jl
166
src/instance.jl
@@ -4,17 +4,59 @@
|
||||
using Printf, JSON, JSONSchema
|
||||
import Base.getindex, Base.time
|
||||
|
||||
"""
|
||||
mutable struct ReverseManufacturingInstance
|
||||
|
||||
Representation of an instance of the Facility Location for Reverse Manufacturing problem.
|
||||
"""
|
||||
struct Product
|
||||
name::String
|
||||
transportation_cost::Float64
|
||||
end
|
||||
|
||||
|
||||
struct CollectionCenter
|
||||
name::String
|
||||
latitude::Float64
|
||||
longitude::Float64
|
||||
product::Product
|
||||
amount::Float64
|
||||
end
|
||||
|
||||
|
||||
struct DisposalEntry
|
||||
product::Product
|
||||
cost::Float64
|
||||
limit::Float64
|
||||
end
|
||||
|
||||
|
||||
struct Plant
|
||||
name::String
|
||||
input::Product
|
||||
output::Dict{Product, Float64}
|
||||
latitude::Float64
|
||||
longitude::Float64
|
||||
variable_operating_cost::Float64
|
||||
fixed_operating_cost::Float64
|
||||
opening_cost::Float64
|
||||
base_capacity::Float64
|
||||
max_capacity::Float64
|
||||
expansion_cost::Float64
|
||||
disposal::Array{DisposalEntry}
|
||||
end
|
||||
|
||||
|
||||
struct Instance
|
||||
products::Array{Product, 1}
|
||||
collection_centers::Array{CollectionCenter, 1}
|
||||
plants::Array{Plant, 1}
|
||||
end
|
||||
|
||||
|
||||
mutable struct ReverseManufacturingInstance
|
||||
json::Dict
|
||||
products::Dict
|
||||
plants::Dict
|
||||
end
|
||||
|
||||
|
||||
function Base.show(io::IO, instance::ReverseManufacturingInstance)
|
||||
n_plants = length(instance["plants"])
|
||||
n_products = length(instance["products"])
|
||||
@@ -23,34 +65,103 @@ function Base.show(io::IO, instance::ReverseManufacturingInstance)
|
||||
print(io, "$n_products products")
|
||||
end
|
||||
|
||||
"""
|
||||
load(name::String)::ReverseManufacturingInstance
|
||||
|
||||
Loads an instance from the benchmark set.
|
||||
|
||||
Example
|
||||
=======
|
||||
|
||||
julia> ReverseManufacturing.load("samples/s1.json")
|
||||
|
||||
"""
|
||||
function load(name::String) :: ReverseManufacturingInstance
|
||||
function load(path::String)::Instance
|
||||
basedir = dirname(@__FILE__)
|
||||
return ReverseManufacturing.readfile("$basedir/../instances/$name.json")
|
||||
json = JSON.parsefile(path)
|
||||
schema = Schema(JSON.parsefile("$basedir/schemas/input.json"))
|
||||
|
||||
validation_results = JSONSchema.validate(json, schema)
|
||||
if validation_results !== nothing
|
||||
println(validation_results)
|
||||
throw("Invalid input file")
|
||||
end
|
||||
|
||||
products = Product[]
|
||||
collection_centers = CollectionCenter[]
|
||||
plants = Plant[]
|
||||
|
||||
product_name_to_product = Dict{String, Product}()
|
||||
|
||||
# Create products
|
||||
for (product_name, product_dict) in json["products"]
|
||||
product = Product(product_name, product_dict["transportation cost"])
|
||||
push!(products, product)
|
||||
product_name_to_product[product_name] = product
|
||||
|
||||
# Create collection centers
|
||||
if "initial amounts" in keys(product_dict)
|
||||
for (center_name, center_dict) in product_dict["initial amounts"]
|
||||
center = CollectionCenter(center_name,
|
||||
center_dict["latitude"],
|
||||
center_dict["longitude"],
|
||||
product,
|
||||
center_dict["amount"])
|
||||
push!(collection_centers, center)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Create plants
|
||||
for (plant_name, plant_dict) in json["plants"]
|
||||
input = product_name_to_product[plant_dict["input"]]
|
||||
output = Dict()
|
||||
|
||||
# Plant outputs
|
||||
if "outputs" in keys(plant_dict)
|
||||
output = Dict(product_name_to_product[key] => value
|
||||
for (key, value) in plant_dict["outputs"]
|
||||
if value > 0)
|
||||
end
|
||||
|
||||
for (location_name, location_dict) in plant_dict["locations"]
|
||||
disposal = DisposalEntry[]
|
||||
|
||||
# Plant disposal
|
||||
if "disposal" in keys(location_dict)
|
||||
for (product_name, disposal_dict) in location_dict["disposal"]
|
||||
push!(disposal, DisposalEntry(product_name_to_product[product_name],
|
||||
disposal_dict["cost"],
|
||||
disposal_dict["limit"]))
|
||||
end
|
||||
end
|
||||
|
||||
base_capacity = Inf
|
||||
max_capacity = Inf
|
||||
expansion_cost = 0
|
||||
|
||||
if "base capacity" in keys(location_dict)
|
||||
base_capacity = location_dict["base capacity"]
|
||||
end
|
||||
|
||||
if "max capacity" in keys(location_dict)
|
||||
max_capacity = location_dict["max capacity"]
|
||||
end
|
||||
|
||||
if "expansion cost" in keys(location_dict)
|
||||
expansion_cost = location_dict["expansion cost"]
|
||||
end
|
||||
|
||||
plant = Plant(location_name,
|
||||
input,
|
||||
output,
|
||||
location_dict["latitude"],
|
||||
location_dict["longitude"],
|
||||
location_dict["variable operating cost"],
|
||||
location_dict["fixed operating cost"],
|
||||
location_dict["opening cost"],
|
||||
base_capacity,
|
||||
max_capacity,
|
||||
expansion_cost,
|
||||
disposal)
|
||||
push!(plants, plant)
|
||||
end
|
||||
end
|
||||
|
||||
return Instance(products, collection_centers, plants)
|
||||
end
|
||||
|
||||
|
||||
"""
|
||||
readfile(path::String)::ReverseManufacturingInstance
|
||||
|
||||
Loads an instance from the given JSON file.
|
||||
|
||||
Example
|
||||
=======
|
||||
|
||||
julia> ReverseManufacturing.load("/home/user/instance.json")
|
||||
|
||||
"""
|
||||
function readfile(path::String)::ReverseManufacturingInstance
|
||||
basedir = dirname(@__FILE__)
|
||||
json = JSON.parsefile(path)
|
||||
@@ -105,4 +216,5 @@ function readfile(path::String)::ReverseManufacturingInstance
|
||||
return ReverseManufacturingInstance(json, products, plants)
|
||||
end
|
||||
|
||||
|
||||
export ReverseManufacturingInstance
|
||||
|
||||
Reference in New Issue
Block a user