|
function _optimize_in_backward_pass(optimizer, i) |
|
object = optimizer.solve_order[i] |
|
|
|
### Unset binary/integer variables |
|
bin_vars_dict = optimizer.binary_map[object] |
|
int_vars_dict = optimizer.integer_map[object] |
|
|
|
bin_vars = collect(keys(bin_vars_dict)) |
|
int_vars = collect(keys(int_vars_dict)) |
|
|
|
# Unset binary/integer variables and set bounds |
|
JuMP.unset_binary.(bin_vars) |
|
bin_vars_not_fixed = (!).(JuMP.is_fixed.(bin_vars)) |
|
JuMP.set_upper_bound.(bin_vars[bin_vars_not_fixed], 1) |
|
JuMP.set_lower_bound.(bin_vars[bin_vars_not_fixed], 0) |
|
JuMP.unset_integer.(int_vars) |
|
|
|
if i != 1 |
|
comp_vars = optimizer.comp_vars[object] |
|
var_copy_map = optimizer.var_copy_map[object] |
|
primal_iters = optimizer.primal_iters[object] |
|
last_primals = primal_iters[:, size(primal_iters, 2)] |
|
|
|
# Fix primal solutions |
|
for (j, var) in enumerate(comp_vars) |
|
JuMP.fix(var_copy_map[var], last_primals[j], force = true) |
|
end |
|
end |
|
|
|
# Optimize the next node |
|
optimize!(object) |
|
|
|
# Check termination status |
|
_check_termination_status(optimizer, object, i) |
|
|
|
# If it's not the first node, save the dual and phi values |
|
if i != 1 |
|
dual_iters = optimizer.dual_iters[object] |
|
next_duals = _get_next_duals(optimizer, object) |
|
|
|
next_phi = JuMP.value(object, JuMP.objective_function(object)) |
|
|
|
optimizer.dual_iters[object] = hcat(dual_iters, next_duals) |
|
push!(optimizer.phis[object], next_phi) |
|
|
|
comp_vars = optimizer.comp_vars[object] |
|
var_copy_map = optimizer.var_copy_map[object] |
|
|
|
# Fix primal solutions |
|
for (j, var) in enumerate(comp_vars) |
|
JuMP.unfix(var_copy_map[var]) |
|
end |
|
end |
|
|
|
_check_fixed_slacks!(optimizer, object) |
|
|
|
# Reset binary/integer variables |
|
bin_vars_with_lower_bound = JuMP.has_lower_bound.(bin_vars) |
|
bin_vars_with_upper_bound = JuMP.has_upper_bound.(bin_vars) |
|
JuMP.delete_lower_bound.(bin_vars[bin_vars_with_lower_bound]) |
|
JuMP.delete_upper_bound.(bin_vars[bin_vars_with_upper_bound]) |
|
JuMP.set_binary.(bin_vars) |
|
JuMP.set_integer.(int_vars) #TODO: fix bounds on integer vars? |
|
end |
Instead of:
PlasmoAlgorithms.jl/lib/PlasmoBenders/src/solution.jl
Lines 230 to 293 in 6c9e489
JuMP has
relax_integrality: https://jump.dev/JuMP.jl/stable/api/JuMP/#relax_integralityHere's SDDP's code for the continuous dual:
https://github.com/odow/SDDP.jl/blob/aec55e2279c4abbd2a15ab1a430f6bb5a526976e/src/plugins/duality_handlers.jl#L92-L118