-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Start implementation of circular model
- Loading branch information
Showing
9 changed files
with
169 additions
and
8 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,8 @@ | ||
module RELOG | ||
|
||
include("instance/structs.jl") | ||
|
||
include("instance/parse.jl") | ||
include("model/jumpext.jl") | ||
include("model/build.jl") | ||
|
||
end # module RELOG |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
using JuMP | ||
|
||
function build_model(instance::Instance; optimizer, variable_names::Bool = false) | ||
model = JuMP.Model(optimizer) | ||
centers = instance.centers | ||
products = instance.products | ||
plants = instance.plants | ||
T = 1:instance.time_horizon | ||
|
||
# Transportation edges | ||
# ------------------------------------------------------------------------- | ||
E = [] | ||
for m in products | ||
for p1 in plants | ||
m ∉ keys(p1.output) || continue | ||
|
||
# Plant to plant | ||
for p2 in plants | ||
p1 != p2 || continue | ||
m ∉ keys(p2.input_mix) || continue | ||
push!(E, (p1, p2, m)) | ||
end | ||
|
||
# Plant to center | ||
for c in centers | ||
m == c.input || continue | ||
push!(E, (p1, c, m)) | ||
end | ||
end | ||
|
||
for c1 in centers | ||
m ∈ c1.outputs || continue | ||
|
||
# Center to plant | ||
for p in plants | ||
m ∈ keys(p.input_mix) || continue | ||
push!(E, (c1, p, m)) | ||
end | ||
|
||
# Center to center | ||
for c2 in centers | ||
m == c2.input || continue | ||
push!(E, (c1, c2, m)) | ||
end | ||
end | ||
end | ||
|
||
|
||
# Decision variables | ||
# ------------------------------------------------------------------------- | ||
|
||
# Plant p is operational at time t | ||
x = _init(model, :x) | ||
for p in plants, t in T | ||
x[p.name, t] = @variable(model, binary = true) | ||
end | ||
|
||
# Amount of product m sent from center/plant u to center/plant v at time T | ||
y = _init(model, :y) | ||
for (p1, p2, m) in E, t in T | ||
y[p1.name, p2.name, m.name, t] = @variable(model, lower_bound=0) | ||
end | ||
|
||
# Amount of product m produced by plant/center at time T | ||
z_prod = _init(model, :z_prod) | ||
for p in plants, m in keys(p.output), t in T | ||
z_prod[p.name, m.name, t] = @variable(model, lower_bound=0) | ||
end | ||
for c in centers, m in c.outputs, t in T | ||
z_prod[c.name, m.name, t] = @variable(model, lower_bound=0) | ||
end | ||
|
||
# Amount of product m disposed at plant/center p at time T | ||
z_disp = _init(model, :z_disp) | ||
for p in plants, m in keys(p.output), t in T | ||
z_disp[p.name, m.name, t] = @variable(model, lower_bound=0) | ||
end | ||
for c in centers, m in c.outputs, t in T | ||
z_disp[c.name, m.name, t] = @variable(model, lower_bound=0) | ||
end | ||
|
||
|
||
# Objective function | ||
# ------------------------------------------------------------------------- | ||
|
||
|
||
# Constraints | ||
# ------------------------------------------------------------------------- | ||
|
||
|
||
if variable_names | ||
_set_names!(model) | ||
end | ||
return model | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
# This file extends some JuMP functions so that decision variables can be safely | ||
# replaced by (constant) floating point numbers. | ||
|
||
using Printf | ||
using JuMP | ||
|
||
import JuMP: value, fix, set_name | ||
|
||
function value(x::Float64) | ||
return x | ||
end | ||
|
||
function fix(x::Float64, v::Float64; force) | ||
return abs(x - v) < 1e-6 || error("Value mismatch: $x != $v") | ||
end | ||
|
||
function set_name(x::Float64, n::String) | ||
# nop | ||
end | ||
|
||
function _init(model::JuMP.Model, key::Symbol)::OrderedDict | ||
if !(key in keys(object_dictionary(model))) | ||
model[key] = OrderedDict() | ||
end | ||
return model[key] | ||
end | ||
|
||
function _set_names!(model::JuMP.Model) | ||
@info "Setting variable and constraint names..." | ||
time_varnames = @elapsed begin | ||
_set_names!(object_dictionary(model)) | ||
end | ||
@info @sprintf("Set names in %.2f seconds", time_varnames) | ||
end | ||
|
||
function _set_names!(dict::Dict) | ||
for name in keys(dict) | ||
dict[name] isa AbstractDict || continue | ||
for idx in keys(dict[name]) | ||
if dict[name][idx] isa AffExpr | ||
continue | ||
end | ||
idx_str = join(map(string, idx), ",") | ||
set_name(dict[name][idx], "$name[$idx_str]") | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
using RELOG | ||
using Test | ||
using HiGHS | ||
using JuMP | ||
|
||
function model_build_test() | ||
instance = RELOG.parsefile(fixture("simple.json")) | ||
model = RELOG.build_model(instance, optimizer=HiGHS.Optimizer, variable_names=true) | ||
print(model) | ||
end |