mirror of
https://github.com/ANL-CEEESA/RELOG.git
synced 2025-12-05 23:38:52 -06:00
Implement full recourse; remove feasibility cuts
This commit is contained in:
@@ -24,6 +24,7 @@ function build_model(
|
|||||||
probs::Vector{Float64};
|
probs::Vector{Float64};
|
||||||
optimizer,
|
optimizer,
|
||||||
method=:ef,
|
method=:ef,
|
||||||
|
tol=0.1,
|
||||||
)
|
)
|
||||||
T = instance.time
|
T = instance.time
|
||||||
|
|
||||||
@@ -118,6 +119,13 @@ function build_model(
|
|||||||
upper_bound = graph.collection_shipping_nodes[n].location.amount[t],
|
upper_bound = graph.collection_shipping_nodes[n].location.amount[t],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Var: collection_shortfall
|
||||||
|
@recourse(
|
||||||
|
model,
|
||||||
|
collection_shortfall[n in 1:CSN, t in 1:T],
|
||||||
|
lower_bound = 0,
|
||||||
|
)
|
||||||
|
|
||||||
# Var: store
|
# Var: store
|
||||||
@recourse(
|
@recourse(
|
||||||
model,
|
model,
|
||||||
@@ -209,6 +217,11 @@ function build_model(
|
|||||||
csn[n].location.product.disposal_cost[t] * collection_dispose[n, t]
|
csn[n].location.product.disposal_cost[t] * collection_dispose[n, t]
|
||||||
for n in 1:CSN
|
for n in 1:CSN
|
||||||
for t in 1:T
|
for t in 1:T
|
||||||
|
) + sum(
|
||||||
|
# Collection shortfall
|
||||||
|
1e4 * collection_shortfall[n, t]
|
||||||
|
for n in 1:CSN
|
||||||
|
for t in 1:T
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -280,7 +293,7 @@ function build_model(
|
|||||||
sum(
|
sum(
|
||||||
flow[arc.index, t]
|
flow[arc.index, t]
|
||||||
for arc in csn[n].outgoing_arcs
|
for arc in csn[n].outgoing_arcs
|
||||||
) == csn[n].location.amount[t] - collection_dispose[n, t]
|
) == csn[n].location.amount[t] - collection_dispose[n, t] - collection_shortfall[n, t]
|
||||||
)
|
)
|
||||||
|
|
||||||
# Material flow at plant shipping nodes
|
# Material flow at plant shipping nodes
|
||||||
@@ -323,7 +336,7 @@ function build_model(
|
|||||||
sp = instantiate(model, ξ; optimizer=LShaped.Optimizer)
|
sp = instantiate(model, ξ; optimizer=LShaped.Optimizer)
|
||||||
set_optimizer_attribute(sp, MasterOptimizer(), optimizer)
|
set_optimizer_attribute(sp, MasterOptimizer(), optimizer)
|
||||||
set_optimizer_attribute(sp, SubProblemOptimizer(), optimizer)
|
set_optimizer_attribute(sp, SubProblemOptimizer(), optimizer)
|
||||||
set_optimizer_attribute(sp, FeasibilityStrategy(), FeasibilityCuts())
|
set_optimizer_attribute(sp, RelativeTolerance(), tol)
|
||||||
else
|
else
|
||||||
error("unknown method: $method")
|
error("unknown method: $method")
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -29,6 +29,8 @@ function solve_stochastic(;
|
|||||||
scenarios::Vector{String},
|
scenarios::Vector{String},
|
||||||
probs::Vector{Float64},
|
probs::Vector{Float64},
|
||||||
optimizer,
|
optimizer,
|
||||||
|
method=:ef,
|
||||||
|
tol=0.1,
|
||||||
)
|
)
|
||||||
@info "Reading instance files..."
|
@info "Reading instance files..."
|
||||||
instances = [parsefile(sc) for sc in scenarios]
|
instances = [parsefile(sc) for sc in scenarios]
|
||||||
@@ -37,7 +39,7 @@ function solve_stochastic(;
|
|||||||
graphs = [build_graph(inst) for inst in instances]
|
graphs = [build_graph(inst) for inst in instances]
|
||||||
|
|
||||||
@info "Building stochastic model..."
|
@info "Building stochastic model..."
|
||||||
sp = RELOG.build_model(instances[1], graphs, probs; optimizer)
|
sp = RELOG.build_model(instances[1], graphs, probs; optimizer, method, tol)
|
||||||
|
|
||||||
@info "Optimizing stochastic model..."
|
@info "Optimizing stochastic model..."
|
||||||
optimize!(sp)
|
optimize!(sp)
|
||||||
|
|||||||
@@ -40,13 +40,13 @@ function model_solve_test()
|
|||||||
solution = RELOG.solve(fixture("instances/s1.json"), heuristic = true)
|
solution = RELOG.solve(fixture("instances/s1.json"), heuristic = true)
|
||||||
end
|
end
|
||||||
|
|
||||||
@testset "solve (infeasible)" begin
|
# @testset "solve (infeasible)" begin
|
||||||
json = JSON.parsefile(fixture("instances/s1.json"))
|
# json = JSON.parsefile(fixture("instances/s1.json"))
|
||||||
for (location_name, location_dict) in json["products"]["P1"]["initial amounts"]
|
# for (location_name, location_dict) in json["products"]["P1"]["initial amounts"]
|
||||||
location_dict["amount (tonne)"] *= 1000
|
# location_dict["amount (tonne)"] *= 1000
|
||||||
end
|
# end
|
||||||
@test_throws ErrorException("No solution available") RELOG.solve(RELOG.parse(json))
|
# @test_throws ErrorException("No solution available") RELOG.solve(RELOG.parse(json))
|
||||||
end
|
# end
|
||||||
|
|
||||||
@testset "solve (with storage)" begin
|
@testset "solve (with storage)" begin
|
||||||
basedir = dirname(@__FILE__)
|
basedir = dirname(@__FILE__)
|
||||||
@@ -75,7 +75,11 @@ function model_solve_test()
|
|||||||
fixture("instances/case3_p010_s1.25.json"),
|
fixture("instances/case3_p010_s1.25.json"),
|
||||||
],
|
],
|
||||||
probs=[0.5, 0.5],
|
probs=[0.5, 0.5],
|
||||||
optimizer=HiGHS.Optimizer,
|
optimizer=optimizer_with_attributes(
|
||||||
|
HiGHS.Optimizer,
|
||||||
|
"log_to_console" => false,
|
||||||
|
),
|
||||||
|
method=:lshaped,
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
Reference in New Issue
Block a user