Skip to content
Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ The following reformulation methods are currently supported:

All variables must be included in exactly one partition. For manual partitioning, ensure each variable appears in exactly one group. For automatic partitioning, variables are divided as evenly as possible among the specified number of partitions.

6. [Cutting Planes](https://pubsonline.informs.org/doi/10.1287/ijoc.2015.0669): This method iteratively generates cutting planes using a separation problem and a relaxed Big-M formulation, then applies a final reformulation method. The `cutting_planes` struct is created with the following arguments:
6. [Cutting Planes](https://pubsonline.informs.org/doi/10.1287/ijoc.2015.0669): This method iteratively generates cutting planes using a separation problem and a relaxed Big-M formulation, then applies a final reformulation method. The `CuttingPlanes` struct is created with the following arguments:

- `optimizer`: Optimizer to use when solving the separation and relaxed Big-M subproblems. This is a required value.
- `max_iter`: Maximum number of cutting plane iterations. Default: `3`.
Expand Down
4 changes: 2 additions & 2 deletions ext/InfiniteDisjunctiveProgramming.jl
Original file line number Diff line number Diff line change
Expand Up @@ -178,8 +178,8 @@ function DP.reformulate_model(::InfiniteOpt.InfiniteModel, ::DP.MBM)
"Please use `BigM`, `Hull`, `Indicator`, or `PSplit` instead.")
end

function DP.reformulate_model(::InfiniteOpt.InfiniteModel, ::DP.cutting_planes)
error("The `cutting_planes` method is not supported for `InfiniteModel`." *
function DP.reformulate_model(::InfiniteOpt.InfiniteModel, ::DP.CuttingPlanes)
error("The `CuttingPlanes` method is not supported for `InfiniteModel`." *
"Please use `BigM`, `Hull`, `Indicator`, or `PSplit` instead.")
end

Expand Down
12 changes: 6 additions & 6 deletions src/cuttingplanes.jl
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
function reformulate_model(
model::JuMP.AbstractModel,
method::cutting_planes
method::CuttingPlanes
)
_clear_reformulations(model)
var_type = JuMP.variable_ref_type(model)
Expand Down Expand Up @@ -39,7 +39,7 @@ function reformulate_model(
rBM_sol = _solve_rBM(rBM)
SEP_sol = _solve_SEP(SEP, rBM, rBM_sol, SEP_to_rBM_map, rBM_to_SEP_map)
sep_obj = objective_value(SEP)
_cutting_planes(model, rBM, main_to_rBM_map,
_CuttingPlanes(model, rBM, main_to_rBM_map,
main_to_SEP_map, rBM_sol, SEP_sol
)
i += 1
Expand Down Expand Up @@ -90,7 +90,7 @@ function _solve_SEP(
return sol
end

function _cutting_planes(
function _CuttingPlanes(
model::M,
rBM::M,
main_to_rBM_map::Dict{<:JuMP.AbstractVariableRef,<:JuMP.AbstractVariableRef},
Expand Down Expand Up @@ -123,7 +123,7 @@ end
# ERROR MESSAGES
################################################################################

function reformulate_model(::M, ::cutting_planes) where {M}
function reformulate_model(::M, ::CuttingPlanes) where {M}
error("reformulate_model not implemented for model type `$(M)`.")
end

Expand All @@ -139,8 +139,8 @@ function _solve_SEP(::M, ::N, ::H, ::S, ::R) where {M, N, H, S, R}
rBM_to_SEP_map: `$(R)`.")
end

function _cutting_planes(::M, ::N, ::H, ::S, ::R, ::T) where {M, N, H, S, R, T}
error("_cutting_planes not implemented for argument types: \n
function _CuttingPlanes(::M, ::N, ::H, ::S, ::R, ::T) where {M, N, H, S, R, T}
error("_CuttingPlanes not implemented for argument types: \n
model: `$(M)`, rBM: `$(N)`,\n
main_to_rBM_map: `$(H)`, main_to_SEP_map:
`$(S)`,\n
Expand Down
79 changes: 56 additions & 23 deletions src/datatypes.jl
Original file line number Diff line number Diff line change
Expand Up @@ -388,15 +388,20 @@ end

mutable struct _MBM{O, T, M <: JuMP.AbstractModel} <: AbstractReformulationMethod
optimizer::O
M::Dict{LogicalVariableRef{M}, T}
default_M::T
conlvref::Vector{LogicalVariableRef{M}}
M::Dict{LogicalVariableRef{M}, Any}
default_M::T
subproblem_indicators::Vector{LogicalVariableRef{M}}
# Cached submodels: indicator => GDPSubmodel.
# Typed Any so extensions can store different types.
model_cache::Dict{LogicalVariableRef{M}, Any}

function _MBM(method::MBM{O, T}, model::M) where {O, T, M <: JuMP.AbstractModel}
new{O, T, M}(method.optimizer,
Dict{LogicalVariableRef{M}, T}(),
new{O, T, M}(
method.optimizer,
Dict{LogicalVariableRef{M}, Any}(),
method.default_M,
Vector{LogicalVariableRef{M}}()
Vector{LogicalVariableRef{M}}(),
Dict{LogicalVariableRef{M}, Any}()
)
end
end
Expand Down Expand Up @@ -432,35 +437,63 @@ mutable struct _Hull{V <: JuMP.AbstractVariableRef, T} <: AbstractReformulationM
end

"""
cutting_planes{O} <: AbstractReformulationMethod
CuttingPlanes{O,T} <: AbstractReformulationMethod

A type for using the cutting planes approach for disjunctive constraints.

**Fields**
- `optimizer::O`: Optimizer to use when solving mini-models (required).
- `max_iter::Int`: Number of iterations (default = `3`).
- `seperation_tolerance::Float64`: Tolerance for the separation problem (default = `1e-6`).
- `seperation_tolerance::T`: Tolerance for the separation problem (default = `1e-6`).
- `final_reform_method::AbstractReformulationMethod`: Final reformulation
method to use after cutting planes (default = `BigM()`).
- `M_value::Float64`: Big-M value to use in the final reformulation (default = `1e9`).
- `M_value::T`: Big-M value to use in the final reformulation (default = `1e9`).
"""
struct cutting_planes{O} <: AbstractReformulationMethod
struct CuttingPlanes{O, T} <: AbstractReformulationMethod
optimizer::O;
max_iter::Int
seperation_tolerance::Float64
seperation_tolerance::T
final_reform_method::AbstractReformulationMethod
M_value::Float64
function cutting_planes(
optimizer::O;
max_iter::Int = 3,
seperation_tolerance::Float64 = 1e-6,
final_reform_method = BigM(),
M_value::Float64 = 1e9
) where {O}
new{O}(optimizer, max_iter, seperation_tolerance, final_reform_method, M_value)
M_value::T
function CuttingPlanes(
optimizer::O;
max_iter::Int = 3,
seperation_tolerance::T = 1e-6,
final_reform_method = BigM(),
M_value::T = 1e9
) where {O, T}
new{O, T}(optimizer, max_iter, seperation_tolerance, final_reform_method, M_value)
end
end

################################################################################
# GDP SUBMODEL
################################################################################

"""
GDPSubmodel{M, V, W}

A unified submodel wrapper used by MBM and cutting plane
reformulations. It encapsulates a flat JuMP optimization
submodel built from a single disjunct's feasible region,
along with mappings back to the original model's variables.

## Fields
- `model::M`: The JuMP submodel representing a disjunct's
feasible region (constraints and variable bounds).
- `dec_vars::Vector{V}`: Ordered decision variables in
the submodel, matching the original model's ordering.
- `fwd::Dict{V, Vector{W}}`: Forward map from original
model variables to their submodel counterparts.
"""
struct GDPSubmodel{M <: JuMP.AbstractModel,
V <: JuMP.AbstractVariableRef,
W <: JuMP.AbstractVariableRef}
model::M
dec_vars::Vector{V}
fwd::Dict{V, Vector{W}}
Comment thread
dnguyen227 marked this conversation as resolved.
Outdated
end

"""
PSplit <: AbstractReformulationMethod

Expand Down Expand Up @@ -635,9 +668,9 @@ end
"""
VariableProperties(expr)::VariableProperties

Creates a `VariableProperties` object with blank variable info (no bounds, not fixed,
not binary/integer) from an expression. The `expr` argument is provided for
extensions to infer additional properties (e.g., parameter dependencies in InfiniteOpt).
Creates a `VariableProperties` object with blank variable info (no bounds, not fixed,
not binary/integer) from an expression. The `expr` argument is provided for
extensions to infer additional properties.

## Arguments
- `expr`: Expression for extensions to extract metadata from
Expand Down
Loading
Loading