Skip to content

Commit

Permalink
Merge pull request #86 from hdavid16/dev
Browse files Browse the repository at this point in the history
  • Loading branch information
hdavid16 authored Oct 17, 2023
2 parents 98f5246 + b6e0902 commit de77f25
Show file tree
Hide file tree
Showing 18 changed files with 164 additions and 164 deletions.
14 changes: 7 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -85,12 +85,12 @@ Two types of logical constraints are supported:

## Disjunctions

Disjunctions are built by first defining the constraints associated with each disjunct. This is done via the `@constraint` JuMP macro with the extra `DisjunctConstraint` tag specifying the Logical variable associated with the constraint:
Disjunctions are built by first defining the constraints associated with each disjunct. This is done via the `@constraint` JuMP macro with the extra `Disjunct` tag specifying the Logical variable associated with the constraint:

```julia
@variable(model, x)
@constraint(model, x ≤ 100, DisjunctConstraint(Y[1]))
@constraint(model, x ≥ 200, DisjunctConstraint(Y[2]))
@constraint(model, x ≤ 100, Disjunct(Y[1]))
@constraint(model, x ≥ 200, Disjunct(Y[2]))
```

After all disjunct constraints associated with a disjunction have been defined, the disjunction is created with the `@disjunction` macro, where the disjunction is defined as a `Vector` of Logical variables associated with each disjunct:
Expand All @@ -99,10 +99,10 @@ After all disjunct constraints associated with a disjunction have been defined,
@disjunction(model, [Y[1], Y[2]])
```

Disjunctions can be nested by passing an additional `DisjunctConstraint` tag. The Logical variable in the `DisjunctConstraint` tag specifies which disjunct, the nested disjunction belongs to:
Disjunctions can be nested by passing an additional `Disjunct` tag. The Logical variable in the `Disjunct` tag specifies which disjunct, the nested disjunction belongs to:

```julia
@disjunction(model, Y[1:2], DisjunctConstraint(Y[3]))
@disjunction(model, Y[1:2], Disjunct(Y[3]))
```

Empty disjuncts are supported in GDP models. When used, the only constraints enforced on the model when the empty disjunct is selected are the global constraints and any other disjunction constraints defined.
Expand Down Expand Up @@ -139,8 +139,8 @@ using HiGHS
m = GDPModel(HiGHS.Optimizer)
@variable(m, 0 ≤ x[1:2] ≤ 20)
@variable(m, Y[1:2], Logical)
@constraint(m, [i = 1:2], [2,5][i] ≤ x[i] ≤ [6,9][i], DisjunctConstraint(Y[1]))
@constraint(m, [i = 1:2], [8,10][i] ≤ x[i] ≤ [11,15][i], DisjunctConstraint(Y[2]))
@constraint(m, [i = 1:2], [2,5][i] ≤ x[i] ≤ [6,9][i], Disjunct(Y[1]))
@constraint(m, [i = 1:2], [8,10][i] ≤ x[i] ≤ [11,15][i], Disjunct(Y[2]))
@disjunction(m, Y)
@constraint(m, Y in Exactly(1)) #logical constraint
@objective(m, Max, sum(x))
Expand Down
14 changes: 7 additions & 7 deletions docs/src/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -85,12 +85,12 @@ Two types of logical constraints are supported:

## Disjunctions

Disjunctions are built by first defining the constraints associated with each disjunct. This is done via the `@constraint` JuMP macro with the extra `DisjunctConstraint` tag specifying the Logical variable associated with the constraint:
Disjunctions are built by first defining the constraints associated with each disjunct. This is done via the `@constraint` JuMP macro with the extra `Disjunct` tag specifying the Logical variable associated with the constraint:

```julia
@variable(model, x)
@constraint(model, x ≤ 100, DisjunctConstraint(Y[1]))
@constraint(model, x ≥ 200, DisjunctConstraint(Y[2]))
@constraint(model, x ≤ 100, Disjunct(Y[1]))
@constraint(model, x ≥ 200, Disjunct(Y[2]))
```

After all disjunct constraints associated with a disjunction have been defined, the disjunction is created with the `@disjunction` macro, where the disjunction is defined as a `Vector` of Logical variables associated with each disjunct:
Expand All @@ -99,10 +99,10 @@ After all disjunct constraints associated with a disjunction have been defined,
@disjunction(model, [Y[1], Y[2]])
```

Disjunctions can be nested by passing an additional `DisjunctConstraint` tag. The Logical variable in the `DisjunctConstraint` tag specifies which disjunct, the nested disjunction belongs to:
Disjunctions can be nested by passing an additional `Disjunct` tag. The Logical variable in the `Disjunct` tag specifies which disjunct, the nested disjunction belongs to:

```julia
@disjunction(model, Y[1:2], DisjunctConstraint(Y[3]))
@disjunction(model, Y[1:2], Disjunct(Y[3]))
```

Empty disjuncts are supported in GDP models. When used, the only constraints enforced on the model when the empty disjunct is selected are the global constraints and any other disjunction constraints defined.
Expand Down Expand Up @@ -139,8 +139,8 @@ using HiGHS
m = GDPModel(HiGHS.Optimizer)
@variable(m, 0 ≤ x[1:2] ≤ 20)
@variable(m, Y[1:2], Logical)
@constraint(m, [i = 1:2], [2,5][i] ≤ x[i] ≤ [6,9][i], DisjunctConstraint(Y[1]))
@constraint(m, [i = 1:2], [8,10][i] ≤ x[i] ≤ [11,15][i], DisjunctConstraint(Y[2]))
@constraint(m, [i = 1:2], [2,5][i] ≤ x[i] ≤ [6,9][i], Disjunct(Y[1]))
@constraint(m, [i = 1:2], [8,10][i] ≤ x[i] ≤ [11,15][i], Disjunct(Y[2]))
@disjunction(m, Y)
@constraint(m, Y in Exactly(1)) #logical constraint
@objective(m, Max, sum(x))
Expand Down
6 changes: 3 additions & 3 deletions examples/ex1.jl
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ using HiGHS
m = GDPModel()
@variable(m, -5 x 10)
@variable(m, Y[1:2], Logical)
@constraint(m, 0 x 3, DisjunctConstraint(Y[1]))
@constraint(m, 5 x, DisjunctConstraint(Y[2]))
@constraint(m, x 9, DisjunctConstraint(Y[2]))
@constraint(m, 0 x 3, Disjunct(Y[1]))
@constraint(m, 5 x, Disjunct(Y[2]))
@constraint(m, x 9, Disjunct(Y[2]))
@disjunction(m, [Y[1], Y[2]])
@constraint(m, Y in Exactly(1))
@objective(m, Max, x)
Expand Down
4 changes: 2 additions & 2 deletions examples/ex2.jl
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ using HiGHS
m = GDPModel(HiGHS.Optimizer)
@variable(m, 0 x[1:2] 20)
@variable(m, Y[1:2], Logical)
@constraint(m, [i = 1:2], [2,5][i] x[i] [6,9][i], DisjunctConstraint(Y[1]))
@constraint(m, [i = 1:2], [8,10][i] x[i] [11,15][i], DisjunctConstraint(Y[2]))
@constraint(m, [i = 1:2], [2,5][i] x[i] [6,9][i], Disjunct(Y[1]))
@constraint(m, [i = 1:2], [8,10][i] x[i] [11,15][i], Disjunct(Y[2]))
@disjunction(m, Y)
@constraint(m, Y in Exactly(1)) #logical constraint
@objective(m, Max, sum(x))
Expand Down
8 changes: 4 additions & 4 deletions examples/ex3.jl
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ using DisjunctiveProgramming
m = GDPModel()
@variable(m, -5 x 10)
@variable(m, Y[1:2], Logical)
@constraint(m, exp(x) <= 2, DisjunctConstraint(Y[1]))
@constraint(m, x >= -3, DisjunctConstraint(Y[1]))
@constraint(m, exp(x) >= 3, DisjunctConstraint(Y[2]))
@constraint(m, x >= 5, DisjunctConstraint(Y[2]))
@constraint(m, exp(x) <= 2, Disjunct(Y[1]))
@constraint(m, x >= -3, Disjunct(Y[1]))
@constraint(m, exp(x) >= 3, Disjunct(Y[2]))
@constraint(m, x >= 5, Disjunct(Y[2]))
@disjunction(m, Y)
@constraint(m, Y in Exactly(1)) #logical constraint
@objective(m, Max, x)
Expand Down
10 changes: 5 additions & 5 deletions examples/ex5.jl
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@ m = GDPModel()
@variable(m, Y[1:2], Logical)
@variable(m, W[1:2], Logical)
@objective(m, Max, sum(x))
@constraint(m, y1[i=1:2], [1,4][i] x[i] [3,6][i], DisjunctConstraint(Y[1]))
@constraint(m, w1[i=1:2], [1,5][i] x[i] [2,6][i], DisjunctConstraint(W[1]))
@constraint(m, w2[i=1:2], [2,4][i] x[i] [3,5][i], DisjunctConstraint(W[2]))
@constraint(m, y2[i=1:2], [8,1][i] x[i] [9,2][i], DisjunctConstraint(Y[2]))
@disjunction(m, inner, [W[1], W[2]], DisjunctConstraint(Y[1]))
@constraint(m, y1[i=1:2], [1,4][i] x[i] [3,6][i], Disjunct(Y[1]))
@constraint(m, w1[i=1:2], [1,5][i] x[i] [2,6][i], Disjunct(W[1]))
@constraint(m, w2[i=1:2], [2,4][i] x[i] [3,5][i], Disjunct(W[2]))
@constraint(m, y2[i=1:2], [8,1][i] x[i] [9,2][i], Disjunct(Y[2]))
@disjunction(m, inner, [W[1], W[2]], Disjunct(Y[1]))
@disjunction(m, outer, [Y[1], Y[2]])
@constraint(m, Y in Exactly(1))
@constraint(m, W in Exactly(Y[1]))
Expand Down
22 changes: 11 additions & 11 deletions examples/ex6.jl
Original file line number Diff line number Diff line change
Expand Up @@ -5,24 +5,24 @@ m = GDPModel()
@variable(m, -5 <= x[1:3] <= 5)

@variable(m, y[1:2], Logical)
@constraint(m, x[1] <= -2, DisjunctConstraint(y[1]))
@constraint(m, x[1] >= 2, DisjunctConstraint(y[2]))
@constraint(m, x[2] == -1, DisjunctConstraint(y[2]))
@constraint(m, x[3] == 1, DisjunctConstraint(y[2]))
@constraint(m, x[1] <= -2, Disjunct(y[1]))
@constraint(m, x[1] >= 2, Disjunct(y[2]))
@constraint(m, x[2] == -1, Disjunct(y[2]))
@constraint(m, x[3] == 1, Disjunct(y[2]))
@disjunction(m, y)
@constraint(m, y in Exactly(1))

@variable(m, w[1:2], Logical)
@constraint(m, x[2] <= -3, DisjunctConstraint(w[1]))
@constraint(m, x[2] >= 3, DisjunctConstraint(w[2]))
@constraint(m, x[3] == 0, DisjunctConstraint(w[2]))
@disjunction(m, w, DisjunctConstraint(y[1]))
@constraint(m, x[2] <= -3, Disjunct(w[1]))
@constraint(m, x[2] >= 3, Disjunct(w[2]))
@constraint(m, x[3] == 0, Disjunct(w[2]))
@disjunction(m, w, Disjunct(y[1]))
@constraint(m, w in Exactly(y[1]))

@variable(m, z[1:2], Logical)
@constraint(m, x[3] <= -4, DisjunctConstraint(z[1]))
@constraint(m, x[3] >= 4, DisjunctConstraint(z[2]))
@disjunction(m, z, DisjunctConstraint(w[1]))
@constraint(m, x[3] <= -4, Disjunct(z[1]))
@constraint(m, x[3] >= 4, Disjunct(z[2]))
@disjunction(m, z, Disjunct(w[1]))
@constraint(m, z in Exactly(w[1]))

##
Expand Down
20 changes: 10 additions & 10 deletions src/constraints.jl
Original file line number Diff line number Diff line change
Expand Up @@ -163,20 +163,20 @@ end
_error::Function,
func,
set::_MOI.AbstractScalarSet,
tag::DisjunctConstraint
tag::Disjunct
)::_DisjunctConstraint
Extend `JuMP.build_constraint` to add constraints to disjuncts. This in
combination with `JuMP.add_constraint` enables the use of
`@constraint(model, [name], constr_expr, tag)`, where tag is a
`DisjunctConstraint(::Type{LogicalVariableRef})`. The user must specify the
`Disjunct(::Type{LogicalVariableRef})`. The user must specify the
`LogicalVariable` to use as the indicator for the `_DisjunctConstraint` being created.
"""
function JuMP.build_constraint(
_error::Function,
func,
set::_MOI.AbstractScalarSet,
tag::DisjunctConstraint
tag::Disjunct
)
_check_expression(func)
constr = build_constraint(_error, func, set)
Expand All @@ -194,7 +194,7 @@ for SetType in (
_error::Function,
func,
set::$($SetType),
tag::DisjunctConstraint
tag::Disjunct
)::_DisjunctConstraint
Extend `JuMP.build_constraint` to add `VectorConstraint`s to disjuncts.
Expand All @@ -203,7 +203,7 @@ for SetType in (
_error::Function,
func,
set::$SetType,
tag::DisjunctConstraint
tag::Disjunct
)
_check_expression(func)
constr = build_constraint(_error, func, set)
Expand All @@ -218,7 +218,7 @@ function JuMP.build_constraint(
func::AbstractJuMPScalar,
lb::Real,
ub::Real,
tag::DisjunctConstraint
tag::Disjunct
)
_check_expression(func)
constr = build_constraint(_error, func, lb, ub)
Expand All @@ -234,7 +234,7 @@ end
name::String = ""
)::DisjunctConstraintRef
Extend `JuMP.add_constraint` to add a [`DisjunctConstraint`](@ref) to a [`GDPModel`](@ref).
Extend `JuMP.add_constraint` to add a [`Disjunct`](@ref) to a [`GDPModel`](@ref).
The constraint is added to the `GDPData` in the `.ext` dictionary of the `GDPModel`.
"""
function JuMP.add_constraint(
Expand Down Expand Up @@ -329,7 +329,7 @@ function _disjunction(
model::Model, # TODO: generalize to AbstractModel
structure,
name::String,
tag::DisjunctConstraint
tag::Disjunct
)
dref = _create_disjunction(_error, model, structure, name, true)
obj = constraint_object(dref)
Expand Down Expand Up @@ -362,7 +362,7 @@ Function to add a [`Disjunction`](@ref) to a [`GDPModel`](@ref).
disjunction(
model::Model,
disjunct_indicators::Vector{LogicalVariableRef},
nested_tag::DisjunctConstraint,
nested_tag::Disjunct,
name::String = ""
)
Expand All @@ -378,7 +378,7 @@ end
function disjunction(
model::Model,
disjunct_indicators,
nested_tag::DisjunctConstraint,
nested_tag::Disjunct,
name::String = ""
) # TODO add kw argument to build exactly 1 constraint
return _disjunction(error, model, disjunct_indicators, name, nested_tag)
Expand Down
10 changes: 5 additions & 5 deletions src/datatypes.jl
Original file line number Diff line number Diff line change
Expand Up @@ -176,20 +176,20 @@ end
# DISJUNCT CONSTRAINTS
################################################################################
"""
DisjunctConstraint
Disjunct
Used as a tag for constraints that will be used in disjunctions. This is done via
the following syntax:
```julia-repl
julia> @constraint(model, [constr_expr], DisjunctConstraint)
julia> @constraint(model, [constr_expr], Disjunct)
julia> @constraint(model, [constr_expr], DisjunctConstraint(lvref))
julia> @constraint(model, [constr_expr], Disjunct(lvref))
```
where `lvref` is a [`LogicalVariableRef`](@ref) that will ultimately be associated
with the disjunct the constraint is added to. If no `lvref` is given, then one is
generated when the disjunction is created.
"""
struct DisjunctConstraint
struct Disjunct
indicator::LogicalVariableRef
end

Expand All @@ -202,7 +202,7 @@ end
"""
DisjunctConstraintIndex
A type for storing the index of a [`DisjunctConstraint`](@ref).
A type for storing the index of a [`Disjunct`](@ref).
**Fields**
- `value::Int64`: The index value.
Expand Down
6 changes: 3 additions & 3 deletions src/macros.jl
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ macro disjunction(model, args...)
_error("Invalid syntax. Did you mean to use `@disjunctions`?")
end

# TODO: three cases lead to problems when julia variables are used for DisjunctConstraint tags
# TODO: three cases lead to problems when julia variables are used for Disjunct tags
# which violate the cases considered in the table further below. The three cases are
# (i) @disjunction(m, Y[1, :], tag[1]) --> gets confused for @disjunction(m, name[...], Y[1, :]) (Case 2 below)
# (ii) @disjunction(m, Y, tagref) --> gets confused for @disjunction(m, name, Y) (Case 1 below)
Expand Down Expand Up @@ -281,8 +281,8 @@ model = GDPModel();
@variable(model, w);
@variable(model, x);
@variable(model, Y[1:4], LogicalVariable);
@constraint(model, [i=1:2], w == i, DisjunctConstraint(Y[i]));
@constraint(model, [i=3:4], x == i, DisjunctConstraint(Y[i]));
@constraint(model, [i=1:2], w == i, Disjunct(Y[i]));
@constraint(model, [i=3:4], x == i, Disjunct(Y[i]));
@disjunctions(model, begin
[Y[1], Y[2]]
[Y[3], Y[4]]
Expand Down
Loading

0 comments on commit de77f25

Please sign in to comment.