mirror of
https://github.com/ANL-CEEESA/MIPLearn.jl.git
synced 2025-12-06 08:28:52 -06:00
gmi: Fix obj_offset; add more profiling
This commit is contained in:
@@ -85,7 +85,7 @@ function collect_gmi(
|
|||||||
# Optimize standard form
|
# Optimize standard form
|
||||||
optimize!(model_s)
|
optimize!(model_s)
|
||||||
stats_time_solve += solve_time(model_s)
|
stats_time_solve += solve_time(model_s)
|
||||||
obj = objective_value(model_s) + data_s.obj_offset
|
obj = objective_value(model_s)
|
||||||
|
|
||||||
if round == 1
|
if round == 1
|
||||||
# Assert standard form problem has same value as original
|
# Assert standard form problem has same value as original
|
||||||
|
|||||||
@@ -87,7 +87,7 @@ function collect_gmi_dual(
|
|||||||
@info "Optimizing standard model..."
|
@info "Optimizing standard model..."
|
||||||
optimize!(model_s)
|
optimize!(model_s)
|
||||||
if round == 1
|
if round == 1
|
||||||
obj = objective_value(model_s) + data_s.obj_offset
|
obj = objective_value(model_s)
|
||||||
push!(stats_obj, obj)
|
push!(stats_obj, obj)
|
||||||
push!(stats_gap, gap(obj))
|
push!(stats_gap, gap(obj))
|
||||||
push!(stats_ncuts, 0)
|
push!(stats_ncuts, 0)
|
||||||
@@ -130,25 +130,31 @@ function collect_gmi_dual(
|
|||||||
end
|
end
|
||||||
|
|
||||||
@timeit "Add GMI cuts to original model" begin
|
@timeit "Add GMI cuts to original model" begin
|
||||||
# Convert cuts
|
@timeit "Convert to original form" begin
|
||||||
cuts = backwards(transforms, cuts_s)
|
cuts = backwards(transforms, cuts_s)
|
||||||
|
|
||||||
# Update data structs
|
|
||||||
bv = repeat([basis], length(selected_rows))
|
|
||||||
if round == 1
|
|
||||||
all_cuts = cuts
|
|
||||||
all_cuts_bases = bv
|
|
||||||
all_cuts_rows = selected_rows
|
|
||||||
else
|
|
||||||
all_cuts.lhs = [all_cuts.lhs; cuts.lhs]
|
|
||||||
all_cuts.lb = [all_cuts.lb; cuts.lb]
|
|
||||||
all_cuts.ub = [all_cuts.ub; cuts.ub]
|
|
||||||
all_cuts_bases = [all_cuts_bases; bv]
|
|
||||||
all_cuts_rows = [all_cuts_rows; selected_rows]
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# Add to model
|
@timeit "Prepare bv" begin
|
||||||
constrs, gmi_exps = add_constraint_set_dual_v2(model, all_cuts)
|
bv = repeat([basis], length(selected_rows))
|
||||||
|
end
|
||||||
|
|
||||||
|
@timeit "Append matrices" begin
|
||||||
|
if round == 1
|
||||||
|
all_cuts = cuts
|
||||||
|
all_cuts_bases = bv
|
||||||
|
all_cuts_rows = selected_rows
|
||||||
|
else
|
||||||
|
all_cuts.lhs = [all_cuts.lhs; cuts.lhs]
|
||||||
|
all_cuts.lb = [all_cuts.lb; cuts.lb]
|
||||||
|
all_cuts.ub = [all_cuts.ub; cuts.ub]
|
||||||
|
all_cuts_bases = [all_cuts_bases; bv]
|
||||||
|
all_cuts_rows = [all_cuts_rows; selected_rows]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
@timeit "Add to model" begin
|
||||||
|
constrs, gmi_exps = add_constraint_set_dual_v2(model, all_cuts)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@timeit "Optimize original model" begin
|
@timeit "Optimize original model" begin
|
||||||
@@ -322,22 +328,28 @@ function add_constraint_set_dual_v2(model::JuMP.Model, cs::ConstraintSet)
|
|||||||
c = nothing
|
c = nothing
|
||||||
gmi_exp = nothing
|
gmi_exp = nothing
|
||||||
gmi_exp2 = nothing
|
gmi_exp2 = nothing
|
||||||
expr = @expression(model, sum(cs.lhs[i, j] * vars[j] for j = 1:ncols))
|
@timeit "Build expr" begin
|
||||||
if isinf(cs.ub[i])
|
expr = @expression(model, sum(cs.lhs[i, j] * vars[j] for j = 1:ncols))
|
||||||
c = @constraint(model, cs.lb[i] <= expr)
|
|
||||||
gmi_exp = cs.lb[i] - expr
|
|
||||||
elseif isinf(cs.lb[i])
|
|
||||||
c = @constraint(model, expr <= cs.ub[i])
|
|
||||||
gmi_exp = expr - cs.ub[i]
|
|
||||||
else
|
|
||||||
c = @constraint(model, cs.lb[i] <= expr <= cs.ub[i])
|
|
||||||
gmi_exp = cs.lb[i] - expr
|
|
||||||
gmi_exp2 = expr - cs.ub[i]
|
|
||||||
end
|
end
|
||||||
push!(constrs, c)
|
@timeit "Add constraints" begin
|
||||||
push!(gmi_exps, gmi_exp)
|
if isinf(cs.ub[i])
|
||||||
if !isnothing(gmi_exp2)
|
c = @constraint(model, cs.lb[i] <= expr)
|
||||||
push!(gmi_exps, gmi_exp2)
|
gmi_exp = cs.lb[i] - expr
|
||||||
|
elseif isinf(cs.lb[i])
|
||||||
|
c = @constraint(model, expr <= cs.ub[i])
|
||||||
|
gmi_exp = expr - cs.ub[i]
|
||||||
|
else
|
||||||
|
c = @constraint(model, cs.lb[i] <= expr <= cs.ub[i])
|
||||||
|
gmi_exp = cs.lb[i] - expr
|
||||||
|
gmi_exp2 = expr - cs.ub[i]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
@timeit "Update structs" begin
|
||||||
|
push!(constrs, c)
|
||||||
|
push!(gmi_exps, gmi_exp)
|
||||||
|
if !isnothing(gmi_exp2)
|
||||||
|
push!(gmi_exps, gmi_exp2)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
return constrs, gmi_exps
|
return constrs, gmi_exps
|
||||||
|
|||||||
@@ -9,6 +9,8 @@ function ProblemData(model::Model)::ProblemData
|
|||||||
|
|
||||||
# Objective function
|
# Objective function
|
||||||
obj = objective_function(model)
|
obj = objective_function(model)
|
||||||
|
obj_offset = obj.constant
|
||||||
|
obj_sense = objective_sense(model)
|
||||||
obj = [v ∈ keys(obj.terms) ? obj.terms[v] : 0.0 for v in vars]
|
obj = [v ∈ keys(obj.terms) ? obj.terms[v] : 0.0 for v in vars]
|
||||||
|
|
||||||
# Variable types, lower bounds and upper bounds
|
# Variable types, lower bounds and upper bounds
|
||||||
@@ -86,8 +88,9 @@ function ProblemData(model::Model)::ProblemData
|
|||||||
@assert length(constr_ub) == m
|
@assert length(constr_ub) == m
|
||||||
|
|
||||||
return ProblemData(
|
return ProblemData(
|
||||||
obj_offset = 0.0;
|
|
||||||
obj,
|
obj,
|
||||||
|
obj_offset,
|
||||||
|
obj_sense,
|
||||||
constr_lb,
|
constr_lb,
|
||||||
constr_ub,
|
constr_ub,
|
||||||
constr_lhs,
|
constr_lhs,
|
||||||
@@ -102,6 +105,7 @@ function to_model(data::ProblemData, tol = 1e-6)::Model
|
|||||||
model = Model()
|
model = Model()
|
||||||
|
|
||||||
# Variables
|
# Variables
|
||||||
|
obj_expr = AffExpr(data.obj_offset)
|
||||||
nvars = length(data.obj)
|
nvars = length(data.obj)
|
||||||
@variable(model, x[1:nvars])
|
@variable(model, x[1:nvars])
|
||||||
for i = 1:nvars
|
for i = 1:nvars
|
||||||
@@ -117,8 +121,9 @@ function to_model(data::ProblemData, tol = 1e-6)::Model
|
|||||||
if isfinite(data.var_ub[i])
|
if isfinite(data.var_ub[i])
|
||||||
set_upper_bound(x[i], data.var_ub[i])
|
set_upper_bound(x[i], data.var_ub[i])
|
||||||
end
|
end
|
||||||
set_objective_coefficient(model, x[i], data.obj[i])
|
add_to_expression!(obj_expr, x[i], data.obj[i])
|
||||||
end
|
end
|
||||||
|
@objective(model, data.obj_sense, obj_expr)
|
||||||
|
|
||||||
# Constraints
|
# Constraints
|
||||||
lhs = data.constr_lhs * x
|
lhs = data.constr_lhs * x
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ using SparseArrays
|
|||||||
Base.@kwdef mutable struct ProblemData
|
Base.@kwdef mutable struct ProblemData
|
||||||
obj::Vector{Float64}
|
obj::Vector{Float64}
|
||||||
obj_offset::Float64
|
obj_offset::Float64
|
||||||
|
obj_sense
|
||||||
constr_lb::Vector{Float64}
|
constr_lb::Vector{Float64}
|
||||||
constr_ub::Vector{Float64}
|
constr_ub::Vector{Float64}
|
||||||
constr_lhs::SparseMatrixCSC
|
constr_lhs::SparseMatrixCSC
|
||||||
|
|||||||
Reference in New Issue
Block a user