Skip to content

Commit

Permalink
remove JuMP prefix
Browse files Browse the repository at this point in the history
  • Loading branch information
hdavid16 committed Oct 16, 2023
1 parent 469c1f7 commit 590fd8b
Show file tree
Hide file tree
Showing 12 changed files with 369 additions and 369 deletions.
2 changes: 1 addition & 1 deletion examples/ex5.jl
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# https://arxiv.org/pdf/2303.04375.pdf
# Nested GDP: https://arxiv.org/pdf/2303.04375.pdf
using DisjunctiveProgramming

##
Expand Down
2 changes: 1 addition & 1 deletion examples/ex6.jl
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
using DisjunctiveProgramming

##
## Multi-level Nested GDP
m = GDPModel()
@variable(m, -5 <= x[1:3] <= 5)

Expand Down
116 changes: 58 additions & 58 deletions src/bigm.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# BIG-M VALUE
################################################################################
# Get Big-M value for a particular constraint
function _get_M_value(func::JuMP.AbstractJuMPScalar, set::_MOI.AbstractSet, method::BigM)
function _get_M_value(func::AbstractJuMPScalar, set::_MOI.AbstractSet, method::BigM)
if method.tighten
M = _get_tight_M(func, set, method)
else
Expand All @@ -12,7 +12,7 @@ function _get_M_value(func::JuMP.AbstractJuMPScalar, set::_MOI.AbstractSet, meth
end

# Get the tightest Big-M value for a particular constraint
function _get_tight_M(func::JuMP.AbstractJuMPScalar, set::_MOI.AbstractSet, method::BigM)
function _get_tight_M(func::AbstractJuMPScalar, set::_MOI.AbstractSet, method::BigM)
M = min.(method.value, _calculate_tight_M(func, set, method)) #broadcast for when S <: MOI.Interval or MOI.EqualTo or MOI.Zeros
if any(isinf.(M))
error("A finite Big-M value must be used. The value obtained was $M.")
Expand All @@ -21,14 +21,14 @@ function _get_tight_M(func::JuMP.AbstractJuMPScalar, set::_MOI.AbstractSet, meth
end

# Get user-specified Big-M value
function _get_M(::JuMP.AbstractJuMPScalar, ::Union{_MOI.LessThan, _MOI.GreaterThan, _MOI.Nonnegatives, _MOI.Nonpositives}, method::BigM)
function _get_M(::AbstractJuMPScalar, ::Union{_MOI.LessThan, _MOI.GreaterThan, _MOI.Nonnegatives, _MOI.Nonpositives}, method::BigM)
M = method.value
if isinf(M)
error("A finite Big-M value must be used. The value given was $M.")
end
return M
end
function _get_M(::JuMP.AbstractJuMPScalar, ::Union{_MOI.Interval, _MOI.EqualTo, _MOI.Zeros}, method::BigM)
function _get_M(::AbstractJuMPScalar, ::Union{_MOI.Interval, _MOI.EqualTo, _MOI.Zeros}, method::BigM)
M = method.value
if isinf(M)
error("A finite Big-M value must be used. The value given was $M.")
Expand All @@ -37,64 +37,64 @@ function _get_M(::JuMP.AbstractJuMPScalar, ::Union{_MOI.Interval, _MOI.EqualTo,
end

# Apply interval arithmetic on a linear constraint to infer the tightest Big-M value from the bounds on the constraint.
function _calculate_tight_M(func::JuMP.AffExpr, set::_MOI.LessThan, method::BigM)
function _calculate_tight_M(func::AffExpr, set::_MOI.LessThan, method::BigM)
return _interval_arithmetic_LessThan(func, -set.upper, method)
end
function _calculate_tight_M(func::JuMP.AffExpr, set::_MOI.GreaterThan, method::BigM)
function _calculate_tight_M(func::AffExpr, set::_MOI.GreaterThan, method::BigM)
return _interval_arithmetic_GreaterThan(func, -set.lower, method)
end
function _calculate_tight_M(func::JuMP.AffExpr, ::_MOI.Nonpositives, method::BigM)
function _calculate_tight_M(func::AffExpr, ::_MOI.Nonpositives, method::BigM)
return _interval_arithmetic_LessThan(func, 0.0, method)
end
function _calculate_tight_M(func::JuMP.AffExpr, ::_MOI.Nonnegatives, method::BigM)
function _calculate_tight_M(func::AffExpr, ::_MOI.Nonnegatives, method::BigM)
return _interval_arithmetic_GreaterThan(func, 0.0, method)
end
function _calculate_tight_M(func::JuMP.AffExpr, set::_MOI.Interval, method::BigM)
function _calculate_tight_M(func::AffExpr, set::_MOI.Interval, method::BigM)
return (
_interval_arithmetic_GreaterThan(func, -set.lower, method),
_interval_arithmetic_LessThan(func, -set.upper, method)
)
end
function _calculate_tight_M(func::JuMP.AffExpr, set::_MOI.EqualTo, method::BigM)
function _calculate_tight_M(func::AffExpr, set::_MOI.EqualTo, method::BigM)
return (
_interval_arithmetic_GreaterThan(func, -set.value, method),
_interval_arithmetic_LessThan(func, -set.value, method)
)
end
function _calculate_tight_M(func::JuMP.AffExpr, ::_MOI.Zeros, method::BigM)
function _calculate_tight_M(func::AffExpr, ::_MOI.Zeros, method::BigM)
return (
_interval_arithmetic_GreaterThan(func, 0.0, method),
_interval_arithmetic_LessThan(func, 0.0, method)
)
end
# fallbacks for other scalar constraints
_calculate_tight_M(func::Union{JuMP.QuadExpr, JuMP.NonlinearExpr}, set::Union{_MOI.Interval, _MOI.EqualTo, _MOI.Zeros}, method::BigM) = (Inf, Inf)
_calculate_tight_M(func::Union{JuMP.QuadExpr, JuMP.NonlinearExpr}, set::Union{_MOI.LessThan, _MOI.GreaterThan, _MOI.Nonnegatives, _MOI.Nonpositives}, method::BigM) = Inf
_calculate_tight_M(func::Union{QuadExpr, NonlinearExpr}, set::Union{_MOI.Interval, _MOI.EqualTo, _MOI.Zeros}, method::BigM) = (Inf, Inf)
_calculate_tight_M(func::Union{QuadExpr, NonlinearExpr}, set::Union{_MOI.LessThan, _MOI.GreaterThan, _MOI.Nonnegatives, _MOI.Nonpositives}, method::BigM) = Inf
_calculate_tight_M(func, set, method::BigM) = error("BigM method not implemented for constraint type $(typeof(func)) in $(typeof(set))")

# get variable bounds for interval arithmetic
function _update_variable_bounds(vref::JuMP.VariableRef, method::BigM)
if JuMP.is_binary(vref)
function _update_variable_bounds(vref::VariableRef, method::BigM)
if is_binary(vref)
lb = 0
elseif !JuMP.has_lower_bound(vref)
elseif !has_lower_bound(vref)
lb = -Inf
else
lb = JuMP.lower_bound(vref)
lb = lower_bound(vref)
end
if JuMP.is_binary(vref)
if is_binary(vref)
ub = 1
elseif !JuMP.has_upper_bound(vref)
elseif !has_upper_bound(vref)
ub = Inf
else
ub = JuMP.upper_bound(vref)
ub = upper_bound(vref)
end
return lb, ub
end

# perform interval arithmetic to update the initial M value
function _interval_arithmetic_LessThan(func::JuMP.AffExpr, M::Float64, method::BigM)
function _interval_arithmetic_LessThan(func::AffExpr, M::Float64, method::BigM)
for (var,coeff) in func.terms
JuMP.is_binary(var) && continue #skip binary variables
is_binary(var) && continue #skip binary variables
if coeff > 0
M += coeff*method.variable_bounds[var][2]
else
Expand All @@ -103,9 +103,9 @@ function _interval_arithmetic_LessThan(func::JuMP.AffExpr, M::Float64, method::B
end
return M + func.constant
end
function _interval_arithmetic_GreaterThan(func::JuMP.AffExpr, M::Float64, method::BigM)
function _interval_arithmetic_GreaterThan(func::AffExpr, M::Float64, method::BigM)
for (var,coeff) in func.terms
JuMP.is_binary(var) && continue #skip binary variables
is_binary(var) && continue #skip binary variables
if coeff < 0
M += coeff*method.variable_bounds[var][2]
else
Expand All @@ -119,81 +119,81 @@ end
# BIG-M REFORMULATION
################################################################################
function reformulate_disjunct_constraint(
model::JuMP.Model,
con::JuMP.ScalarConstraint{T, S},
bvref::JuMP.VariableRef,
model::Model,
con::ScalarConstraint{T, S},
bvref::VariableRef,
method::BigM
) where {T, S <: _MOI.LessThan}
M = _get_M_value(con.func, con.set, method)
new_func = JuMP.@expression(model, con.func - M*(1-bvref))
reform_con = JuMP.build_constraint(error, new_func, con.set)
new_func = @expression(model, con.func - M*(1-bvref))
reform_con = build_constraint(error, new_func, con.set)
return [reform_con]
end
function reformulate_disjunct_constraint(
model::JuMP.Model,
con::JuMP.VectorConstraint{T, S, R},
bvref::JuMP.VariableRef,
model::Model,
con::VectorConstraint{T, S, R},
bvref::VariableRef,
method::BigM
) where {T, S <: _MOI.Nonpositives, R}
M = [_get_M_value(func, con.set, method) for func in con.func]
new_func = JuMP.@expression(model, [i=1:con.set.dimension],
new_func = @expression(model, [i=1:con.set.dimension],
con.func[i] - M[i]*(1-bvref)
)
reform_con = JuMP.build_constraint(error, new_func, con.set)
reform_con = build_constraint(error, new_func, con.set)
return [reform_con]
end
function reformulate_disjunct_constraint(
model::JuMP.Model,
con::JuMP.ScalarConstraint{T, S},
bvref::JuMP.VariableRef,
model::Model,
con::ScalarConstraint{T, S},
bvref::VariableRef,
method::BigM
) where {T, S <: _MOI.GreaterThan}
M = _get_M_value(con.func, con.set, method)
new_func = JuMP.@expression(model, con.func + M*(1-bvref))
reform_con = JuMP.build_constraint(error, new_func, con.set)
new_func = @expression(model, con.func + M*(1-bvref))
reform_con = build_constraint(error, new_func, con.set)
return [reform_con]
end
function reformulate_disjunct_constraint(
model::JuMP.Model,
con::JuMP.VectorConstraint{T, S, R},
bvref::JuMP.VariableRef,
model::Model,
con::VectorConstraint{T, S, R},
bvref::VariableRef,
method::BigM
) where {T, S <: _MOI.Nonnegatives, R}
M = [_get_M_value(func, con.set, method) for func in con.func]
new_func = JuMP.@expression(model, [i=1:con.set.dimension],
new_func = @expression(model, [i=1:con.set.dimension],
con.func[i] + M[i]*(1-bvref)
)
reform_con = JuMP.build_constraint(error, new_func, con.set)
reform_con = build_constraint(error, new_func, con.set)
return [reform_con]
end
function reformulate_disjunct_constraint(
model::JuMP.Model,
con::JuMP.ScalarConstraint{T, S},
bvref::JuMP.VariableRef,
model::Model,
con::ScalarConstraint{T, S},
bvref::VariableRef,
method::BigM
) where {T, S <: Union{_MOI.Interval, _MOI.EqualTo}}
M = _get_M_value(con.func, con.set, method)
new_func_gt = JuMP.@expression(model, con.func + M[1]*(1-bvref))
new_func_lt = JuMP.@expression(model, con.func - M[2]*(1-bvref))
new_func_gt = @expression(model, con.func + M[1]*(1-bvref))
new_func_lt = @expression(model, con.func - M[2]*(1-bvref))
set_values = _set_values(con.set)
reform_con_gt = JuMP.build_constraint(error, new_func_gt, _MOI.GreaterThan(set_values[1]))
reform_con_lt = JuMP.build_constraint(error, new_func_lt, _MOI.LessThan(set_values[2]))
reform_con_gt = build_constraint(error, new_func_gt, _MOI.GreaterThan(set_values[1]))
reform_con_lt = build_constraint(error, new_func_lt, _MOI.LessThan(set_values[2]))
return [reform_con_gt, reform_con_lt]
end
function reformulate_disjunct_constraint(
model::JuMP.Model,
con::JuMP.VectorConstraint{T, S, R},
bvref::JuMP.VariableRef,
model::Model,
con::VectorConstraint{T, S, R},
bvref::VariableRef,
method::BigM
) where {T, S <: _MOI.Zeros, R}
M = [_get_M_value(func, con.set, method) for func in con.func]
new_func_nn = JuMP.@expression(model, [i=1:con.set.dimension],
new_func_nn = @expression(model, [i=1:con.set.dimension],
con.func[i] + M[i][1]*(1-bvref)
)
new_func_np = JuMP.@expression(model, [i=1:con.set.dimension],
new_func_np = @expression(model, [i=1:con.set.dimension],
con.func[i] - M[i][2]*(1-bvref)
)
reform_con_nn = JuMP.build_constraint(error, new_func_nn, _MOI.Nonnegatives(con.set.dimension))
reform_con_np = JuMP.build_constraint(error, new_func_np, _MOI.Nonpositives(con.set.dimension))
reform_con_nn = build_constraint(error, new_func_nn, _MOI.Nonnegatives(con.set.dimension))
reform_con_np = build_constraint(error, new_func_np, _MOI.Nonpositives(con.set.dimension))
return [reform_con_nn, reform_con_np]
end
Loading

0 comments on commit 590fd8b

Please sign in to comment.