Skip to content

Commit

Permalink
Create local artifical variables in setconstr! (#336)
Browse files Browse the repository at this point in the history
* loc_art_var option in setconstr

* store ids of local art var in constraint

* store art var in constraint

* bug in activate / deactivate

* (de)activate local art vars with constraint
  • Loading branch information
guimarqu authored May 12, 2020
1 parent 680d441 commit 473fc42
Show file tree
Hide file tree
Showing 5 changed files with 139 additions and 106 deletions.
65 changes: 35 additions & 30 deletions src/MathProg/clone.jl
Original file line number Diff line number Diff line change
@@ -1,18 +1,20 @@
function clonevar!(originform::Formulation,
destform::Formulation,
assignedform::Formulation,
var::Variable,
duty::Duty{Variable};
name::String = getname(originform, var),
cost::Float64 = getperenecost(originform, var),
lb::Float64 = getperenelb(originform, var),
ub::Float64 = getpereneub(originform, var),
kind::VarKind = getperenekind(originform, var),
sense::VarSense = getperenesense(originform, var),
inc_val::Float64 = getpereneincval(originform, var),
is_active::Bool = ispereneactive(originform, var),
is_explicit::Bool = ispereneexplicit(originform, var),
members::Union{ConstrMembership,Nothing} = nothing)
function clonevar!(
originform::Formulation,
destform::Formulation,
assignedform::Formulation,
var::Variable,
duty::Duty{Variable};
name::String = getname(originform, var),
cost::Float64 = getperenecost(originform, var),
lb::Float64 = getperenelb(originform, var),
ub::Float64 = getpereneub(originform, var),
kind::VarKind = getperenekind(originform, var),
sense::VarSense = getperenesense(originform, var),
inc_val::Float64 = getpereneincval(originform, var),
is_active::Bool = ispereneactive(originform, var),
is_explicit::Bool = ispereneexplicit(originform, var),
members::Union{ConstrMembership,Nothing} = nothing
)
return setvar!(
destform, name, duty;
cost = cost, lb = lb, ub = ub, kind = kind, sense = sense,
Expand All @@ -22,24 +24,27 @@ function clonevar!(originform::Formulation,
)
end

function cloneconstr!(originform::Formulation,
destform::Formulation,
assignedform::Formulation,
constr::Constraint,
duty::Duty{Constraint};
name::String = getname(originform, constr),
rhs::Float64 = getperenerhs(originform, constr),
kind::ConstrKind = getperenekind(originform, constr),
sense::ConstrSense = getperenesense(originform, constr),
inc_val::Float64 = getpereneincval(originform, constr),
is_active::Bool = ispereneactive(originform, constr),
is_explicit::Bool = ispereneexplicit(originform, constr),
members::Union{VarMembership,Nothing} = nothing)
function cloneconstr!(
originform::Formulation,
destform::Formulation,
assignedform::Formulation,
constr::Constraint,
duty::Duty{Constraint};
name::String = getname(originform, constr),
rhs::Float64 = getperenerhs(originform, constr),
kind::ConstrKind = getperenekind(originform, constr),
sense::ConstrSense = getperenesense(originform, constr),
inc_val::Float64 = getpereneincval(originform, constr),
is_active::Bool = ispereneactive(originform, constr),
is_explicit::Bool = ispereneexplicit(originform, constr),
members::Union{VarMembership,Nothing} = nothing,
loc_art_var = false
)
return setconstr!(
destform, name, duty;
destform, name, duty;
rhs = rhs, kind = kind, sense = sense, inc_val = inc_val,
is_active = is_active, is_explicit = is_explicit, members = members,
id = Id{Constraint}(duty, getid(constr), getuid(assignedform))
loc_art_var = loc_art_var, id = Id{Constraint}(duty, getid(constr), getuid(assignedform))
)
end

Expand Down
16 changes: 7 additions & 9 deletions src/MathProg/constraint.jl
Original file line number Diff line number Diff line change
Expand Up @@ -49,22 +49,20 @@ setindex!(record::MoiConstrRecord, index::MoiConstrIndex) = record.index = index
Representation of a constraint in Coluna.
"""

struct Constraint <: AbstractVarConstr
id::Id{Constraint}
name::String
perene_data::ConstrData
moirecord::MoiConstrRecord
art_var_ids::Vector{VarId}
end

const ConstrId = Id{Constraint}

function Constraint(id::ConstrId,
name::String;
constr_data = ConstrData(),
moi_index::MoiConstrIndex = MoiConstrIndex())
return Constraint(
id, name, constr_data,
MoiConstrRecord(index = moi_index)
)
function Constraint(
id::ConstrId, name::String;
constr_data = ConstrData(), moi_index::MoiConstrIndex = MoiConstrIndex()
)
return Constraint(id, name, constr_data, MoiConstrRecord(index = moi_index), VarId[])
end

44 changes: 5 additions & 39 deletions src/MathProg/decomposition.jl
Original file line number Diff line number Diff line change
Expand Up @@ -8,41 +8,6 @@ function set_glob_art_var(form::Formulation, is_pos::Bool)
)
end

function create_local_art_vars!(masterform::Formulation)
matrix = getcoefmatrix(masterform)
cost = Cl._params_.local_art_var_cost
cost *= getobjsense(masterform) == MinSense ? 1.0 : -1.0
for (constrid, constr) in getconstrs(masterform)
constrname = getname(masterform, constr)
if getcursense(masterform, constr) == Equal
name1 = string("local_art_of_", constrname, "1")
name2 = string("local_art_of_", constrname, "2")
var1 = setvar!(
masterform, name1, MasterArtVar;
cost = cost, lb = 0.0, ub = Inf, kind = Continuous, sense = Positive
)
var2 = setvar!(
masterform, name1, MasterArtVar;
cost = cost, lb = 0.0, ub = Inf, kind = Continuous, sense = Positive
)
matrix[constrid, getid(var1)] = 1.0
matrix[constrid, getid(var2)] = -1.0
else
name = string("local_art_of_", constrname)
var = setvar!(
masterform, name, MasterArtVar;
cost = cost, lb = 0.0, ub = Inf, kind = Continuous, sense = Positive
)
if getcursense(masterform, constr) == Greater
matrix[constrid, getid(var)] = 1.0
elseif getcursense(masterform, constr) == Less
matrix[constrid, getid(var)] = -1.0
end
end
end
return
end

function create_global_art_vars!(masterform::Formulation)
global_pos = set_glob_art_var(masterform, true)
global_neg = set_glob_art_var(masterform, false)
Expand Down Expand Up @@ -144,7 +109,9 @@ function instantiate_orig_constrs!(
!haskey(annotations.constrs_per_ann, mast_ann) && return
constrs = annotations.constrs_per_ann[mast_ann]
for (id, constr) in constrs
cloneconstr!(origform, masterform, masterform, constr, MasterMixedConstr) # TODO distinguish Pure versus Mixed
cloneconstr!(
origform, masterform, masterform, constr, MasterMixedConstr, loc_art_var = true
) # TODO distinguish Pure versus Mixed
end
return
end
Expand All @@ -166,7 +133,7 @@ function create_side_vars_constrs!(
name = string("sp_lb_", spuid)
lb_conv_constr = setconstr!(
masterform, name, MasterConvexityConstr;
rhs = lb_mult, kind = Core, sense = Greater, inc_val = 100.0
rhs = lb_mult, kind = Core, sense = Greater, inc_val = 100.0, loc_art_var = true
)
masterform.parent_formulation.dw_pricing_sp_lb[spuid] = getid(lb_conv_constr)
coefmatrix[getid(lb_conv_constr), getid(setuprepvar)] = 1.0
Expand All @@ -175,7 +142,7 @@ function create_side_vars_constrs!(
name = string("sp_ub_", spuid)
ub_conv_constr = setconstr!(
masterform, name, MasterConvexityConstr; rhs = ub_mult,
kind = Core, sense = Less, inc_val = 100.0
kind = Core, sense = Less, inc_val = 100.0, loc_art_var = true
)
masterform.parent_formulation.dw_pricing_sp_ub[spuid] = getid(ub_conv_constr)
coefmatrix[getid(ub_conv_constr), getid(setuprepvar)] = 1.0
Expand All @@ -185,7 +152,6 @@ end

function create_artificial_vars!(masterform::Formulation{DwMaster})
create_global_art_vars!(masterform)
create_local_art_vars!(masterform)
return
end

Expand Down
81 changes: 61 additions & 20 deletions src/MathProg/formulation.jl
Original file line number Diff line number Diff line change
Expand Up @@ -291,40 +291,81 @@ function setcut_from_sp_dualsol!(
end
end
end
_addconstr!(masterform, benders_cut)
_addconstr!(masterform.manager, benders_cut)
if iscurexplicit(masterform, benders_cut)
add!(masterform.buffer, getid(benders_cut))
end
return benders_cut
end

"Creates a `Constraint` according to the parameters passed and adds it to `Formulation` `form`."
function setconstr!(form::Formulation,
name::String,
duty::Duty{Constraint};
rhs::Float64 = 0.0,
kind::ConstrKind = Core,
sense::ConstrSense = Greater,
inc_val::Float64 = 0.0,
is_active::Bool = true,
is_explicit::Bool = true,
moi_index::MoiConstrIndex = MoiConstrIndex(),
members = nothing, # todo Union{AbstractDict{VarId,Float64},Nothing}
id = generateconstrid(duty, form))
function setconstr!(
form::Formulation,
name::String,
duty::Duty{Constraint};
rhs::Float64 = 0.0,
kind::ConstrKind = Core,
sense::ConstrSense = Greater,
inc_val::Float64 = 0.0,
is_active::Bool = true,
is_explicit::Bool = true,
moi_index::MoiConstrIndex = MoiConstrIndex(),
members = nothing, # todo Union{AbstractDict{VarId,Float64},Nothing}
loc_art_var = false,
id = generateconstrid(duty, form)
)
if getduty(id) != duty
id = ConstrId(duty, id)
end
c_data = ConstrData(rhs, kind, sense, inc_val, is_active, is_explicit)
constr = Constraint(id, name; constr_data = c_data, moi_index = moi_index)
members !== nothing && _setmembers!(form, constr, members)
_addconstr!(form, constr)
return constr
end

"Adds `Constraint` `constr` to `Formulation` `form`."
function _addconstr!(form::Formulation, constr::Constraint)
_addconstr!(form.manager, constr)
if loc_art_var
_addlocalartvar!(form, constr)
end
if iscurexplicit(form, constr)
add!(form.buffer, getid(constr))
end
return
return constr
end

function _addlocalartvar!(form::Formulation, constr::Constraint)
matrix = getcoefmatrix(form)
cost = Cl._params_.local_art_var_cost
cost *= getobjsense(form) == MinSense ? 1.0 : -1.0
constrid = getid(constr)
constrname = getname(form, constr)
constrsense = getperenesense(form, constr)
if constrsense == Equal
name1 = string("local_art_of_", constrname, "1")
name2 = string("local_art_of_", constrname, "2")
var1 = setvar!(
form, name1, MasterArtVar;
cost = cost, lb = 0.0, ub = Inf, kind = Continuous, sense = Positive
)
var2 = setvar!(
form, name1, MasterArtVar;
cost = cost, lb = 0.0, ub = Inf, kind = Continuous, sense = Positive
)
push!(constr.art_var_ids, getid(var1))
push!(constr.art_var_ids, getid(var2))
matrix[constrid, getid(var1)] = 1.0
matrix[constrid, getid(var2)] = -1.0
else
name = string("local_art_of_", constrname)
var = setvar!(
form, name, MasterArtVar;
cost = cost, lb = 0.0, ub = Inf, kind = Continuous, sense = Positive
)
push!(constr.art_var_ids, getid(var))
if constrsense == Greater
matrix[constrid, getid(var)] = 1.0
elseif constrsense == Less
matrix[constrid, getid(var)] = -1.0
end
end
return
end

function enforce_integrality!(form::Formulation)
Expand Down
39 changes: 31 additions & 8 deletions src/MathProg/new_varconstr.jl
Original file line number Diff line number Diff line change
Expand Up @@ -257,40 +257,63 @@ function _setiscuractive!(form::Formulation, constrid::ConstrId, is_active::Bool
return
end

"Activate a variable in the formulation"
function activate!(form::Formulation, varconstrid::Id{VC}) where {VC<:AbstractVarConstr}

function _activate!(form::Formulation, varconstrid::Id{VC}) where {VC<:AbstractVarConstr}
if iscurexplicit(form, varconstrid) && !iscuractive(form, varconstrid)
add!(form.buffer, varconstrid)
end
_setiscuractive!(form, varconstrid, true)
return
end

"Activate a variable or a constraint in the formulation"
function activate!(form::Formulation, constrid::ConstrId)
_activate!(form::Formulation, constrid)
constr = getconstr(form, constrid)
for varid in constr.art_var_ids
_activate!(form, varid)
end
return
end

activate!(form::Formulation, varid::VarId) = _activate!(form, varid)
activate!(form::Formulation, varconstr::AbstractVarConstr) = activate!(form, getid(varconstr))

function activate!(form::Formulation, f::Function)
for (varid, _) in getvars(form)
if iscuractive(form, varid) && f(varid)
if !iscuractive(form, varid) && f(varid)
activate!(form, varid)
end
end
for (constrid, _) in getconstrs(form)
if iscuractive(form, constrid) && f(constrid)
if !iscuractive(form, constrid) && f(constrid)
activate!(form, constrid)
end
end
return
end

"""
Deactivate a variable or a constraint in the formulation
"""
function deactivate!(form::Formulation, varconstrid::Id{VC}) where {VC<:AbstractVarConstr}
function _deactivate!(form::Formulation, varconstrid::Id{VC}) where {VC<:AbstractVarConstr}
if iscurexplicit(form, varconstrid) && iscuractive(form, varconstrid)
remove!(form.buffer, varconstrid)
end
_setiscuractive!(form, varconstrid, false)
return
end

"""
Deactivate a variable or a constraint in the formulation
"""
function deactivate!(form::Formulation, constrid::ConstrId)
_deactivate!(form, constrid)
constr = getconstr(form, constrid)
for varid in constr.art_var_ids
_deactivate!(form, varid)
end
return
end

deactivate!(form::Formulation, varid::VarId) = _deactivate!(form, varid)
deactivate!(form::Formulation, varconstr::AbstractVarConstr) = deactivate!(form, getid(varconstr))

function deactivate!(form::Formulation, f::Function)
Expand Down

0 comments on commit 473fc42

Please sign in to comment.