mirror of
https://github.com/ANL-CEEESA/RELOG.git
synced 2025-12-05 23:38:52 -06:00
Implement compress method
This commit is contained in:
228
model-3.jl
228
model-3.jl
@@ -21,23 +21,23 @@ Random.seed!(42)
|
|||||||
# Structs
|
# Structs
|
||||||
# =========================================================================
|
# =========================================================================
|
||||||
|
|
||||||
Base.@kwdef struct Component
|
Base.@kwdef mutable struct Component
|
||||||
name::String
|
name::String
|
||||||
end
|
end
|
||||||
|
|
||||||
Base.@kwdef struct Product
|
Base.@kwdef mutable struct Product
|
||||||
name::String
|
name::String
|
||||||
comp::Vector{Component}
|
comp::Vector{Component}
|
||||||
end
|
end
|
||||||
|
|
||||||
Base.@kwdef struct Center
|
Base.@kwdef mutable struct Center
|
||||||
name::String
|
name::String
|
||||||
latitude::Float64
|
latitude::Float64
|
||||||
longitude::Float64
|
longitude::Float64
|
||||||
prod_out::Vector{Product}
|
prod_out::Vector{Product}
|
||||||
end
|
end
|
||||||
|
|
||||||
Base.@kwdef struct Plant
|
Base.@kwdef mutable struct Plant
|
||||||
name::String
|
name::String
|
||||||
latitude::Float64
|
latitude::Float64
|
||||||
longitude::Float64
|
longitude::Float64
|
||||||
@@ -45,7 +45,7 @@ Base.@kwdef struct Plant
|
|||||||
prod_in::Product
|
prod_in::Product
|
||||||
end
|
end
|
||||||
|
|
||||||
Base.@kwdef struct Emission
|
Base.@kwdef mutable struct Emission
|
||||||
name::String
|
name::String
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -310,7 +310,7 @@ end
|
|||||||
|
|
||||||
# Read
|
# Read
|
||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
function read_json(filename, max_centers = 10, max_plants = 10)
|
function read_json(filename; max_centers = Inf, max_plants = Inf)::Instance
|
||||||
json = JSON.parsefile(filename)
|
json = JSON.parsefile(filename)
|
||||||
T = 1:json["parameters"]["time horizon (years)"]
|
T = 1:json["parameters"]["time horizon (years)"]
|
||||||
centers = []
|
centers = []
|
||||||
@@ -484,6 +484,114 @@ function read_json(filename, max_centers = 10, max_plants = 10)
|
|||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Multi-period Heuristic
|
||||||
|
# ==============================================================================
|
||||||
|
|
||||||
|
function compress(original::Instance)::Instance
|
||||||
|
T = original.T
|
||||||
|
alpha_plant_emission = Dict(
|
||||||
|
(p, s, 1) => mean([original.alpha_plant_emission[p, s, t] for t in T]) for
|
||||||
|
p in original.plants, s in original.emissions
|
||||||
|
)
|
||||||
|
alpha_tr_emission = Dict(
|
||||||
|
(r, s, 1) => mean([original.alpha_tr_emission[r, s, t] for t in T]) for
|
||||||
|
r in original.products, s in original.emissions
|
||||||
|
)
|
||||||
|
c_acq = Dict(
|
||||||
|
(q, r, 1) => mean([original.c_acq[q, r, t] for t in T]) for
|
||||||
|
q in original.centers for r in q.prod_out
|
||||||
|
)
|
||||||
|
c_center_disp = Dict(
|
||||||
|
(q, r, 1) => mean([original.c_center_disp[q, r, t] for t in T]) for
|
||||||
|
q in original.centers for r in q.prod_out
|
||||||
|
)
|
||||||
|
c_emission = Dict(
|
||||||
|
(s, 1) => mean([original.c_emission[s, t] for t in T]) for s in original.emissions
|
||||||
|
)
|
||||||
|
c_fix = Dict((p, 1) => sum([original.c_fix[p, t] for t in T]) for p in original.plants)
|
||||||
|
c_open =
|
||||||
|
Dict((p, 1) => mean([original.c_open[p, t] for t in T]) for p in original.plants)
|
||||||
|
c_plant_disp = Dict(
|
||||||
|
(p, r, 1) => mean([original.c_plant_disp[p, r, t] for t in T]) for
|
||||||
|
p in original.plants for r in p.prod_out
|
||||||
|
)
|
||||||
|
c_store = Dict(
|
||||||
|
(q, r, 1) => mean([original.c_store[q, r, t] for t in T]) for
|
||||||
|
q in original.centers for r in q.prod_out
|
||||||
|
)
|
||||||
|
c_tr = Dict((r, 1) => mean([original.c_tr[r, t] for t in T]) for r in original.products)
|
||||||
|
c_var = Dict((p, 1) => mean([original.c_var[p, t] for t in T]) for p in original.plants)
|
||||||
|
m_cap = Dict(p => original.m_cap[p] * length(T) for p in original.plants)
|
||||||
|
m_center_disp = Dict(
|
||||||
|
(r, 1) => sum([original.m_center_disp[r, t] for t in T]) for r in original.products
|
||||||
|
)
|
||||||
|
m_emission = Dict(
|
||||||
|
(s, 1) => sum([original.m_emission[s, t] for t in T]) for s in original.emissions
|
||||||
|
)
|
||||||
|
m_init = Dict(
|
||||||
|
(q, r, c, 1) => sum([original.m_init[q, r, c, t] for t in T]) for
|
||||||
|
q in original.centers for r in q.prod_out for c in r.comp
|
||||||
|
)
|
||||||
|
m_plant_disp = Dict(
|
||||||
|
(p, r, 1) => sum([original.m_plant_disp[p, r, t] for t in T]) for
|
||||||
|
p in original.plants for r in p.prod_out
|
||||||
|
)
|
||||||
|
m_store = Dict(
|
||||||
|
(q, r, 1) => sum([original.m_store[q, r, t] for t in T]) for
|
||||||
|
q in original.centers for r in q.prod_out
|
||||||
|
)
|
||||||
|
return Instance(;
|
||||||
|
T = 1:1,
|
||||||
|
centers = original.centers,
|
||||||
|
plants = original.plants,
|
||||||
|
products = original.products,
|
||||||
|
emissions = original.emissions,
|
||||||
|
alpha_mix=original.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=original.m_dist,
|
||||||
|
m_emission,
|
||||||
|
m_init,
|
||||||
|
m_plant_disp,
|
||||||
|
m_store,
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
function benchmark_compress(filename, optimizer; max_centers=[Inf], max_plants=[Inf])
|
||||||
|
stats = []
|
||||||
|
for mc in max_centers, mp in max_plants
|
||||||
|
# Solve original
|
||||||
|
orig = read_json(filename; max_centers=mc, max_plants=mp)
|
||||||
|
reset_timer!()
|
||||||
|
stats_orig = solve(orig; optimizer)
|
||||||
|
stats_orig["Filename"] = filename
|
||||||
|
stats_orig["Method"] = "Original"
|
||||||
|
push!(stats, stats_orig)
|
||||||
|
|
||||||
|
# Solve compressed
|
||||||
|
compressed = compress(orig)
|
||||||
|
reset_timer!()
|
||||||
|
stats_comp = solve(compressed; optimizer)
|
||||||
|
stats_comp["Filename"] = filename
|
||||||
|
stats_comp["Method"] = "Compressed"
|
||||||
|
push!(stats, stats_comp)
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
return DataFrame(stats)
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
# Run
|
# Run
|
||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
@@ -496,13 +604,16 @@ function generate_json()
|
|||||||
write_json(data, "output-3/case.json")
|
write_json(data, "output-3/case.json")
|
||||||
end
|
end
|
||||||
|
|
||||||
function solve(filename, optimizer)
|
function solve(filename, optimizer; max_centers = Inf, max_plants = Inf)
|
||||||
reset_timer!()
|
reset_timer!()
|
||||||
|
|
||||||
@timeit "Read JSON" begin
|
@timeit "Read JSON" begin
|
||||||
data = read_json(filename)
|
data = read_json(filename; max_centers, max_plants)
|
||||||
end
|
end
|
||||||
|
return solve(data; optimizer = optimizer, output_dir = dirname(filename))
|
||||||
|
print_timer()
|
||||||
|
end
|
||||||
|
|
||||||
|
function solve(data::Instance; optimizer, output_dir=nothing)
|
||||||
T = data.T
|
T = data.T
|
||||||
centers = data.centers
|
centers = data.centers
|
||||||
plants = data.plants
|
plants = data.plants
|
||||||
@@ -510,6 +621,7 @@ function solve(filename, optimizer)
|
|||||||
emissions = data.emissions
|
emissions = data.emissions
|
||||||
|
|
||||||
model = Model(optimizer)
|
model = Model(optimizer)
|
||||||
|
init_time = time()
|
||||||
|
|
||||||
# Graph
|
# Graph
|
||||||
# -------------------------------------------------------------------------
|
# -------------------------------------------------------------------------
|
||||||
@@ -920,13 +1032,30 @@ function solve(filename, optimizer)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
model_build_time = time() - init_time
|
||||||
|
|
||||||
# Optimize
|
# Optimize
|
||||||
# -------------------------------------------------------------------------
|
# -------------------------------------------------------------------------
|
||||||
optimize!(model)
|
optimize!(model)
|
||||||
|
|
||||||
|
stats = OrderedDict{String,Any}(
|
||||||
|
"Plants" => length(plants),
|
||||||
|
"Centers" => length(centers),
|
||||||
|
"Products" => length(products),
|
||||||
|
"Time periods" => length(T),
|
||||||
|
"Model build time (s)" => model_build_time,
|
||||||
|
"Variables" => num_variables(model),
|
||||||
|
"Constraints" => num_constraints(model, count_variable_in_set_constraints=false),
|
||||||
|
"Objective Value" => objective_value(model),
|
||||||
|
"Solve time (s)" => solve_time(model),
|
||||||
|
)
|
||||||
|
|
||||||
|
if output_dir === nothing
|
||||||
|
return stats
|
||||||
|
end
|
||||||
|
|
||||||
# Report: Transportation
|
# Report: Transportation
|
||||||
# -------------------------------------------------------------------------
|
# -------------------------------------------------------------------------
|
||||||
output_dir = dirname(filename)
|
|
||||||
df = DataFrame()
|
df = DataFrame()
|
||||||
df."source" = String[]
|
df."source" = String[]
|
||||||
df."destination" = String[]
|
df."destination" = String[]
|
||||||
@@ -949,10 +1078,13 @@ function solve(filename, optimizer)
|
|||||||
r.name,
|
r.name,
|
||||||
c.name,
|
c.name,
|
||||||
t,
|
t,
|
||||||
round(data.m_dist[q, p], digits=2),
|
round(data.m_dist[q, p], digits = 2),
|
||||||
round(value(y[q, p, r][c, t]), digits=2),
|
round(value(y[q, p, r][c, t]), digits = 2),
|
||||||
round(data.m_dist[q, p] * data.c_tr[r, t] * value(y[q, p, r][c, t]), digits=2),
|
round(
|
||||||
round(data.c_var[p, t] * value(y[q, p, r][c, t]), digits=2),
|
data.m_dist[q, p] * data.c_tr[r, t] * value(y[q, p, r][c, t]),
|
||||||
|
digits = 2,
|
||||||
|
),
|
||||||
|
round(data.c_var[p, t] * value(y[q, p, r][c, t]), digits = 2),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
@@ -980,13 +1112,19 @@ function solve(filename, optimizer)
|
|||||||
r.name,
|
r.name,
|
||||||
c.name,
|
c.name,
|
||||||
t,
|
t,
|
||||||
round(data.m_init[q, r, c, t], digits=2),
|
round(data.m_init[q, r, c, t], digits = 2),
|
||||||
round(sum(value(y[q, p, r][c, t]) for (p, r2) in E_out[q] if r == r2), digits=2),
|
round(
|
||||||
round(value(z_store[q, r, c, t]), digits=2),
|
sum(value(y[q, p, r][c, t]) for (p, r2) in E_out[q] if r == r2),
|
||||||
round(value(z_center_disp[q, r, c, t]), digits=2),
|
digits = 2,
|
||||||
round(data.m_init[q, r, c, t] * data.c_acq[q, r, t], digits=2),
|
),
|
||||||
round(data.c_store[q, r, t] * value(z_store[q, r, c, t]), digits=2),
|
round(value(z_store[q, r, c, t]), digits = 2),
|
||||||
round(data.c_center_disp[q, r, t] * value(z_center_disp[q, r, c, t]), digits=2),
|
round(value(z_center_disp[q, r, c, t]), digits = 2),
|
||||||
|
round(data.m_init[q, r, c, t] * data.c_acq[q, r, t], digits = 2),
|
||||||
|
round(data.c_store[q, r, t] * value(z_store[q, r, c, t]), digits = 2),
|
||||||
|
round(
|
||||||
|
data.c_center_disp[q, r, t] * value(z_center_disp[q, r, c, t]),
|
||||||
|
digits = 2,
|
||||||
|
),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
@@ -1006,9 +1144,12 @@ function solve(filename, optimizer)
|
|||||||
[
|
[
|
||||||
p.name,
|
p.name,
|
||||||
t,
|
t,
|
||||||
round(value(x_open[p, t]), digits=2),
|
round(value(x_open[p, t]), digits = 2),
|
||||||
round(data.c_open[p, t] * (value(x_open[p, t]) - value(x_open[p, t-1])), digits=2),
|
round(
|
||||||
round(data.c_fix[p, t] * value(x_open[p, t]), digits=2),
|
data.c_open[p, t] * (value(x_open[p, t]) - value(x_open[p, t-1])),
|
||||||
|
digits = 2,
|
||||||
|
),
|
||||||
|
round(data.c_fix[p, t] * value(x_open[p, t]), digits = 2),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
@@ -1036,10 +1177,19 @@ function solve(filename, optimizer)
|
|||||||
r.name,
|
r.name,
|
||||||
c.name,
|
c.name,
|
||||||
t,
|
t,
|
||||||
round(value(z_prod[p, r, c, t]), digits=2),
|
round(value(z_prod[p, r, c, t]), digits = 2),
|
||||||
round(value(z_plant_disp[p, r, c, t]), digits=2),
|
round(value(z_plant_disp[p, r, c, t]), digits = 2),
|
||||||
round(sum(value(y[p, q, r][c, t]) for (q, r2) in E_out[p] if r == r2; init = 0.0), digits=2),
|
round(
|
||||||
round(data.c_plant_disp[p, r, t] * value(z_plant_disp[p, r, c, t]), digits=2),
|
sum(
|
||||||
|
value(y[p, q, r][c, t]) for (q, r2) in E_out[p] if r == r2;
|
||||||
|
init = 0.0,
|
||||||
|
),
|
||||||
|
digits = 2,
|
||||||
|
),
|
||||||
|
round(
|
||||||
|
data.c_plant_disp[p, r, t] * value(z_plant_disp[p, r, c, t]),
|
||||||
|
digits = 2,
|
||||||
|
),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
@@ -1060,8 +1210,11 @@ function solve(filename, optimizer)
|
|||||||
p.name,
|
p.name,
|
||||||
s.name,
|
s.name,
|
||||||
t,
|
t,
|
||||||
round(value(z_plant_emissions[p, s, t]), digits=2),
|
round(value(z_plant_emissions[p, s, t]), digits = 2),
|
||||||
round(data.c_emission[s, t] * value(z_plant_emissions[p, s, t]), digits=2),
|
round(
|
||||||
|
data.c_emission[s, t] * value(z_plant_emissions[p, s, t]),
|
||||||
|
digits = 2,
|
||||||
|
),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
@@ -1091,16 +1244,17 @@ function solve(filename, optimizer)
|
|||||||
r.name,
|
r.name,
|
||||||
s.name,
|
s.name,
|
||||||
t,
|
t,
|
||||||
round(data.m_dist[q, p], digits=2),
|
round(data.m_dist[q, p], digits = 2),
|
||||||
round(value(y_total[q, p, r][t]), digits=2),
|
round(value(y_total[q, p, r][t]), digits = 2),
|
||||||
round(value(z_tr_emissions[q, p, r, s, t]), digits=2),
|
round(value(z_tr_emissions[q, p, r, s, t]), digits = 2),
|
||||||
round(data.c_emission[s, t] * value(z_tr_emissions[q, p, r, s, t]), digits=2),
|
round(
|
||||||
|
data.c_emission[s, t] * value(z_tr_emissions[q, p, r, s, t]),
|
||||||
|
digits = 2,
|
||||||
|
),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
CSV.write("$output_dir/transp-emissions.csv", df)
|
CSV.write("$output_dir/transp-emissions.csv", df)
|
||||||
|
|
||||||
print_timer()
|
return stats
|
||||||
|
|
||||||
return
|
|
||||||
end
|
end
|
||||||
|
|||||||
Reference in New Issue
Block a user