3 Commits

Author SHA1 Message Date
7dbc3cf90b model: Capacity cannot decrease over time 2025-11-14 10:24:58 -06:00
b7d16fee3e model: Fix division by zero 2025-11-14 10:14:20 -06:00
eedf023b47 Fix RELOG.parsefile 2025-11-14 10:13:59 -06:00
4 changed files with 39 additions and 8 deletions

View File

@@ -249,6 +249,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

View File

@@ -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

View File

@@ -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)
@@ -361,6 +370,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

View File

@@ -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]) ==