mirror of
https://github.com/ANL-CEEESA/RELOG.git
synced 2025-12-06 07:48:50 -06:00
Compare commits
5 Commits
5eee29547c
...
product_de
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9c2e2610da | ||
|
|
8186482db5 | ||
| 7dbc3cf90b | |||
| b7d16fee3e | |||
| eedf023b47 |
@@ -66,6 +66,8 @@ The mathematical model employed by RELOG is based on three main components:
|
|||||||
| $K^\text{out-var}_{cmi}$ | Factor used to calculate variable amount of material $m$ collected at center $c$. See `eq_z_collected` for more details. | -- |
|
| $K^\text{out-var}_{cmi}$ | Factor used to calculate variable amount of material $m$ collected at center $c$. See `eq_z_collected` for more details. | -- |
|
||||||
| $K^\text{output}_{pmt}$ | Amount of material $m$ produced by plant $p$ at time $t$ for each tonne of input material processed | tonne |
|
| $K^\text{output}_{pmt}$ | Amount of material $m$ produced by plant $p$ at time $t$ for each tonne of input material processed | tonne |
|
||||||
| $K^\text{storage-limit}_{pm}$ | Maximum amount of material $m$ that can be stored at plant $p$ at any time | tonne |
|
| $K^\text{storage-limit}_{pm}$ | Maximum amount of material $m$ that can be stored at plant $p$ at any time | tonne |
|
||||||
|
| $K^\text{dem-min}_{mt}$ | Minimum demand of material $m$ at time $t$ | tonne |
|
||||||
|
| $K^\text{dem-max}_{mt}$ | Maximum demand of material $m$ at time $t$ | tonne |
|
||||||
| $R^\text{collect}_{cmt}$ | Cost of collecting material $m$ at center $c$ at time $t$ | \$/tonne |
|
| $R^\text{collect}_{cmt}$ | Cost of collecting material $m$ at center $c$ at time $t$ | \$/tonne |
|
||||||
| $R^\text{disp}_{umt}$ | Cost to dispose of material at plant/center $u$ at time $t$ | \$/tonne |
|
| $R^\text{disp}_{umt}$ | Cost to dispose of material at plant/center $u$ at time $t$ | \$/tonne |
|
||||||
| $R^\text{em}_{gt}$ | Penalty cost per tonne of greenhouse gas $g$ emitted at time $t$ | \$/tonne |
|
| $R^\text{em}_{gt}$ | Penalty cost per tonne of greenhouse gas $g$ emitted at time $t$ | \$/tonne |
|
||||||
@@ -249,6 +251,15 @@ The goal is to minimize a linear objective function with the following terms:
|
|||||||
\end{align*}
|
\end{align*}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
- Plant capacity cannot decrease over time (`eq_capacity_nondecreasing[p.name, t]`):
|
||||||
|
|
||||||
|
```math
|
||||||
|
\begin{align*}
|
||||||
|
& z^\text{exp}_{pt} \geq z^\text{exp}_{p,t-1}
|
||||||
|
& \forall p \in P, t \in T
|
||||||
|
\end{align*}
|
||||||
|
```
|
||||||
|
|
||||||
- Plant is initially open if initial capacity is positive:
|
- Plant is initially open if initial capacity is positive:
|
||||||
|
|
||||||
```math
|
```math
|
||||||
@@ -317,6 +328,21 @@ The goal is to minimize a linear objective function with the following terms:
|
|||||||
\end{align*}
|
\end{align*}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
- Minimum product demands for products at centers:
|
||||||
|
```math
|
||||||
|
\begin{align*}
|
||||||
|
& \sum_{c : m \in M^-_c} \sum_{u : (u,m) \in E^-(c)} y_{ucmt} \geq K^\text{dem-min}_{mt}
|
||||||
|
& \forall m \in M, t \in T
|
||||||
|
\end{align*}
|
||||||
|
```
|
||||||
|
- Maximum product demands for products at centers:
|
||||||
|
```math
|
||||||
|
\begin{align*}
|
||||||
|
& \sum_{c : m \in M^-_c} \sum_{u : (u,m) \in E^-(c)} y_{ucmt} \leq K^\text{dem-max}_{mt}
|
||||||
|
& \forall m \in M, t \in T
|
||||||
|
\end{align*}
|
||||||
|
```
|
||||||
|
|
||||||
- Calculation of amount collected by the center
|
- Calculation of amount collected by the center
|
||||||
(`eq_z_collected[c.name, m.name, t]`). In the equation below,
|
(`eq_z_collected[c.name, m.name, t]`). In the equation below,
|
||||||
$K^\text{out-var-len}$ is the length of the $K^\text{out-var}_{c,m,*}$ vector.
|
$K^\text{out-var-len}$ is the length of the $K^\text{out-var}_{c,m,*}$ vector.
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ using JSON
|
|||||||
using OrderedCollections
|
using OrderedCollections
|
||||||
|
|
||||||
function parsefile(path::String)::Instance
|
function parsefile(path::String)::Instance
|
||||||
return RELOG.parse(JSON.parsefile(path, dicttype = () -> OrderedDict()))
|
return RELOG.parse(JSON.parsefile(path; dicttype = OrderedDict))
|
||||||
end
|
end
|
||||||
|
|
||||||
function parse(json)::Instance
|
function parse(json)::Instance
|
||||||
|
|||||||
@@ -4,13 +4,22 @@
|
|||||||
|
|
||||||
using JuMP
|
using JuMP
|
||||||
|
|
||||||
R_expand(p::Plant, t::Int) =
|
function R_expand(p::Plant, t::Int)
|
||||||
(p.capacities[2].opening_cost[t] - p.capacities[1].opening_cost[t]) /
|
denominator = p.capacities[2].size - p.capacities[1].size
|
||||||
(p.capacities[2].size - p.capacities[1].size)
|
if denominator == 0
|
||||||
|
return 0.0
|
||||||
|
end
|
||||||
|
return (p.capacities[2].opening_cost[t] - p.capacities[1].opening_cost[t]) / denominator
|
||||||
|
end
|
||||||
|
|
||||||
R_fix_exp(p::Plant, t::Int) =
|
function R_fix_exp(p::Plant, t::Int)
|
||||||
(p.capacities[2].fix_operating_cost[t] - p.capacities[1].fix_operating_cost[t]) /
|
denominator = p.capacities[2].size - p.capacities[1].size
|
||||||
(p.capacities[2].size - p.capacities[1].size)
|
if denominator == 0
|
||||||
|
return 0.0
|
||||||
|
end
|
||||||
|
return (p.capacities[2].fix_operating_cost[t] - p.capacities[1].fix_operating_cost[t]) /
|
||||||
|
denominator
|
||||||
|
end
|
||||||
|
|
||||||
function build_model(instance::Instance; optimizer, variable_names::Bool = false)
|
function build_model(instance::Instance; optimizer, variable_names::Bool = false)
|
||||||
model = JuMP.Model(optimizer)
|
model = JuMP.Model(optimizer)
|
||||||
@@ -347,6 +356,29 @@ function build_model(instance::Instance; optimizer, variable_names::Bool = false
|
|||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
# Demand bounds (only when active: > 0 for min; finite and > 0 for max)
|
||||||
|
eq_min_demand = _init(model, :eq_min_demand)
|
||||||
|
eq_max_demand = _init(model, :eq_max_demand)
|
||||||
|
for m in products, t in T
|
||||||
|
if m.minimum_demand[t] > 0
|
||||||
|
eq_min_demand[m.name, t] = @constraint(
|
||||||
|
model,
|
||||||
|
sum(
|
||||||
|
y[src.name, c.name, m.name, t] for c in centers if c.input == m for (src, m2) in E_in[c] if m2 == m
|
||||||
|
) >= m.minimum_demand[t]
|
||||||
|
)
|
||||||
|
end
|
||||||
|
if isfinite(m.maximum_demand[t]) && m.maximum_demand[t] > 0
|
||||||
|
eq_max_demand[m.name, t] = @constraint(
|
||||||
|
model,
|
||||||
|
sum(
|
||||||
|
y[src.name, c.name, m.name, t] for c in centers if c.input == m for (src, m2) in E_in[c] if m2 == m
|
||||||
|
) <= m.maximum_demand[t]
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
# Plants: Disposal limit
|
# Plants: Disposal limit
|
||||||
eq_disposal_limit = _init(model, :eq_disposal_limit)
|
eq_disposal_limit = _init(model, :eq_disposal_limit)
|
||||||
for p in plants, m in keys(p.output), t in T
|
for p in plants, m in keys(p.output), t in T
|
||||||
@@ -361,6 +393,13 @@ function build_model(instance::Instance; optimizer, variable_names::Bool = false
|
|||||||
eq_keep_open[p.name, t] = @constraint(model, x[p.name, t] >= x[p.name, t-1])
|
eq_keep_open[p.name, t] = @constraint(model, x[p.name, t] >= x[p.name, t-1])
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Plants: Capacity cannot decrease over time
|
||||||
|
eq_capacity_nondecreasing = _init(model, :eq_capacity_nondecreasing)
|
||||||
|
for p in plants, t in T
|
||||||
|
eq_capacity_nondecreasing[p.name, t] =
|
||||||
|
@constraint(model, z_exp[p.name, t] >= z_exp[p.name, t-1])
|
||||||
|
end
|
||||||
|
|
||||||
# Plants: Building period
|
# Plants: Building period
|
||||||
eq_building_period = _init(model, :eq_building_period)
|
eq_building_period = _init(model, :eq_building_period)
|
||||||
for p in plants, t in T
|
for p in plants, t in T
|
||||||
@@ -389,7 +428,7 @@ function build_model(instance::Instance; optimizer, variable_names::Bool = false
|
|||||||
z_collected[c.name, m.name, t] ==
|
z_collected[c.name, m.name, t] ==
|
||||||
sum(
|
sum(
|
||||||
z_input[c.name, t-offset] * c.var_output[m][offset+1] for
|
z_input[c.name, t-offset] * c.var_output[m][offset+1] for
|
||||||
offset = 0:min(M - 1, t - 1)
|
offset = 0:min(M-1, t-1)
|
||||||
) + c.fixed_output[m][t]
|
) + c.fixed_output[m][t]
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -128,6 +128,12 @@ function model_build_test()
|
|||||||
"eq_keep_open[L1,4] : -x[L1,3] + x[L1,4] ≥ 0"
|
"eq_keep_open[L1,4] : -x[L1,3] + x[L1,4] ≥ 0"
|
||||||
@test repr(model[:eq_keep_open]["L1", 1]) == "eq_keep_open[L1,1] : x[L1,1] ≥ 1"
|
@test repr(model[:eq_keep_open]["L1", 1]) == "eq_keep_open[L1,1] : x[L1,1] ≥ 1"
|
||||||
|
|
||||||
|
# Plants: Capacity cannot decrease over time
|
||||||
|
@test repr(model[:eq_capacity_nondecreasing]["L1", 4]) ==
|
||||||
|
"eq_capacity_nondecreasing[L1,4] : -z_exp[L1,3] + z_exp[L1,4] ≥ 0"
|
||||||
|
@test repr(model[:eq_capacity_nondecreasing]["L1", 1]) ==
|
||||||
|
"eq_capacity_nondecreasing[L1,1] : z_exp[L1,1] ≥ 150"
|
||||||
|
|
||||||
# Plants: Building period
|
# Plants: Building period
|
||||||
@test ("L1", 1) ∉ keys(model[:eq_building_period])
|
@test ("L1", 1) ∉ keys(model[:eq_building_period])
|
||||||
@test repr(model[:eq_building_period]["L1", 2]) ==
|
@test repr(model[:eq_building_period]["L1", 2]) ==
|
||||||
|
|||||||
Reference in New Issue
Block a user