|
|
|
@ -36,13 +36,14 @@ function _add_constrs(
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
function _extract_after_load(model::JuMP.Model, h5)
|
|
|
|
|
@info "_extract_after_load"
|
|
|
|
|
if JuMP.objective_sense(model) == MOI.MIN_SENSE
|
|
|
|
|
h5.put_scalar("static_sense", "min")
|
|
|
|
|
else
|
|
|
|
|
h5.put_scalar("static_sense", "max")
|
|
|
|
|
end
|
|
|
|
|
_extract_after_load_vars(model, h5)
|
|
|
|
|
_extract_after_load_constrs(model, h5)
|
|
|
|
|
@time _extract_after_load_vars(model, h5)
|
|
|
|
|
@time _extract_after_load_constrs(model, h5)
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
function _extract_after_load_vars(model::JuMP.Model, h5)
|
|
|
|
@ -117,10 +118,11 @@ function _extract_after_load_constrs(model::JuMP.Model, h5)
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
function _extract_after_lp(model::JuMP.Model, h5)
|
|
|
|
|
@info "_extract_after_lp"
|
|
|
|
|
h5.put_scalar("lp_wallclock_time", solve_time(model))
|
|
|
|
|
h5.put_scalar("lp_obj_value", objective_value(model))
|
|
|
|
|
_extract_after_lp_vars(model, h5)
|
|
|
|
|
_extract_after_lp_constrs(model, h5)
|
|
|
|
|
@time _extract_after_lp_vars(model, h5)
|
|
|
|
|
@time _extract_after_lp_constrs(model, h5)
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
function _extract_after_lp_vars(model::JuMP.Model, h5)
|
|
|
|
@ -146,46 +148,46 @@ function _extract_after_lp_vars(model::JuMP.Model, h5)
|
|
|
|
|
end
|
|
|
|
|
h5.put_array("lp_var_basis_status", to_str_array(basis_status))
|
|
|
|
|
|
|
|
|
|
# Sensitivity analysis
|
|
|
|
|
obj_coeffs = h5.get_array("static_var_obj_coeffs")
|
|
|
|
|
sensitivity_report = lp_sensitivity_report(model)
|
|
|
|
|
sa_obj_down, sa_obj_up = Float64[], Float64[]
|
|
|
|
|
sa_lb_down, sa_lb_up = Float64[], Float64[]
|
|
|
|
|
sa_ub_down, sa_ub_up = Float64[], Float64[]
|
|
|
|
|
for (i, v) in enumerate(vars)
|
|
|
|
|
# Objective function
|
|
|
|
|
(delta_down, delta_up) = sensitivity_report[v]
|
|
|
|
|
push!(sa_obj_down, delta_down + obj_coeffs[i])
|
|
|
|
|
push!(sa_obj_up, delta_up + obj_coeffs[i])
|
|
|
|
|
|
|
|
|
|
# Lower bound
|
|
|
|
|
if has_lower_bound(v)
|
|
|
|
|
constr = LowerBoundRef(v)
|
|
|
|
|
(delta_down, delta_up) = sensitivity_report[constr]
|
|
|
|
|
push!(sa_lb_down, lower_bound(v) + delta_down)
|
|
|
|
|
push!(sa_lb_up, lower_bound(v) + delta_up)
|
|
|
|
|
else
|
|
|
|
|
push!(sa_lb_down, -Inf)
|
|
|
|
|
push!(sa_lb_up, -Inf)
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
# Upper bound
|
|
|
|
|
if has_upper_bound(v)
|
|
|
|
|
constr = JuMP.UpperBoundRef(v)
|
|
|
|
|
(delta_down, delta_up) = sensitivity_report[constr]
|
|
|
|
|
push!(sa_ub_down, upper_bound(v) + delta_down)
|
|
|
|
|
push!(sa_ub_up, upper_bound(v) + delta_up)
|
|
|
|
|
else
|
|
|
|
|
push!(sa_ub_down, Inf)
|
|
|
|
|
push!(sa_ub_up, Inf)
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
h5.put_array("lp_var_sa_obj_up", sa_obj_up)
|
|
|
|
|
h5.put_array("lp_var_sa_obj_down", sa_obj_down)
|
|
|
|
|
h5.put_array("lp_var_sa_ub_up", sa_ub_up)
|
|
|
|
|
h5.put_array("lp_var_sa_ub_down", sa_ub_down)
|
|
|
|
|
h5.put_array("lp_var_sa_lb_up", sa_lb_up)
|
|
|
|
|
h5.put_array("lp_var_sa_lb_down", sa_lb_down)
|
|
|
|
|
# # Sensitivity analysis
|
|
|
|
|
# obj_coeffs = h5.get_array("static_var_obj_coeffs")
|
|
|
|
|
# sensitivity_report = lp_sensitivity_report(model)
|
|
|
|
|
# sa_obj_down, sa_obj_up = Float64[], Float64[]
|
|
|
|
|
# sa_lb_down, sa_lb_up = Float64[], Float64[]
|
|
|
|
|
# sa_ub_down, sa_ub_up = Float64[], Float64[]
|
|
|
|
|
# for (i, v) in enumerate(vars)
|
|
|
|
|
# # Objective function
|
|
|
|
|
# (delta_down, delta_up) = sensitivity_report[v]
|
|
|
|
|
# push!(sa_obj_down, delta_down + obj_coeffs[i])
|
|
|
|
|
# push!(sa_obj_up, delta_up + obj_coeffs[i])
|
|
|
|
|
|
|
|
|
|
# # Lower bound
|
|
|
|
|
# if has_lower_bound(v)
|
|
|
|
|
# constr = LowerBoundRef(v)
|
|
|
|
|
# (delta_down, delta_up) = sensitivity_report[constr]
|
|
|
|
|
# push!(sa_lb_down, lower_bound(v) + delta_down)
|
|
|
|
|
# push!(sa_lb_up, lower_bound(v) + delta_up)
|
|
|
|
|
# else
|
|
|
|
|
# push!(sa_lb_down, -Inf)
|
|
|
|
|
# push!(sa_lb_up, -Inf)
|
|
|
|
|
# end
|
|
|
|
|
|
|
|
|
|
# # Upper bound
|
|
|
|
|
# if has_upper_bound(v)
|
|
|
|
|
# constr = JuMP.UpperBoundRef(v)
|
|
|
|
|
# (delta_down, delta_up) = sensitivity_report[constr]
|
|
|
|
|
# push!(sa_ub_down, upper_bound(v) + delta_down)
|
|
|
|
|
# push!(sa_ub_up, upper_bound(v) + delta_up)
|
|
|
|
|
# else
|
|
|
|
|
# push!(sa_ub_down, Inf)
|
|
|
|
|
# push!(sa_ub_up, Inf)
|
|
|
|
|
# end
|
|
|
|
|
# end
|
|
|
|
|
# h5.put_array("lp_var_sa_obj_up", sa_obj_up)
|
|
|
|
|
# h5.put_array("lp_var_sa_obj_down", sa_obj_down)
|
|
|
|
|
# h5.put_array("lp_var_sa_ub_up", sa_ub_up)
|
|
|
|
|
# h5.put_array("lp_var_sa_ub_down", sa_ub_down)
|
|
|
|
|
# h5.put_array("lp_var_sa_lb_up", sa_lb_up)
|
|
|
|
|
# h5.put_array("lp_var_sa_lb_down", sa_lb_down)
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -201,7 +203,7 @@ function _extract_after_lp_constrs(model::JuMP.Model, h5)
|
|
|
|
|
duals = Float64[]
|
|
|
|
|
basis_status = []
|
|
|
|
|
constr_idx = 1
|
|
|
|
|
sensitivity_report = lp_sensitivity_report(model)
|
|
|
|
|
# sensitivity_report = lp_sensitivity_report(model)
|
|
|
|
|
for (ftype, stype) in JuMP.list_of_constraint_types(model)
|
|
|
|
|
for constr in JuMP.all_constraints(model, ftype, stype)
|
|
|
|
|
length(JuMP.name(constr)) > 0 || continue
|
|
|
|
@ -219,21 +221,22 @@ function _extract_after_lp_constrs(model::JuMP.Model, h5)
|
|
|
|
|
error("Unknown basis status: $b")
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
# Sensitivity analysis
|
|
|
|
|
(delta_down, delta_up) = sensitivity_report[constr]
|
|
|
|
|
push!(sa_rhs_down, rhs[constr_idx] + delta_down)
|
|
|
|
|
push!(sa_rhs_up, rhs[constr_idx] + delta_up)
|
|
|
|
|
# # Sensitivity analysis
|
|
|
|
|
# (delta_down, delta_up) = sensitivity_report[constr]
|
|
|
|
|
# push!(sa_rhs_down, rhs[constr_idx] + delta_down)
|
|
|
|
|
# push!(sa_rhs_up, rhs[constr_idx] + delta_up)
|
|
|
|
|
|
|
|
|
|
constr_idx += 1
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
h5.put_array("lp_constr_dual_values", duals)
|
|
|
|
|
h5.put_array("lp_constr_basis_status", to_str_array(basis_status))
|
|
|
|
|
h5.put_array("lp_constr_sa_rhs_up", sa_rhs_up)
|
|
|
|
|
h5.put_array("lp_constr_sa_rhs_down", sa_rhs_down)
|
|
|
|
|
# h5.put_array("lp_constr_sa_rhs_up", sa_rhs_up)
|
|
|
|
|
# h5.put_array("lp_constr_sa_rhs_down", sa_rhs_down)
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
function _extract_after_mip(model::JuMP.Model, h5)
|
|
|
|
|
@info "_extract_after_mip"
|
|
|
|
|
h5.put_scalar("mip_obj_value", objective_value(model))
|
|
|
|
|
h5.put_scalar("mip_obj_bound", objective_bound(model))
|
|
|
|
|
h5.put_scalar("mip_wallclock_time", solve_time(model))
|
|
|
|
@ -254,11 +257,14 @@ end
|
|
|
|
|
function _fix_variables(model::JuMP.Model, var_names, var_values, stats)
|
|
|
|
|
vars = [variable_by_name(model, v) for v in var_names]
|
|
|
|
|
for (i, var) in enumerate(vars)
|
|
|
|
|
fix(var, var_values[i], force = true)
|
|
|
|
|
if isfinite(var_values[i])
|
|
|
|
|
fix(var, var_values[i], force=true)
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
function _optimize(model::JuMP.Model)
|
|
|
|
|
@info "_optimize"
|
|
|
|
|
optimize!(model)
|
|
|
|
|
flush(stdout)
|
|
|
|
|
Libc.flush_cstdio()
|
|
|
|
@ -269,7 +275,7 @@ function _relax(model::JuMP.Model)
|
|
|
|
|
relax_integrality(relaxed)
|
|
|
|
|
# FIXME: Remove hardcoded optimizer
|
|
|
|
|
set_optimizer(relaxed, HiGHS.Optimizer)
|
|
|
|
|
set_silent(relaxed)
|
|
|
|
|
# set_silent(relaxed)
|
|
|
|
|
return relaxed
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
@ -303,7 +309,7 @@ function __init_solvers_jump__()
|
|
|
|
|
constrs_lhs,
|
|
|
|
|
constrs_sense,
|
|
|
|
|
constrs_rhs,
|
|
|
|
|
stats = nothing,
|
|
|
|
|
stats=nothing,
|
|
|
|
|
) = _add_constrs(
|
|
|
|
|
self.inner,
|
|
|
|
|
from_str_array(var_names),
|
|
|
|
@ -319,14 +325,14 @@ function __init_solvers_jump__()
|
|
|
|
|
|
|
|
|
|
extract_after_mip(self, h5) = _extract_after_mip(self.inner, h5)
|
|
|
|
|
|
|
|
|
|
fix_variables(self, var_names, var_values, stats = nothing) =
|
|
|
|
|
fix_variables(self, var_names, var_values, stats=nothing) =
|
|
|
|
|
_fix_variables(self.inner, from_str_array(var_names), var_values, stats)
|
|
|
|
|
|
|
|
|
|
optimize(self) = _optimize(self.inner)
|
|
|
|
|
|
|
|
|
|
relax(self) = Class(_relax(self.inner))
|
|
|
|
|
|
|
|
|
|
set_warm_starts(self, var_names, var_values, stats = nothing) =
|
|
|
|
|
set_warm_starts(self, var_names, var_values, stats=nothing) =
|
|
|
|
|
_set_warm_starts(self.inner, from_str_array(var_names), var_values, stats)
|
|
|
|
|
|
|
|
|
|
write(self, filename) = _write(self.inner, filename)
|
|
|
|
|