Skip to content

Constraints.jl: Streamlining Constraint Definition and Integration in Julia

julia
using Constraints

@info concept(:cumulative, [1, 2, 3, 4, 5]; val = 1)
@info concept(:cumulative, [1, 2, 2, 4, 5]; val = 1)
@info concept(:cumulative, [1, 2, 3, 4, 5]; pair_vars = [3 2 5 4 2; 1 2 1 1 3], op =, val = 5)
@info concept(:cumulative, [1, 2, 3, 4, 5]; pair_vars = [3 2 5 4 2; 1 2 1 1 3], op = <, val = 5)
julia
using Constraints

c = x -> Constraints.xcsp_cumulative(
	origins = x,
	lengths = [3, 2, 5, 4, 2],
	heights = [1, 2, 1, 1, 3],
	condition = (, 5)
)

@info c([1, 2, 3, 4, 5])
@info c([1, 1, 1, 2, 2])
julia
using CBLS, JuMP

model = Model(CBLS.Optimizer)
@variable(model, 1X[1:5]5, Int)
@variable(model, 1Y[1:5]5, Int)
@variable(model, 1Z[1:5]5, Int)
@constraint(model, X in Cumulative(; val = 1))
@constraint(model,
    Y in Cumulative(; pair_vars = [3 2 5 4 2; 1 2 1 1 3], op =, val = 5))
@constraint(model,
    Z in Cumulative(; pair_vars = [3 2 5 4 2; 1 2 1 1 3], op = <, val = 5))
JuMP.optimize!(model)
@info "Cumulative" value.(X) value.(Y) value.(Z)
julia
# TODO: How to handle intention in JuMP/MOI
julia
using Constraints

@info concept(:no_overlap, [1, 2, 3, 4, 5])
@info concept(:no_overlap, [1, 2, 3, 4, 1])
@info concept(:no_overlap, [1, 2, 4, 6, 3]; pair_vars = [1, 1, 1, 1, 1])
@info concept(:no_overlap, [1, 2, 4, 6, 3]; pair_vars = [1, 1, 1, 3, 1])
@info concept(:no_overlap, [1, 2, 4, 6, 3]; pair_vars = [1, 1, 3, 1, 1])
julia
using Constraints

c = x -> Constraints.xcsp_no_overlap(
	origins = x,
	lengths = [1, 4, 10],
	zero_ignored = true
)

@info c([1, 3, 10])
@info c([2, 1, 4, 3])
julia
using CBLS, JuMP

model = Model(CBLS.Optimizer)
@variable(model, 1X[1:5]5, Int)
@variable(model, 1Y[1:5]6, Int)
@variable(model, 1Z[1:12]12, Int)
@constraint(model, X in NoOverlap())
@constraint(model, Y in NoOverlap(; pair_vars = [1, 1, 1, 1, 1]))
@constraint(model,
    Z in NoOverlap(; pair_vars = [2, 4, 1, 4, 2, 3, 5, 1, 2, 3, 3, 2], dim = 3))
JuMP.optimize!(model)
@info "NoOverlap" value.(X) value.(Y) value.(Z)
julia
# TODO: How to handle intention in JuMP/MOI

Packing and Scheduling Constraints

Constraints.xcsp_cumulative Function
julia
xcsp_cumulative(; origins, lengths, heights, condition)

Return true if the cumulative constraint is satisfied, false otherwise. The cumulative constraint is a global constraint operating on a set of tasks, defined by origin (starting times), length, and height. This constraint ensures that, at each point in time, the sum of the height of tasks that overlap that point, respects a numerical condition.

Arguments

  • origins::AbstractVector: list of origins of the tasks.

  • lengths::AbstractVector: list of lengths of the tasks.

  • heights::AbstractVector: list of heights of the tasks.

  • condition::Tuple: condition to check.

Variants

  • :cumulative: Global constraint operating on a set of tasks, defined by origin (starting times), length, and height. This constraint ensures that, at each point in time, the sum of the height of tasks that overlap that point, respects a numerical condition.
julia
concept(:cumulative, x; pair_vars, op, val)
concept(:cumulative)(x; pair_vars, op, val)

Examples

julia
c = concept(:cumulative)

c([1, 2, 3, 4, 5]; val = 1)
c([1, 2, 2, 4, 5]; val = 1)
c([1, 2, 3, 4, 5]; pair_vars = [3 2 5 4 2; 1 2 1 1 3], op =, val = 5)
c([1, 2, 3, 4, 5]; pair_vars = [3 2 5 4 2; 1 2 1 1 3], op = <, val = 5)

source

Constraints.xcsp_no_overlap Function
julia
xcsp_no_overlap(; origins, lengths, zero_ignored)

Return true if the no_overlap constraint is satisfied, false otherwise. The no_overlap constraint is a global constraint used in constraint programming, often in scheduling problems. It ensures that tasks do not overlap in time, i.e., for any two tasks, either the first task finishes before the second task starts, or the second task finishes before the first task starts.

Arguments

  • origins::AbstractVector: list of origins of the tasks.

  • lengths::AbstractVector: list of lengths of the tasks.

  • zero_ignored::Bool: whether to ignore zero-length tasks.

Variants

  • :no_overlap: Global constraint operating on a set of tasks, defined by origin (starting times), and length. This constraint ensures that tasks do not overlap in time, i.e., for any two tasks, either the first task finishes before the second task starts, or the second task finishes before the first task starts. Often used in scheduling problems.
julia
concept(:no_overlap, x; pair_vars, bool)
concept(:no_overlap)(x; pair_vars, bool)
  • :no_overlap_no_zero: Global constraint operating on a set of tasks, defined by origin (starting times), and length. This constraint ensures that tasks do not overlap in time, i.e., for any two tasks, either the first task finishes before the second task starts, or the second task finishes before the first task starts. This variant ignores zero-length tasks. Often used in scheduling problems.
julia
concept(:no_overlap_no_zero, x; pair_vars)
concept(:no_overlap_no_zero)(x; pair_vars)
  • :no_overlap_with_zero: Global constraint operating on a set of tasks, defined by origin (starting times), and length. This constraint ensures that tasks do not overlap in time, i.e., for any two tasks, either the first task finishes before the second task starts, or the second task finishes before the first task starts. This variant includes zero-length tasks. Often used in scheduling problems.
julia
concept(:no_overlap_with_zero, x; pair_vars)
concept(:no_overlap_with_zero)(x; pair_vars)

Examples

julia
c = concept(:no_overlap)

c([1, 2, 3, 4, 5])
c([1, 2, 3, 4, 1])
c([1, 2, 4, 6, 3]; pair_vars = [1, 1, 1, 1, 1])
c([1, 2, 4, 6, 3]; pair_vars = [1, 1, 1, 3, 1])
c([1, 2, 4, 6, 3]; pair_vars = [1, 1, 3, 1, 1])
c([1, 1, 1, 3, 5, 2, 7, 7, 5, 12, 8, 7]; pair_vars = [2, 4, 1, 4 ,2 ,3, 5, 1, 2, 3, 3, 2], dim = 3)
c([1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4]; pair_vars = [2, 4, 1, 4 ,2 ,3, 5, 1, 2, 3, 3, 2], dim = 3)

source