From ef5dd1dad6f918acf07dca64271661dbf4b52169 Mon Sep 17 00:00:00 2001 From: Ole Kroeger Date: Sat, 31 Jul 2021 16:00:01 +0200 Subject: [PATCH 01/10] removed changed! function --- src/constraints/boolset.jl | 8 -------- src/constraints/indicator.jl | 5 ----- src/constraints/linear_constraints.jl | 4 ---- src/constraints/reified.jl | 9 --------- src/pruning.jl | 1 - src/util.jl | 4 ---- test/unit/constraints/and.jl | 1 - test/unit/constraints/complement.jl | 4 ---- test/unit/constraints/less_than.jl | 1 - test/unit/constraints/or.jl | 2 -- test/unit/constraints/reified.jl | 1 - test/unit/constraints/strictly_less_than.jl | 2 -- test/unit/constraints/xnor.jl | 1 - test/unit/constraints/xor.jl | 2 -- 14 files changed, 45 deletions(-) diff --git a/src/constraints/boolset.jl b/src/constraints/boolset.jl index d1d9e3c2..af696b32 100644 --- a/src/constraints/boolset.jl +++ b/src/constraints/boolset.jl @@ -298,11 +298,3 @@ function finished_pruning_constraint!( end end end - - -function changed!(com::CS.CoM, constraint::BoolConstraint, fct, set) - lhs = constraint.lhs - changed!(com, lhs, lhs.fct, lhs.set) - rhs = constraint.rhs - changed!(com, rhs, rhs.fct, rhs.set) -end \ No newline at end of file diff --git a/src/constraints/indicator.jl b/src/constraints/indicator.jl index c862da1d..40129612 100644 --- a/src/constraints/indicator.jl +++ b/src/constraints/indicator.jl @@ -231,8 +231,3 @@ function is_constraint_violated( end return false end - -function changed!(com::CS.CoM, constraint::IndicatorConstraint, fct, set) - inner_constraint = constraint.inner_constraint - changed!(com, inner_constraint, inner_constraint.fct, inner_constraint.set) -end \ No newline at end of file diff --git a/src/constraints/linear_constraints.jl b/src/constraints/linear_constraints.jl index 7474dbd7..83198e51 100644 --- a/src/constraints/linear_constraints.jl +++ b/src/constraints/linear_constraints.jl @@ -116,10 +116,6 @@ function init_constraint!( return true end -function changed!(com::CS.CoM, constraint::LinearConstraint, fct, set) - recompute_lc_extrema!(com, constraint, fct) -end - """ get_new_extrema_and_sum(search_space, vidx, i, terms, full_min, full_max, pre_mins, pre_maxs) diff --git a/src/constraints/reified.jl b/src/constraints/reified.jl index 89bf3faf..ed849da1 100644 --- a/src/constraints/reified.jl +++ b/src/constraints/reified.jl @@ -207,12 +207,3 @@ function is_constraint_violated( end return false end - -function changed!(com::CS.CoM, constraint::ReifiedConstraint, fct, set) - inner_constraint = constraint.inner_constraint - changed!(com, inner_constraint, inner_constraint.fct, inner_constraint.set) - if constraint.complement_constraint !== nothing - complement_constraint = constraint.complement_constraint - changed!(com, complement_constraint, complement_constraint.fct, complement_constraint.set) - end -end \ No newline at end of file diff --git a/src/pruning.jl b/src/pruning.jl index 08a701e1..5361f01b 100644 --- a/src/pruning.jl +++ b/src/pruning.jl @@ -91,7 +91,6 @@ function prune!( constraint_idxs_vec[ci] = N constraint = com.constraints[ci] - changed!(com, constraint, constraint.fct, constraint.set) feasible = prune_constraint!(com, constraint, constraint.fct, constraint.set; logs = false) if !pre_backtrack diff --git a/src/util.jl b/src/util.jl index 26c00ffa..434896f2 100644 --- a/src/util.jl +++ b/src/util.jl @@ -371,7 +371,3 @@ function view_changes(v::Variable, step_nr::Int) idx_end = v.changes.indices[step_nr+1]-1 return @views v.changes.changes[idx_begin:idx_end] end - -function changed!(com::CS.CoM, constraint::Constraint, fct, set) - return -end \ No newline at end of file diff --git a/test/unit/constraints/and.jl b/test/unit/constraints/and.jl index 882703b7..fc179baf 100644 --- a/test/unit/constraints/and.jl +++ b/test/unit/constraints/and.jl @@ -162,7 +162,6 @@ end constr_indices = constraint.indices @test CS.fix!(com, variables[constraint.indices[3]], 0; check_feasibility = false) - CS.changed!(com, constraint, constraint.fct, constraint.set) @test !CS.prune_constraint!(com, constraint, constraint.fct, constraint.set) end diff --git a/test/unit/constraints/complement.jl b/test/unit/constraints/complement.jl index cf5bfcd7..66b7f7d1 100644 --- a/test/unit/constraints/complement.jl +++ b/test/unit/constraints/complement.jl @@ -9,7 +9,6 @@ constraint = com.constraints[1] @test CS.fix!(com, variables[constraint.indices[1]], 1; check_feasibility = false) @test CS.fix!(com, variables[constraint.indices[2]], 2; check_feasibility = false) - CS.changed!(com, constraint, constraint.fct, constraint.set) @test CS.is_constraint_solved(com, constraint, constraint.fct, constraint.set) ################# @@ -24,7 +23,6 @@ constraint = com.constraints[1] @test CS.fix!(com, variables[constraint.indices[1]], 1; check_feasibility = false) @test CS.fix!(com, variables[constraint.indices[2]], 1; check_feasibility = false) - CS.changed!(com, constraint, constraint.fct, constraint.set) @test CS.is_constraint_solved(com, constraint, constraint.fct, constraint.set) ################# @@ -41,7 +39,6 @@ xor_constraint = com.constraints[1].inner_constraint @test CS.fix!(com, variables[xor_constraint.indices[1]], 0; check_feasibility = false) @test CS.fix!(com, variables[xor_constraint.indices[2]], 2; check_feasibility = false) - CS.changed!(com, xor_constraint, xor_constraint.fct, xor_constraint.set) @test CS.is_constraint_solved(com, xor_constraint, xor_constraint.fct, xor_constraint.set) ################# @@ -58,7 +55,6 @@ xor_constraint = com.constraints[1].inner_constraint @test CS.fix!(com, variables[xor_constraint.indices[1]], 0; check_feasibility = false) @test CS.fix!(com, variables[xor_constraint.indices[2]], 2; check_feasibility = false) - CS.changed!(com, xor_constraint, xor_constraint.fct, xor_constraint.set) @test CS.is_constraint_solved(com, xor_constraint, xor_constraint.fct, xor_constraint.set) diff --git a/test/unit/constraints/less_than.jl b/test/unit/constraints/less_than.jl index e9e4ab45..3520ff49 100644 --- a/test/unit/constraints/less_than.jl +++ b/test/unit/constraints/less_than.jl @@ -73,7 +73,6 @@ @test sort(CS.values(com.search_space[3])) == -4:5 @test CS.fix!(com, com.search_space[constr_indices[3]], -4) - CS.changed!(com, constraint, constraint.fct, constraint.set) @test CS.prune_constraint!(com, constraint, constraint.fct, constraint.set) @test CS.value(com.search_space[1]) == -1 @test CS.value(com.search_space[2]) == -1 diff --git a/test/unit/constraints/or.jl b/test/unit/constraints/or.jl index da720ae8..70067380 100644 --- a/test/unit/constraints/or.jl +++ b/test/unit/constraints/or.jl @@ -165,7 +165,6 @@ end constr_indices = constraint.indices @test CS.fix!(com, variables[constraint.indices[2]], 0; check_feasibility = false) - CS.changed!(com, constraint, constraint.fct, constraint.set) @test CS.prune_constraint!(com, constraint, constraint.fct, constraint.set) for v in 0:2 @test !CS.has(variables[constraint.indices[3]], v) @@ -185,7 +184,6 @@ end constr_indices = constraint.indices @test CS.fix!(com, variables[constraint.indices[2]], 0; check_feasibility = false) - CS.changed!(com, constraint, constraint.fct, constraint.set) @test CS.prune_constraint!(com, constraint, constraint.fct, constraint.set) for v in 0:2 @test !CS.has(variables[constraint.indices[4]], v) diff --git a/test/unit/constraints/reified.jl b/test/unit/constraints/reified.jl index 539769dd..c9ed0f72 100644 --- a/test/unit/constraints/reified.jl +++ b/test/unit/constraints/reified.jl @@ -254,7 +254,6 @@ end @test CS.fix!(com, variables[constr_indices[1]], 0; check_feasibility = false) @test CS.fix!(com, variables[constr_indices[2]], 0; check_feasibility = false) @test CS.fix!(com, variables[constr_indices[3]], 5; check_feasibility = false) - CS.changed!(com, constraint, constraint.fct, constraint.set) # should prune complement @test CS.prune_constraint!(com, constraint, constraint.fct, constraint.set) diff --git a/test/unit/constraints/strictly_less_than.jl b/test/unit/constraints/strictly_less_than.jl index 53704903..30307ead 100644 --- a/test/unit/constraints/strictly_less_than.jl +++ b/test/unit/constraints/strictly_less_than.jl @@ -73,7 +73,6 @@ @test sort(CS.values(com.search_space[3])) == -5:5 # 6 not possible @test CS.fix!(com, com.search_space[constr_indices[3]], 5) - CS.changed!(com, constraint, constraint.fct, constraint.set) @test CS.prune_constraint!(com, constraint, constraint.fct, constraint.set) @test CS.value(com.search_space[1]) == -1 @test CS.value(com.search_space[2]) == -1 @@ -200,7 +199,6 @@ end @test sort(CS.values(com.search_space[3])) == -5:6 # -6 not possible @test CS.fix!(com, com.search_space[constr_indices[3]], -5) - CS.changed!(com, constraint, constraint.fct, constraint.set) @test CS.prune_constraint!(com, constraint, constraint.fct, constraint.set) @test CS.value(com.search_space[1]) == -5 @test CS.value(com.search_space[2]) == 5 diff --git a/test/unit/constraints/xnor.jl b/test/unit/constraints/xnor.jl index ca747a09..6af0bb48 100644 --- a/test/unit/constraints/xnor.jl +++ b/test/unit/constraints/xnor.jl @@ -180,7 +180,6 @@ end constr_indices = constraint.indices @test CS.fix!(com, variables[constraint.indices[3]], 0; check_feasibility = false) - CS.changed!(com, constraint, constraint.fct, constraint.set) @test CS.prune_constraint!(com, constraint, constraint.fct, constraint.set) @test sort(CS.values(m, x[1])) == [0,1,2] end diff --git a/test/unit/constraints/xor.jl b/test/unit/constraints/xor.jl index 3c4235ad..d56a678b 100644 --- a/test/unit/constraints/xor.jl +++ b/test/unit/constraints/xor.jl @@ -148,7 +148,6 @@ end xor_constraint = com.constraints[1].inner_constraint @test CS.fix!(com, variables[xor_constraint.indices[1]], 0; check_feasibility = false) @test CS.fix!(com, variables[xor_constraint.indices[2]], 2; check_feasibility = false) - CS.changed!(com, xor_constraint, xor_constraint.fct, xor_constraint.set) @test CS.is_constraint_violated(com, xor_constraint, xor_constraint.fct, xor_constraint.set) ################## @@ -181,7 +180,6 @@ end constr_indices = constraint.indices @test CS.fix!(com, variables[constraint.indices[3]], 0; check_feasibility = false) - CS.changed!(com, constraint, constraint.fct, constraint.set) @test CS.prune_constraint!(com, constraint, constraint.fct, constraint.set) @test sort(CS.values(m, x[1])) == [3,4,5] end From c6a610287d63dc828837993fdc00d25c2d6f0c3b Mon Sep 17 00:00:00 2001 From: Ole Kroeger Date: Sun, 1 Aug 2021 16:24:51 +0200 Subject: [PATCH 02/10] notify_constraints_var_changed! & changed_var! --- src/Variable.jl | 2 + src/constraints.jl | 20 ++++++++ src/constraints/activator_constraints.jl | 22 ++++++--- src/constraints/boolset.jl | 13 +++++ src/constraints/indicator.jl | 11 +++++ src/constraints/linear_constraints.jl | 62 ++++++++++++++++++++++-- src/constraints/reified.jl | 15 ++++++ src/type_inits.jl | 6 +++ src/types.jl | 6 ++- src/util.jl | 2 + test/small_special.jl | 1 + 11 files changed, 149 insertions(+), 11 deletions(-) diff --git a/src/Variable.jl b/src/Variable.jl index 6d125322..4a8ade04 100644 --- a/src/Variable.jl +++ b/src/Variable.jl @@ -91,6 +91,7 @@ function rm!( end changes && push_to_changes!(v, (:rm, x, 0, 1)) end + notify_constraints_var_changed!(com, v.idx) return true end @@ -108,6 +109,7 @@ function fix!(com::CS.CoM, v::CS.Variable, x::Int; changes = true, check_feasibi v.first_ptr = vidx v.min = x v.max = x + notify_constraints_var_changed!(com, v.idx) return true end diff --git a/src/constraints.jl b/src/constraints.jl index e20c243e..1b6b47c3 100644 --- a/src/constraints.jl +++ b/src/constraints.jl @@ -294,3 +294,23 @@ function get_two_unfixed(com::CS.CoM, constraint::Constraint) end return local_vidx_1, vidx_1, local_vidx_2, vidx_2 end + +""" + notify_constraints_var_changed!(com, vidx::Int) + +Notify all constraints that the domain of `vidx` changed. Calls [`changed_var!`](@ref) +""" +function notify_constraints_var_changed!(com::CS.CoM, vidx::Int) + constraints = com.constraints + for ci in com.subscription[vidx] + constraint = constraints[ci] + changed_var!(com, constraint, constraint.fct, constraint.set, vidx) + end +end + +""" + changed_var!(com::CS.CoM, connstraint::Constraint, fct, set, vidx) + +This method needs to be implemented by the constraint when it needs to update something when a variable changed +""" +changed_var!(com::CS.CoM, constraint::Constraint, fct, set, vidx) = nothing \ No newline at end of file diff --git a/src/constraints/activator_constraints.jl b/src/constraints/activator_constraints.jl index 5d7e3843..62e63255 100644 --- a/src/constraints/activator_constraints.jl +++ b/src/constraints/activator_constraints.jl @@ -22,10 +22,10 @@ Saves at which stage it was activated. """ function activate_complement_inner!(com, constraint::ActivatorConstraint) complement_constraint = constraint.complement_constraint - if !constraint.complement_inner_constraint && complement_constraint.impl.activate + if !constraint.complement_activated && complement_constraint.impl.activate !activate_constraint!(com, complement_constraint, complement_constraint.fct, complement_constraint.set) && return false - constraint.complement_inner_constraint = true - constraint.complement_inner_constraint_in_backtrack_idx = com.c_backtrack_idx + constraint.complement_activated = true + constraint.complement_activated_in_backtrack_idx = com.c_backtrack_idx end return true end @@ -122,9 +122,19 @@ function reverse_pruning_constraint!( constraint.inner_activated_in_backtrack_idx = 0 end if constraint isa ReifiedConstraint - if constraint.complement_inner_constraint && backtrack_id == constraint.complement_inner_constraint_in_backtrack_idx - constraint.complement_inner_constraint = false - constraint.complement_inner_constraint_in_backtrack_idx = 0 + if constraint.complement_activated && backtrack_id == constraint.complement_activated_in_backtrack_idx + constraint.complement_activated = false + constraint.complement_activated_in_backtrack_idx = 0 + end + complement_constraint = constraint.complement_constraint + if complement_constraint !== nothing && complement_constraint.impl.reverse_pruning + reverse_pruning_constraint!( + com, + complement_constraint, + complement_constraint.fct, + complement_constraint.set, + backtrack_id, + ) end end diff --git a/src/constraints/boolset.jl b/src/constraints/boolset.jl index af696b32..92dfd54e 100644 --- a/src/constraints/boolset.jl +++ b/src/constraints/boolset.jl @@ -298,3 +298,16 @@ function finished_pruning_constraint!( end end end + +function changed_var!( + com::CS.CoM, + constraint::BoolConstraint, + fct, + set, + vidx::Int +) where {T<:Real} + lhs = constraint.lhs + changed_var!(com, lhs, lhs.fct, lhs.set, vidx) + rhs = constraint.rhs + changed_var!(com, rhs, rhs.fct, rhs.set, vidx) +end diff --git a/src/constraints/indicator.jl b/src/constraints/indicator.jl index 40129612..5791c43c 100644 --- a/src/constraints/indicator.jl +++ b/src/constraints/indicator.jl @@ -231,3 +231,14 @@ function is_constraint_violated( end return false end + +function changed_var!( + com::CS.CoM, + constraint::IndicatorConstraint, + fct, + set, + vidx::Int +) where {T<:Real} + inner_constraint = constraint.inner_constraint + changed_var!(com, inner_constraint, inner_constraint.fct, inner_constraint.set, vidx) +end \ No newline at end of file diff --git a/src/constraints/linear_constraints.jl b/src/constraints/linear_constraints.jl index 83198e51..b65bc084 100644 --- a/src/constraints/linear_constraints.jl +++ b/src/constraints/linear_constraints.jl @@ -180,6 +180,49 @@ function recompute_lc_extrema!( end end +""" + changed_var!( + com::CS.CoM, + constraint::LinearConstraint, + fct::SAF{T}, + set, + vidx::Int + ) where {T<:Real} + +Update constraint.maxs, mins, pre_maxs and pre_mins for the changed var +""" +function changed_var!( + com::CS.CoM, + constraint::LinearConstraint, + fct::SAF{T}, + set, + vidx::Int +) where {T<:Real} + constraint.currently_pruning && return + if get(constraint.vidx_to_idx, vidx, nothing) === nothing + return + end + search_space = com.search_space + maxs = constraint.maxs + mins = constraint.mins + pre_maxs = constraint.pre_maxs + pre_mins = constraint.pre_mins + + idx = constraint.vidx_to_idx[vidx] + if fct.terms[idx].coefficient >= 0 + max_val = search_space[vidx].max * fct.terms[idx].coefficient + min_val = search_space[vidx].min * fct.terms[idx].coefficient + else + min_val = search_space[vidx].max * fct.terms[idx].coefficient + max_val = search_space[vidx].min * fct.terms[idx].coefficient + end + maxs[idx] = max_val + mins[idx] = min_val + pre_maxs[idx] = max_val + pre_mins[idx] = min_val +end + + """ get_fixed_rhs(com::CS.CoM, constraint::Constraint) @@ -217,13 +260,26 @@ function set_new_extrema(i, pre_mins, pre_maxs, new_min, new_max) return changed end +function prune_constraint!( + com::CS.CoM, + constraint::LinearConstraint, + fct::SAF{T}, + set::Union{MOI.LessThan, MOI.EqualTo, Strictly{T, MOI.LessThan{T}}}; + logs = true, +) where {T<:Real} + constraint.currently_pruning = true + isfeasible = _prune_constraint!(com, constraint, fct, set; logs=logs) + constraint.currently_pruning = false + return isfeasible +end + """ - prune_constraint!(com::CS.CoM, constraint::LinearConstraint, fct::SAF{T}, set::MOI.EqualTo{T}; logs = true) where T <: Real + _prune_constraint!(com::CS.CoM, constraint::LinearConstraint, fct::SAF{T}, set::MOI.EqualTo{T}; logs = true) where T <: Real Reduce the number of possibilities given the equality `LinearConstraint` . Return if still feasible and throw a warning if infeasible and `logs` is set to `true` """ -function prune_constraint!( +function _prune_constraint!( com::CS.CoM, constraint::LinearConstraint, fct::SAF{T}, @@ -635,6 +691,6 @@ function reverse_pruning_constraint!( fct::SAF{T}, set::Union{MOI.LessThan, MOI.EqualTo, Strictly{T, MOI.LessThan{T}}}, backtrack_id::Int, -) where {T <: Real} +) where {T <: Real} recompute_lc_extrema!(com, constraint, fct) end \ No newline at end of file diff --git a/src/constraints/reified.jl b/src/constraints/reified.jl index ed849da1..1f80f085 100644 --- a/src/constraints/reified.jl +++ b/src/constraints/reified.jl @@ -207,3 +207,18 @@ function is_constraint_violated( end return false end + +function changed_var!( + com::CS.CoM, + constraint::ReifiedConstraint, + fct, + set, + vidx::Int +) where {T<:Real} + inner_constraint = constraint.inner_constraint + changed_var!(com, inner_constraint, inner_constraint.fct, inner_constraint.set, vidx) + if constraint.complement_constraint !== nothing + complement_constraint = constraint.complement_constraint + changed_var!(com, complement_constraint, complement_constraint.fct, complement_constraint.set, vidx) + end +end \ No newline at end of file diff --git a/src/type_inits.jl b/src/type_inits.jl index 0c876c5a..094c1eb1 100644 --- a/src/type_inits.jl +++ b/src/type_inits.jl @@ -24,10 +24,15 @@ MatchingInit() = MatchingInit(0, Int[], Int[], Int[], Int[], Int[], Int[], Bool[ SCCInit() = SCCInit(Int[], Int[], Int[], Bool[], Int[]) function ConstraintInternals(cidx::Int, fct, set, indices::Vector{Int}) + vidx_to_idx = Dict{Int, Int}() + for (idx,vidx) in enumerate(indices) + vidx_to_idx[vidx] = idx + end return ConstraintInternals( cidx, fct, set, + vidx_to_idx, indices, Int[], ImplementedConstraintFunctions(), @@ -96,6 +101,7 @@ function LinearConstraint( # the rhs is filled in init_constraint lc = LinearConstraint( internals, + false, in_all_different, is_strict, is_equal, diff --git a/src/types.jl b/src/types.jl index 1c6bcaf0..7ed4da87 100644 --- a/src/types.jl +++ b/src/types.jl @@ -404,6 +404,7 @@ mutable struct ConstraintInternals{ idx::Int fct::FCT set::SET + vidx_to_idx::Dict{Int,Int} indices::Vector{Int} pvals::Vector{Int} impl::ImplementedConstraintFunctions @@ -483,6 +484,7 @@ end mutable struct LinearConstraint{T<:Real} <: Constraint std::ConstraintInternals + currently_pruning::Bool # whether this constraint is currently in pruning in_all_different::Bool is_strict::Bool # for differentiate between < and <= is_equal::Bool # for == @@ -542,8 +544,8 @@ mutable struct ReifiedConstraint{C<:Constraint, AC<:Union{Constraint,Nothing}} < act_std::ActivatorConstraintInternals inner_constraint::C complement_constraint::AC - complement_inner_constraint::Bool - complement_inner_constraint_in_backtrack_idx::Int + complement_activated::Bool + complement_activated_in_backtrack_idx::Int end #==================================================================================== diff --git a/src/util.jl b/src/util.jl index 434896f2..577249e1 100644 --- a/src/util.jl +++ b/src/util.jl @@ -132,6 +132,7 @@ end :indices, :fct, :set, + :vidx_to_idx, :pvals, :impl, :is_initialized, @@ -151,6 +152,7 @@ end :indices, :fct, :set, + :vidx_to_idx, :pvals, :impl, :is_initialized, diff --git a/test/small_special.jl b/test/small_special.jl index 1689c30f..c2c48b10 100644 --- a/test/small_special.jl +++ b/test/small_special.jl @@ -584,6 +584,7 @@ )) @variable(model, b >= 1, Bin) @variable(model, 0 <= x[1:4] <= 5, Int) + @constraint(model, x[1] <= x[3]) @constraint(model, b => {sum([0.4,0.5,0.7,0.8] .* x) > 9}) @objective(model, Min, sum([0.4,0.5,0.7,0.8] .* x)) optimize!(model) From c1b91ac19e0545d5ab5394f2ee577f9bb4c1b055 Mon Sep 17 00:00:00 2001 From: Ole Kroeger Date: Sun, 15 Aug 2021 17:03:10 +0200 Subject: [PATCH 03/10] Strictly fixed --- src/constraints/linear_constraints.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/constraints/linear_constraints.jl b/src/constraints/linear_constraints.jl index 68930a96..52a9b952 100644 --- a/src/constraints/linear_constraints.jl +++ b/src/constraints/linear_constraints.jl @@ -270,7 +270,7 @@ function prune_constraint!( com::CS.CoM, constraint::LinearConstraint, fct::SAF{T}, - set::Union{MOI.LessThan, MOI.EqualTo, Strictly{T, MOI.LessThan{T}}}; + set::Union{MOI.LessThan, MOI.EqualTo, CPE.Strictly{MOI.LessThan{T}}}; logs = true, ) where {T<:Real} constraint.currently_pruning = true From db9eb943ac873955b648acc050709ea96f0cadb7 Mon Sep 17 00:00:00 2001 From: Ole Kroeger Date: Mon, 16 Aug 2021 17:05:29 +0200 Subject: [PATCH 04/10] testing inner_pruned check but failing... --- src/MOI_wrapper/util.jl | 2 +- src/constraints/activator_constraints.jl | 2 ++ src/constraints/indicator.jl | 1 + src/constraints/linear_constraints.jl | 10 ++++++++++ src/constraints/reified.jl | 2 ++ src/type_inits.jl | 2 +- src/types.jl | 2 ++ src/util.jl | 2 ++ 8 files changed, 21 insertions(+), 2 deletions(-) diff --git a/src/MOI_wrapper/util.jl b/src/MOI_wrapper/util.jl index 21d04d12..22f107c9 100644 --- a/src/MOI_wrapper/util.jl +++ b/src/MOI_wrapper/util.jl @@ -97,7 +97,7 @@ function get_inner_constraint(com, vars::MOI.VectorOfVariables, set::Union{Reifi end function get_activator_internals(A, indices) - ActivatorConstraintInternals(A, indices[1] in indices[2:end], false, 0) + ActivatorConstraintInternals(A, indices[1] in indices[2:end], false, 0, false) end """ diff --git a/src/constraints/activator_constraints.jl b/src/constraints/activator_constraints.jl index 62e63255..55d305b5 100644 --- a/src/constraints/activator_constraints.jl +++ b/src/constraints/activator_constraints.jl @@ -135,6 +135,7 @@ function reverse_pruning_constraint!( complement_constraint.set, backtrack_id, ) + constraint.complement_pruned = false end end @@ -147,6 +148,7 @@ function reverse_pruning_constraint!( inner_constraint.set, backtrack_id, ) + constraint.inner_pruned = false end end diff --git a/src/constraints/indicator.jl b/src/constraints/indicator.jl index 5791c43c..e225a6b4 100644 --- a/src/constraints/indicator.jl +++ b/src/constraints/indicator.jl @@ -82,6 +82,7 @@ function prune_constraint!( # check if active CS.value(indicator_var) != Int(constraint.activate_on) && return true !activate_inner!(com, constraint) && return false + constraint.inner_pruned = true return prune_constraint!( com, inner_constraint, diff --git a/src/constraints/linear_constraints.jl b/src/constraints/linear_constraints.jl index 52a9b952..8675b387 100644 --- a/src/constraints/linear_constraints.jl +++ b/src/constraints/linear_constraints.jl @@ -693,4 +693,14 @@ function reverse_pruning_constraint!( backtrack_id::Int, ) where {T <: Real} recompute_lc_extrema!(com, constraint, fct) +end + +function activate_constraint!( + com::CoM, + constraint::LinearConstraint, + fct::SAF{T}, + set::Union{MOI.LessThan, MOI.EqualTo, CPE.Strictly{MOI.LessThan{T}}}, +) where {T <: Real} + recompute_lc_extrema!(com, constraint, fct) + return true end \ No newline at end of file diff --git a/src/constraints/reified.jl b/src/constraints/reified.jl index 1f80f085..1a0302b7 100644 --- a/src/constraints/reified.jl +++ b/src/constraints/reified.jl @@ -65,6 +65,7 @@ function prune_constraint!( # 3 if issetto(variables[rei_vidx], activate_on) + constraint.inner_pruned = true !activate_inner!(com, constraint) && return false return prune_constraint!( com, @@ -74,6 +75,7 @@ function prune_constraint!( ) # 4 elseif issetto(variables[rei_vidx], activate_off) && complement_constraint !== nothing + constraint.complement_pruned = true !activate_complement_inner!(com, constraint) && return false return prune_constraint!( com, diff --git a/src/type_inits.jl b/src/type_inits.jl index f6ec6386..05ce18cb 100644 --- a/src/type_inits.jl +++ b/src/type_inits.jl @@ -118,7 +118,7 @@ function LinearConstraint( end function ReifiedConstraint(std, act_std, inner_constraint, complement_constraint) - return ReifiedConstraint(std, act_std, inner_constraint, complement_constraint, false, 0) + return ReifiedConstraint(std, act_std, inner_constraint, complement_constraint, false, 0, false) end """ diff --git a/src/types.jl b/src/types.jl index 4617830e..b06ca5e6 100644 --- a/src/types.jl +++ b/src/types.jl @@ -499,6 +499,7 @@ mutable struct ActivatorConstraintInternals activator_in_inner::Bool inner_activated::Bool inner_activated_in_backtrack_idx::Int + inner_pruned::Bool end mutable struct IndicatorConstraint{C<:Constraint} <: ActivatorConstraint @@ -514,6 +515,7 @@ mutable struct ReifiedConstraint{C<:Constraint, AC<:Union{Constraint,Nothing}} < complement_constraint::AC complement_activated::Bool complement_activated_in_backtrack_idx::Int + complement_pruned::Bool end #==================================================================================== diff --git a/src/util.jl b/src/util.jl index 577249e1..9988e72d 100644 --- a/src/util.jl +++ b/src/util.jl @@ -188,6 +188,7 @@ end :activator_in_inner, :inner_activated, :inner_activated_in_backtrack_idx, + :inner_pruned, ) Core.getproperty(Core.getproperty(c, :act_std), s) else @@ -214,6 +215,7 @@ end :activator_in_inner, :inner_activated, :inner_activated_in_backtrack_idx, + :inner_pruned, ) Core.setproperty!(c.act_std, s, v) else From a715e0734dc2fec7f296ae6c6c92dcf6b32e5262 Mon Sep 17 00:00:00 2001 From: Ole Kroeger Date: Sat, 21 Aug 2021 20:04:08 +0200 Subject: [PATCH 05/10] merge fixes --- src/constraints.jl | 4 ++-- src/constraints/activator_constraints.jl | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/constraints.jl b/src/constraints.jl index 9ec8d4ad..53a80d4f 100644 --- a/src/constraints.jl +++ b/src/constraints.jl @@ -78,7 +78,7 @@ end """ call_finished_pruning!(com) -Call `finished_pruning_constraint!` for every constraint which implements that function as saved in `constraint.impl.finished_pruning` +Call `finished_pruning_constraint!` for every constraint. """ function call_finished_pruning!(com) for constraint in com.constraints @@ -89,7 +89,7 @@ end """ call_restore_pruning!(com, prune_steps) -Call `call_restore_pruning!` for every constraint which implements that function as saved in `constraint.impl.restore_pruning` +Call `call_restore_pruning!` for every constraint. """ function call_restore_pruning!(com, prune_steps) for constraint in com.constraints diff --git a/src/constraints/activator_constraints.jl b/src/constraints/activator_constraints.jl index 07673d94..8fdb662d 100644 --- a/src/constraints/activator_constraints.jl +++ b/src/constraints/activator_constraints.jl @@ -123,7 +123,7 @@ function reverse_pruning_constraint!( constraint.complement_activated_in_backtrack_idx = 0 end complement_constraint = constraint.complement_constraint - if complement_constraint !== nothing && complement_constraint.impl.reverse_pruning + if complement_constraint !== nothing reverse_pruning_constraint!( com, complement_constraint, From 9afa65cc0c0236c18a50bc10d4d4d9477e0c039f Mon Sep 17 00:00:00 2001 From: Ole Kroeger Date: Sun, 22 Aug 2021 21:59:52 +0200 Subject: [PATCH 06/10] set_first_node_call! in prune, feasible, solved, violated --- src/ConstraintSolver.jl | 2 +- src/MOI_wrapper/util.jl | 2 +- src/constraints.jl | 66 ++++++++++++++++++++ src/constraints/activator_constraints.jl | 2 - src/constraints/all_different.jl | 17 +++--- src/constraints/all_equal.jl | 17 +++--- src/constraints/and.jl | 22 +++---- src/constraints/boolset.jl | 26 +++++--- src/constraints/geqset.jl | 22 ++++--- src/constraints/indicator.jl | 43 ++++++------- src/constraints/linear_constraints.jl | 57 ++++++++--------- src/constraints/not_equal.jl | 20 +++--- src/constraints/or.jl | 30 ++++----- src/constraints/reified.jl | 46 ++++++-------- src/constraints/svc.jl | 24 +++++--- src/constraints/table.jl | 21 +++---- src/constraints/xnor.jl | 55 ++++++++++------- src/constraints/xor.jl | 55 ++++++++++------- src/pruning.jl | 6 +- src/type_inits.jl | 3 +- src/types.jl | 7 +-- src/util.jl | 21 ++++--- test/constraints/table.jl | 16 ----- test/general.jl | 4 +- test/small_special.jl | 12 ++-- test/unit/constraints/alldifferent.jl | 44 ++++++------- test/unit/constraints/and.jl | 26 ++++---- test/unit/constraints/complement.jl | 20 +++--- test/unit/constraints/equal.jl | 26 +++----- test/unit/constraints/equal_to.jl | 20 ++---- test/unit/constraints/geqset.jl | 24 +++----- test/unit/constraints/indicator.jl | 24 +++----- test/unit/constraints/less_than.jl | 20 ++---- test/unit/constraints/not_equal.jl | 18 ++---- test/unit/constraints/or.jl | 28 ++++----- test/unit/constraints/reified.jl | 44 +++++-------- test/unit/constraints/strictly_less_than.jl | 68 ++++++++------------- test/unit/constraints/svc.jl | 24 +++----- test/unit/constraints/table.jl | 18 ++---- test/unit/constraints/xnor.jl | 48 +++++++-------- test/unit/constraints/xor.jl | 36 +++++------ 41 files changed, 533 insertions(+), 551 deletions(-) diff --git a/src/ConstraintSolver.jl b/src/ConstraintSolver.jl index 10a5b51a..c556bca0 100644 --- a/src/ConstraintSolver.jl +++ b/src/ConstraintSolver.jl @@ -118,7 +118,7 @@ function fulfills_constraints(com::CS.CoM, vidx, value) # only call if the function got initialized already if constraint.is_initialized feasible = - still_feasible(com, constraint, constraint.fct, constraint.set, vidx, value) + still_feasible(com, constraint, vidx, value) !feasible && break end end diff --git a/src/MOI_wrapper/util.jl b/src/MOI_wrapper/util.jl index 22f107c9..21d04d12 100644 --- a/src/MOI_wrapper/util.jl +++ b/src/MOI_wrapper/util.jl @@ -97,7 +97,7 @@ function get_inner_constraint(com, vars::MOI.VectorOfVariables, set::Union{Reifi end function get_activator_internals(A, indices) - ActivatorConstraintInternals(A, indices[1] in indices[2:end], false, 0, false) + ActivatorConstraintInternals(A, indices[1] in indices[2:end], false, 0) end """ diff --git a/src/constraints.jl b/src/constraints.jl index 53a80d4f..9af22de3 100644 --- a/src/constraints.jl +++ b/src/constraints.jl @@ -327,3 +327,69 @@ function update_init_constraint!( return true end +set_first_node_call!(constraint::Constraint, val::Bool) = constraint.first_node_call = val + +function prune_constraint!( + com::CS.CoM, + constraint::Constraint; + logs = false +) + check_first_node_call!(com, constraint) + feasible = _prune_constraint!(com, constraint, constraint.fct, constraint.set; logs = logs) + constraint.first_node_call = false + return feasible +end + +function still_feasible( + com::CoM, + constraint::Constraint, + vidx::Int, + value::Int, +) + check_first_node_call!(com, constraint) + feasible = _still_feasible(com, constraint, constraint.fct, constraint.set, vidx, value) + constraint.first_node_call = false + return feasible +end + +function is_constraint_violated( + com::CoM, + constraint::Constraint, +) + check_first_node_call!(com, constraint) + violated = _is_constraint_violated(com, constraint, constraint.fct, constraint.set) + constraint.first_node_call = false + return violated +end + +function is_constraint_solved(com::CS.CoM, constraint::Constraint) + check_first_node_call!(com, constraint) + solved = _is_constraint_solved(com, constraint, constraint.fct, constraint.set) + constraint.first_node_call = false + return solved +end + +function _is_constraint_solved(com::CS.CoM, constraint::Constraint, fct, set) + variables = com.search_space + !all(isfixed(variables[ind]) for ind in constraint.indices) && return false + values = CS.value.(variables[constraint.indices]) + return _is_constraint_solved(com, constraint, constraint.fct, constraint.set, values) +end + +function is_constraint_solved( + com::CS.CoM, + constraint::Constraint, + values::Vector{Int}, +) + check_first_node_call!(com, constraint) + solved = _is_constraint_solved(com, constraint, constraint.fct, constraint.set, values) + constraint.first_node_call = false + return solved +end + +function check_first_node_call!(com, constraint::Constraint) + !constraint.first_node_call && return + first_node_call!(com, constraint, constraint.fct, constraint.set) +end + +first_node_call!(::CS.CoM, ::Constraint, fct, set) = nothing \ No newline at end of file diff --git a/src/constraints/activator_constraints.jl b/src/constraints/activator_constraints.jl index 8fdb662d..9fbc9869 100644 --- a/src/constraints/activator_constraints.jl +++ b/src/constraints/activator_constraints.jl @@ -131,7 +131,6 @@ function reverse_pruning_constraint!( complement_constraint.set, backtrack_id, ) - constraint.complement_pruned = false end end @@ -143,7 +142,6 @@ function reverse_pruning_constraint!( inner_constraint.set, backtrack_id, ) - constraint.inner_pruned = false end function restore_pruning_constraint!( diff --git a/src/constraints/all_different.jl b/src/constraints/all_different.jl index a7c55f91..adaa14f2 100644 --- a/src/constraints/all_different.jl +++ b/src/constraints/all_different.jl @@ -206,17 +206,17 @@ function update_best_bound_constraint!( end """ - prune_constraint!(com::CS.CoM, constraint::AllDifferentConstraint, fct::MOI.VectorOfVariables, set::CPE.AllDifferent; logs = true) + _prune_constraint!(com::CS.CoM, constraint::AllDifferentConstraint, fct::MOI.VectorOfVariables, set::CPE.AllDifferent; logs = false) Reduce the number of possibilities given the `AllDifferentConstraint`. Return whether still feasible and throws a warning if infeasible and `logs` is set to `true` """ -function prune_constraint!( +function _prune_constraint!( com::CS.CoM, constraint::AllDifferentConstraint, fct::MOI.VectorOfVariables, set::CPE.AllDifferent; - logs = true, + logs = false, ) indices = constraint.indices pvals = constraint.pvals @@ -436,12 +436,12 @@ function prune_constraint!( end """ - still_feasible(com::CoM, constraint::AllDifferentConstraint, fct::MOI.VectorOfVariables, set::CPE.AllDifferent, vidx::Int, value::Int) + _still_feasible(com::CoM, constraint::AllDifferentConstraint, fct::MOI.VectorOfVariables, set::CPE.AllDifferent, vidx::Int, value::Int) Return whether the constraint can be still fulfilled when setting a variable with index `vidx` to `value`. **Attention:** This assumes that it isn't violated before. """ -function still_feasible( +function _still_feasible( com::CoM, constraint::AllDifferentConstraint, fct::MOI.VectorOfVariables, @@ -461,7 +461,8 @@ function still_feasible( return true end -function is_constraint_solved( +function _is_constraint_solved( + com, constraint::AllDifferentConstraint, fct::MOI.VectorOfVariables, set::CPE.AllDifferent, @@ -471,7 +472,7 @@ function is_constraint_solved( end """ - is_constraint_violated( + _is_constraint_violated( com::CoM, constraint::AllDifferentConstraint, fct::MOI.VectorOfVariables, @@ -481,7 +482,7 @@ end Checks if the constraint is violated as it is currently set. This can happen inside an inactive reified or indicator constraint. """ -function is_constraint_violated( +function _is_constraint_violated( com::CoM, constraint::AllDifferentConstraint, fct::MOI.VectorOfVariables, diff --git a/src/constraints/all_equal.jl b/src/constraints/all_equal.jl index efbb9806..3ff92a9f 100644 --- a/src/constraints/all_equal.jl +++ b/src/constraints/all_equal.jl @@ -47,17 +47,17 @@ function apply_changes!( end """ - prune_constraint!(com::CS.CoM, constraint::EqualConstraint, fct::MOI.VectorOfVariables, set::CPE.AllEqual; logs = true) + _prune_constraint!(com::CS.CoM, constraint::EqualConstraint, fct::MOI.VectorOfVariables, set::CPE.AllEqual; logs = false) Reduce the number of possibilities given the equality constraint which sets all variables in `MOI.VectorOfVariables` to the same value. Return if still feasible and throw a warning if infeasible and `logs` is set to `true` """ -function prune_constraint!( +function _prune_constraint!( com::CS.CoM, constraint::EqualConstraint, fct::MOI.VectorOfVariables, set::CPE.AllEqual; - logs = true, + logs = false, ) indices = constraint.indices @@ -155,11 +155,11 @@ function finished_pruning_constraint!( end """ - still_feasible(com::CoM, constraint::EqualConstraint, fct::MOI.VectorOfVariables, set::CPE.AllEqual, vidx::Int, value::Int) + _still_feasible(com::CoM, constraint::EqualConstraint, fct::MOI.VectorOfVariables, set::CPE.AllEqual, vidx::Int, value::Int) Return whether the constraint can be still fulfilled. """ -function still_feasible( +function _still_feasible( com::CoM, constraint::EqualConstraint, fct::MOI.VectorOfVariables, @@ -178,7 +178,8 @@ function still_feasible( return true end -function is_constraint_solved( +function _is_constraint_solved( + com, constraint::EqualConstraint, fct::MOI.VectorOfVariables, set::CPE.AllEqual, @@ -188,7 +189,7 @@ function is_constraint_solved( end """ - is_constraint_violated( + _is_constraint_violated( com::CoM, constraint::EqualConstraint, fct::MOI.VectorOfVariables, @@ -198,7 +199,7 @@ end Checks if the constraint is violated as it is currently set. This can happen inside an inactive reified or indicator constraint. """ -function is_constraint_violated( +function _is_constraint_violated( com::CoM, constraint::EqualConstraint, fct::MOI.VectorOfVariables, diff --git a/src/constraints/and.jl b/src/constraints/and.jl index 9c55a7ef..88c5ba98 100644 --- a/src/constraints/and.jl +++ b/src/constraints/and.jl @@ -1,5 +1,5 @@ """ - function is_constraint_violated( + function _is_constraint_violated( com::CoM, constraint::BoolConstraint, fct, @@ -8,7 +8,7 @@ Check if one of the inner constraints is violated """ -function is_constraint_violated( +function _is_constraint_violated( com::CoM, constraint::BoolConstraint, fct, @@ -18,12 +18,12 @@ function is_constraint_violated( end """ - still_feasible(com::CoM, constraint::AndConstraint, fct, set::AndSet, vidx::Int, value::Int) + _still_feasible(com::CoM, constraint::AndConstraint, fct, set::AndSet, vidx::Int, value::Int) Return whether the constraint can be still fulfilled when setting a variable with index `vidx` to `value`. **Attention:** This assumes that it isn't violated before. """ -function still_feasible( +function _still_feasible( com::CoM, constraint::AndConstraint, fct, @@ -34,34 +34,34 @@ function still_feasible( lhs_indices = constraint.lhs.indices for i in 1:length(lhs_indices) if lhs_indices[i] == vidx - !still_feasible(com, constraint.lhs, constraint.lhs.fct, constraint.lhs.set, vidx, value) && return false + !still_feasible(com, constraint.lhs, vidx, value) && return false end end rhs_indices = constraint.rhs.indices for i in 1:length(rhs_indices) if rhs_indices[i] == vidx - !still_feasible(com, constraint.rhs, constraint.rhs.fct, constraint.rhs.set, vidx, value) && return false + !still_feasible(com, constraint.rhs, vidx, value) && return false end end return true end """ - prune_constraint!(com::CS.CoM, constraint::AndConstraint, fct, set::AndSet; logs = true) + _prune_constraint!(com::CS.CoM, constraint::AndConstraint, fct, set::AndSet; logs = false) Reduce the number of possibilities given the `AndConstraint` by pruning both parts Return whether still feasible """ -function prune_constraint!( +function _prune_constraint!( com::CS.CoM, constraint::AndConstraint, fct, set::AndSet; - logs = true, + logs = false, ) !activate_lhs!(com, constraint) && return false - !prune_constraint!(com, constraint.lhs, constraint.lhs.fct, constraint.lhs.set; logs=logs) && return false + !prune_constraint!(com, constraint.lhs; logs=logs) && return false !activate_rhs!(com, constraint) && return false - feasible = prune_constraint!(com, constraint.rhs, constraint.rhs.fct, constraint.rhs.set; logs=logs) + feasible = prune_constraint!(com, constraint.rhs; logs=logs) return feasible end \ No newline at end of file diff --git a/src/constraints/boolset.jl b/src/constraints/boolset.jl index 313e7359..52afd0f9 100644 --- a/src/constraints/boolset.jl +++ b/src/constraints/boolset.jl @@ -1,3 +1,9 @@ +function set_first_node_call!(constraint::BoolConstraint, val::Bool) + constraint.first_node_call = val + set_first_node_call!(constraint.lhs, val) + set_first_node_call!(constraint.rhs, val) +end + function init_constraint_struct(com, set::AbstractBoolSet{F1,F2}, internals) where {F1,F2} f = MOIU.eachscalar(internals.fct) @@ -123,7 +129,8 @@ function init_lhs_and_rhs!( end """ - is_constraint_solved( + _is_constraint_solved( + com, constraint::BoolConstraint, fct, set::AbstractBoolSet, @@ -132,31 +139,32 @@ end Check if the constraint is solved gived the `values` """ -function is_constraint_solved( +function _is_constraint_solved( + com, constraint::BoolConstraint, fct, set::AbstractBoolSet, values::Vector{Int}, ) - apply_bool_operator(typeof(set), lhs_solved, rhs_solved, constraint, values) + apply_bool_operator(typeof(set), lhs_solved, rhs_solved, com, constraint, values) end -function lhs_solved(constraint::BoolConstraint, values::Vector{Int}) +function lhs_solved(com, constraint::BoolConstraint, values::Vector{Int}) lhs_num_vars = get_num_vars(constraint.lhs.fct) - return is_constraint_solved(constraint.lhs, constraint.lhs.fct, constraint.lhs.set, values[1:lhs_num_vars]) + return is_constraint_solved(com, constraint.lhs, values[1:lhs_num_vars]) end -function rhs_solved(constraint::BoolConstraint, values::Vector{Int}) +function rhs_solved(com, constraint::BoolConstraint, values::Vector{Int}) rhs_num_vars = get_num_vars(constraint.rhs.fct) - return is_constraint_solved(constraint.rhs, constraint.rhs.fct, constraint.rhs.set, values[end-rhs_num_vars+1:end]) + return is_constraint_solved(com, constraint.rhs, values[end-rhs_num_vars+1:end]) end function is_lhs_constraint_violated(com, constraint) - is_constraint_violated(com, constraint.lhs, constraint.lhs.fct, constraint.lhs.set) + is_constraint_violated(com, constraint.lhs) end function is_rhs_constraint_violated(com, constraint) - is_constraint_violated(com, constraint.rhs, constraint.rhs.fct, constraint.rhs.set) + is_constraint_violated(com, constraint.rhs) end """ diff --git a/src/constraints/geqset.jl b/src/constraints/geqset.jl index 58c5541a..bb5b6ab3 100644 --- a/src/constraints/geqset.jl +++ b/src/constraints/geqset.jl @@ -44,12 +44,12 @@ function update_init_constraint!( end """ - prune_constraint!( + _prune_constraint!( com::CS.CoM, constraint::GeqSetConstraint, fct::MOI.VectorOfVariables, set::GeqSetInternal; - logs = true + logs = false ) Prune the constraint with: @@ -57,12 +57,12 @@ Prune the constraint with: - Remove values bigger than the allowed maximum from `X` - Set the lower bound of `a` even higher if there fully included `AllDifferentConstraints` allow it """ -function prune_constraint!( +function _prune_constraint!( com::CS.CoM, constraint::GeqSetConstraint, fct::MOI.VectorOfVariables, set::GeqSetInternal; - logs = true, + logs = false, ) # find the maximum of the minima max_val = -typemax(Int) @@ -103,7 +103,7 @@ function prune_constraint!( end """ - still_feasible( + _still_feasible( com::CoM, constraint::GeqSetConstraint, fct::MOI.VectorOfVariables, @@ -114,7 +114,7 @@ end Check if the constraint is still feasible when setting vidx to value """ -function still_feasible( +function _still_feasible( com::CoM, constraint::GeqSetConstraint, fct::MOI.VectorOfVariables, @@ -130,7 +130,8 @@ function still_feasible( end """ - is_constraint_solved( + _is_constraint_solved( + com, constraint::GeqSetConstraint, fct::MOI.VectorOfVariables, set::GeqSetInternal, @@ -139,7 +140,8 @@ end Return true if `values` fulfills the constraint """ -function is_constraint_solved( +function _is_constraint_solved( + com, constraint::GeqSetConstraint, fct::MOI.VectorOfVariables, set::GeqSetInternal, @@ -153,7 +155,7 @@ function is_constraint_solved( end """ - is_constraint_violated( + _is_constraint_violated( com::CoM, constraint::GeqSetConstraint, fct::MOI.VectorOfVariables, @@ -163,7 +165,7 @@ end Checks if the constraint is violated as it is currently set. This can happen inside an inactive reified or indicator constraint. """ -function is_constraint_violated( +function _is_constraint_violated( com::CoM, constraint::GeqSetConstraint, fct::MOI.VectorOfVariables, diff --git a/src/constraints/indicator.jl b/src/constraints/indicator.jl index 56724d48..7b48a745 100644 --- a/src/constraints/indicator.jl +++ b/src/constraints/indicator.jl @@ -1,3 +1,9 @@ +function set_first_node_call!(constraint::IndicatorConstraint, val::Bool) + constraint.first_node_call = val + set_first_node_call!(constraint.inner_constraint, val) +end + + """ init_constraint!( com::CS.CoM, @@ -42,12 +48,12 @@ function init_constraint!( end """ - prune_constraint!( + _prune_constraint!( com::CS.CoM, constraint::IndicatorConstraint, fct::Union{MOI.VectorOfVariables, VAF{T}}, set::IS; - logs = true, + logs = false, ) where {A, T<:Real, ASS<:MOI.AbstractScalarSet, IS<:Union{IndicatorSet{A}, MOI.IndicatorSet{A, ASS}}} Prune the search space given the indicator constraint. An indicator constraint is of the form `b => {x + y == 2}`. @@ -55,12 +61,12 @@ Where the constraint in `{ }` is currently a linear constraint. Return whether the search space is still feasible. """ -function prune_constraint!( +function _prune_constraint!( com::CS.CoM, constraint::IndicatorConstraint, fct::Union{MOI.VectorOfVariables,VAF{T}}, set::IS; - logs = true, + logs = false, ) where { A, T<:Real, @@ -77,18 +83,15 @@ function prune_constraint!( # check if active CS.value(indicator_var) != Int(constraint.activate_on) && return true !activate_inner!(com, constraint) && return false - constraint.inner_pruned = true return prune_constraint!( com, inner_constraint, - inner_constraint.fct, - inner_constraint.set; logs = logs, ) end """ - still_feasible( + _still_feasible( com::CoM, constraint::IndicatorConstraint, fct::Union{MOI.VectorOfVariables, VAF{T}}, @@ -99,7 +102,7 @@ end Return whether the search space is still feasible when setting `search_space[vidx]` to value. """ -function still_feasible( +function _still_feasible( com::CoM, constraint::IndicatorConstraint, fct::Union{MOI.VectorOfVariables,VAF{T}}, @@ -130,23 +133,20 @@ function still_feasible( violated = is_constraint_violated( com, inner_constraint, - inner_constraint.fct, - inner_constraint.set, ) violated && return false # otherwise check if feasible when setting vidx to val return still_feasible( com, inner_constraint, - inner_constraint.fct, - inner_constraint.set, vidx, val, ) end """ - is_constraint_solved( + _is_constraint_solved( + com, constraint::IndicatorConstraint, fct::Union{MOI.VectorOfVariables, VAF{T}}, set::IS, @@ -155,7 +155,8 @@ end Return whether given `values` the constraint is fulfilled. """ -function is_constraint_solved( +function _is_constraint_solved( + com, constraint::IndicatorConstraint, fct::Union{MOI.VectorOfVariables,VAF{T}}, set::IS, @@ -169,9 +170,8 @@ function is_constraint_solved( if values[1] == Int(constraint.activate_on) inner_constraint = constraint.inner_constraint return is_constraint_solved( + com, inner_constraint, - inner_constraint.fct, - inner_constraint.set, values[2:end], ) end @@ -179,7 +179,7 @@ function is_constraint_solved( end """ - is_constraint_violated( + _is_constraint_violated( com::CoM, constraint::IndicatorConstraint, fct::Union{MOI.VectorOfVariables,VAF{T}}, @@ -194,7 +194,7 @@ end Checks if the constraint is violated as it is currently set. This can happen inside an inactive reified or indicator constraint. """ -function is_constraint_violated( +function _is_constraint_violated( com::CoM, constraint::IndicatorConstraint, fct::Union{MOI.VectorOfVariables,VAF{T}}, @@ -207,9 +207,8 @@ function is_constraint_violated( } if all(isfixed(var) for var in com.search_space[constraint.indices]) return !is_constraint_solved( + com, constraint, - fct, - set, [CS.value(var) for var in com.search_space[constraint.indices]], ) end @@ -221,8 +220,6 @@ function is_constraint_violated( return is_constraint_violated( com, inner_constraint, - inner_constraint.fct, - inner_constraint.set, ) end return false diff --git a/src/constraints/linear_constraints.jl b/src/constraints/linear_constraints.jl index 8675b387..891e1a84 100644 --- a/src/constraints/linear_constraints.jl +++ b/src/constraints/linear_constraints.jl @@ -116,6 +116,10 @@ function init_constraint!( return true end +function first_node_call!(com::CS.CoM, constraint::LinearConstraint, fct, set) + recompute_lc_extrema!(com, constraint, fct) +end + """ get_new_extrema_and_sum(search_space, vidx, i, terms, full_min, full_max, pre_mins, pre_maxs) @@ -261,30 +265,31 @@ function set_new_extrema(i, pre_mins, pre_maxs, new_min, new_max) end """ - prune_constraint!(com::CS.CoM, constraint::LinearConstraint, fct::SAF{T}, set; logs = true) where T <: Real + _prune_constraint!(com::CS.CoM, constraint::LinearConstraint, fct::SAF{T}, set; logs = false) where T <: Real Reduce the number of possibilities given the `LinearConstraint` . Return if still feasible and throw a warning if infeasible and `logs` is set to `true` """ -function prune_constraint!( +function _prune_constraint!( com::CS.CoM, constraint::LinearConstraint, fct::SAF{T}, set::Union{MOI.LessThan, MOI.EqualTo, CPE.Strictly{MOI.LessThan{T}}}; - logs = true, + logs = false, ) where {T<:Real} constraint.currently_pruning = true - isfeasible = _prune_constraint!(com, constraint, fct, set; logs=logs) + recompute_lc_extrema!(com, constraint, fct) + isfeasible = _prune_constraint_actual!(com, constraint, fct, set; logs=logs) constraint.currently_pruning = false return isfeasible end -function _prune_constraint!( +function _prune_constraint_actual!( com::CS.CoM, constraint::LinearConstraint, fct::SAF{T}, set::Union{MOI.LessThan, MOI.EqualTo, CPE.Strictly{MOI.LessThan{T}}}; - logs = true, + logs = false, ) where {T<:Real} indices = constraint.indices search_space = com.search_space @@ -497,12 +502,12 @@ function prune_is_equal_two_var!(com::CS.CoM, end """ - still_feasible(com::CoM, constraint::LinearConstraint, fct::SAF{T}, + _still_feasible(com::CoM, constraint::LinearConstraint, fct::SAF{T}, set::MOI.EqualTo{T}, vidx::Int, val::Int) where T <: Real Return whether setting `search_space[vidx]` to `val` is still feasible given `constraint`. """ -function still_feasible( +function _still_feasible( com::CoM, constraint::LinearConstraint, fct::SAF{T}, @@ -572,16 +577,16 @@ function still_feasible( end """ - is_constraint_solved( + _is_constraint_solved( com::CS.CoM, constraint::LinearConstraint, fct::SAF{T}, set::MOI.LessThan{T}, ) - Check if the constraint is fulfilled even though not all variables are set +Check if the constraint is fulfilled even though not all variables are set """ -function is_constraint_solved( +function _is_constraint_solved( com::CS.CoM, constraint::LinearConstraint, fct::SAF{T}, @@ -592,7 +597,7 @@ function is_constraint_solved( end """ - is_constraint_solved( + _is_constraint_solved( com::CS.CoM, constraint::LinearConstraint, fct::SAF{T}, @@ -601,7 +606,7 @@ end Check if the constraint is fulfilled even though not all variables are set """ -function is_constraint_solved( +function _is_constraint_solved( com::CS.CoM, constraint::LinearConstraint, fct::SAF{T}, @@ -611,7 +616,8 @@ function is_constraint_solved( return sum_maxs < MOI.constant(set) end -function is_constraint_solved( +function _is_constraint_solved( + com, constraint::LinearConstraint, fct::SAF{T}, set::MOI.EqualTo{T}, @@ -620,7 +626,8 @@ function is_constraint_solved( return sum(values .* constraint.coeffs) + fct.constant ≈ set.value end -function is_constraint_solved( +function _is_constraint_solved( + com, constraint::LinearConstraint, fct::SAF{T}, set::MOI.LessThan{T}, @@ -630,7 +637,8 @@ function is_constraint_solved( end -function is_constraint_solved( +function _is_constraint_solved( + com, constraint::LinearConstraint, fct::SAF{T}, set::CPE.Strictly{MOI.LessThan{T}}, @@ -641,7 +649,7 @@ end """ - is_constraint_violated( + _is_constraint_violated( com::CoM, constraint::LinearConstraint, fct::SAF{T}, @@ -651,7 +659,7 @@ end Checks if the constraint is violated as it is currently set. This can happen inside an inactive reified or indicator constraint. """ -function is_constraint_violated( +function _is_constraint_violated( com::CoM, constraint::LinearConstraint, fct::SAF{T}, @@ -659,9 +667,8 @@ function is_constraint_violated( ) where {T<:Real} if all(isfixed(var) for var in com.search_space[constraint.indices]) return !is_constraint_solved( + com, constraint, - fct, - set, CS.value.(com.search_space[constraint.indices]), ) end @@ -685,16 +692,6 @@ function min_sum_feasible(com, min_sum, set::CPE.Strictly{MOI.LessThan{T}}) wher return min_sum <= MOI.constant(set) + com.options.atol end -function reverse_pruning_constraint!( - com::CoM, - constraint::LinearConstraint, - fct::SAF{T}, - set::Union{MOI.LessThan, MOI.EqualTo, CPE.Strictly{MOI.LessThan{T}}}, - backtrack_id::Int, -) where {T <: Real} - recompute_lc_extrema!(com, constraint, fct) -end - function activate_constraint!( com::CoM, constraint::LinearConstraint, diff --git a/src/constraints/not_equal.jl b/src/constraints/not_equal.jl index 7284fcc9..492b7173 100644 --- a/src/constraints/not_equal.jl +++ b/src/constraints/not_equal.jl @@ -1,15 +1,15 @@ """ - prune_constraint!(com::CS.CoM, constraint::BasicConstraint, fct::SAF{T}, set::CPE.DifferentFrom{T}; logs = true) where T <: Real + _prune_constraint!(com::CS.CoM, constraint::BasicConstraint, fct::SAF{T}, set::CPE.DifferentFrom{T}; logs = false) where T <: Real Reduce the number of possibilities given the not equal constraint. Return if still feasible and throw a warning if infeasible and `logs` is set to `true` """ -function prune_constraint!( +function _prune_constraint!( com::CS.CoM, constraint::LinearConstraint, fct::SAF{T}, set::CPE.DifferentFrom{T}; - logs = true, + logs = false, ) where {T<:Real} indices = constraint.indices @@ -48,11 +48,11 @@ function prune_constraint!( end """ -still_feasible(com::CoM, constraint::LinearConstraint, fct::MOI.ScalarAffineFunction{T}, set::CPE.DifferentFrom{T}, vidx::Int, value::Int) where T <: Real + _still_feasible(com::CoM, constraint::LinearConstraint, fct::MOI.ScalarAffineFunction{T}, set::CPE.DifferentFrom{T}, vidx::Int, value::Int) where T <: Real Return whether the `not_equal` constraint can be still fulfilled. """ -function still_feasible( +function _still_feasible( com::CoM, constraint::LinearConstraint, fct::SAF{T}, @@ -90,7 +90,8 @@ function still_feasible( return true end -function is_constraint_solved( +function _is_constraint_solved( + com, constraint::LinearConstraint, fct::SAF{T}, set::CPE.DifferentFrom{T}, @@ -103,7 +104,7 @@ function is_constraint_solved( end """ - is_constraint_violated( + _is_constraint_violated( com::CoM, constraint::LinearConstraint, fct::SAF{T}, @@ -113,7 +114,7 @@ end Checks if the constraint is violated as it is currently set. This can happen inside an inactive reified or indicator constraint. """ -function is_constraint_violated( +function _is_constraint_violated( com::CoM, constraint::LinearConstraint, fct::SAF{T}, @@ -121,9 +122,8 @@ function is_constraint_violated( ) where {T<:Real} if all(isfixed(var) for var in com.search_space[constraint.indices]) return !is_constraint_solved( + com, constraint, - fct, - set, [CS.value(var) for var in com.search_space[constraint.indices]], ) end diff --git a/src/constraints/or.jl b/src/constraints/or.jl index f2e54531..b6b4d2dd 100644 --- a/src/constraints/or.jl +++ b/src/constraints/or.jl @@ -1,5 +1,5 @@ """ - function is_constraint_violated( + function _is_constraint_violated( com::CoM, constraint::BoolConstraint, fct, @@ -8,7 +8,7 @@ Check if both of the inner constraints are violated """ -function is_constraint_violated( +function _is_constraint_violated( com::CoM, constraint::BoolConstraint, fct, @@ -18,12 +18,12 @@ function is_constraint_violated( end """ - still_feasible(com::CoM, constraint::OrConstraint, fct, set::OrSet, vidx::Int, value::Int) + _still_feasible(com::CoM, constraint::OrConstraint, fct, set::OrSet, vidx::Int, value::Int) Return whether the constraint can be still fulfilled when setting a variable with index `vidx` to `value`. **Attention:** This assumes that it isn't violated before. """ -function still_feasible( +function _still_feasible( com::CoM, constraint::OrConstraint, fct, @@ -31,23 +31,23 @@ function still_feasible( vidx::Int, value::Int, ) - lhs_feasible = !is_constraint_violated(com, constraint.lhs, constraint.lhs.fct, constraint.lhs.set) + lhs_feasible = !is_constraint_violated(com, constraint.lhs) if lhs_feasible lhs_indices = constraint.lhs.indices for i in 1:length(lhs_indices) if lhs_indices[i] == vidx - lhs_feasible = still_feasible(com, constraint.lhs, constraint.lhs.fct, constraint.lhs.set, vidx, value) + lhs_feasible = still_feasible(com, constraint.lhs, vidx, value) lhs_feasible && return true break end end end - rhs_feasible = !is_constraint_violated(com, constraint.rhs, constraint.rhs.fct, constraint.rhs.set) + rhs_feasible = !is_constraint_violated(com, constraint.rhs) if rhs_feasible rhs_indices = constraint.rhs.indices for i in 1:length(rhs_indices) if rhs_indices[i] == vidx - rhs_feasible = still_feasible(com, constraint.rhs, constraint.rhs.fct, constraint.rhs.set, vidx, value) + rhs_feasible = still_feasible(com, constraint.rhs, vidx, value) rhs_feasible && return true break end @@ -57,30 +57,30 @@ function still_feasible( end """ - prune_constraint!(com::CS.CoM, constraint::OrConstraint, fct, set::OrSet; logs = true) + _prune_constraint!(com::CS.CoM, constraint::OrConstraint, fct, set::OrSet; logs = false) Reduce the number of possibilities given the `OrConstraint` by pruning both parts Return whether still feasible """ -function prune_constraint!( +function _prune_constraint!( com::CS.CoM, constraint::OrConstraint, fct, set::OrSet; - logs = true, + logs = false, ) - lhs_violated = is_constraint_violated(com, constraint.lhs, constraint.lhs.fct, constraint.lhs.set) - rhs_violated = is_constraint_violated(com, constraint.rhs, constraint.rhs.fct, constraint.rhs.set) + lhs_violated = is_constraint_violated(com, constraint.lhs) + rhs_violated = is_constraint_violated(com, constraint.rhs) if lhs_violated && rhs_violated return false end if lhs_violated activate_rhs!(com, constraint) - return prune_constraint!(com, constraint.rhs, constraint.rhs.fct, constraint.rhs.set; logs=logs) + return prune_constraint!(com, constraint.rhs; logs=logs) end if rhs_violated activate_lhs!(com, constraint) - return prune_constraint!(com, constraint.lhs, constraint.lhs.fct, constraint.lhs.set; logs=logs) + return prune_constraint!(com, constraint.lhs; logs=logs) end return true end \ No newline at end of file diff --git a/src/constraints/reified.jl b/src/constraints/reified.jl index 933a7831..d7e6192f 100644 --- a/src/constraints/reified.jl +++ b/src/constraints/reified.jl @@ -1,3 +1,11 @@ +function set_first_node_call!(constraint::ReifiedConstraint, val::Bool) + constraint.first_node_call = val + set_first_node_call!(constraint.inner_constraint, val) + if constraint.complement_constraint !== nothing + set_first_node_call!(constraint.complement_constraint, val) + end +end + function init_constraint!( com::CS.CoM, constraint::ReifiedConstraint, @@ -37,12 +45,12 @@ function init_constraint!( return true end -function prune_constraint!( +function _prune_constraint!( com::CS.CoM, constraint::ReifiedConstraint, fct::Union{MOI.VectorOfVariables,VAF{T}}, set::RS; - logs = true, + logs = false, ) where {A,T<:Real,RS<:ReifiedSet{A}} # 1. if the inner constraint is solved then the reified variable can be set to activate_on # 2. if the inner constraint is infeasible the reified variable can be set to !activate_on @@ -59,45 +67,35 @@ function prune_constraint!( # 3 if issetto(variables[rei_vidx], activate_on) - constraint.inner_pruned = true !activate_inner!(com, constraint) && return false return prune_constraint!( com, inner_constraint, - inner_constraint.fct, - inner_constraint.set, ) # 4 elseif issetto(variables[rei_vidx], activate_off) && complement_constraint !== nothing - constraint.complement_pruned = true !activate_complement_inner!(com, constraint) && return false return prune_constraint!( com, complement_constraint, - complement_constraint.fct, - complement_constraint.set, ) # 1 elseif is_constraint_solved( com, inner_constraint, - inner_constraint.fct, - inner_constraint.set, ) !fix!(com, variables[rei_vidx], activate_on) && return false # 2 elseif is_constraint_violated( com, inner_constraint, - inner_constraint.fct, - inner_constraint.set, ) !fix!(com, variables[rei_vidx], activate_off) && return false end return true end -function still_feasible( +function _still_feasible( com::CS.CoM, constraint::ReifiedConstraint, fct::Union{MOI.VectorOfVariables,VAF{T}}, @@ -117,15 +115,11 @@ function still_feasible( violated = is_constraint_violated( com, inner_constraint, - inner_constraint.fct, - inner_constraint.set, ) violated && return false return still_feasible( com, inner_constraint, - inner_constraint.fct, - inner_constraint.set, vidx, val, ) @@ -138,9 +132,8 @@ function still_feasible( for i in inner_constraint.indices ] return !is_constraint_solved( + com, inner_constraint, - inner_constraint.fct, - inner_constraint.set, values, ) end @@ -148,7 +141,8 @@ function still_feasible( return true end -function is_constraint_solved( +function _is_constraint_solved( + com, constraint::ReifiedConstraint, fct::Union{MOI.VectorOfVariables,VAF{T}}, set::RS, @@ -157,15 +151,14 @@ function is_constraint_solved( activate_on = Int(constraint.activate_on) inner_constraint = constraint.inner_constraint return is_constraint_solved( + com, inner_constraint, - inner_constraint.fct, - inner_constraint.set, values[2:end], ) == (values[1] == activate_on) end """ - is_constraint_violated( + _is_constraint_violated( com::CoM, constraint::ReifiedConstraint, fct::Union{MOI.VectorOfVariables,VAF{T}}, @@ -175,7 +168,7 @@ end Checks if the constraint is violated as it is currently set. This can happen inside an inactive reified or indicator constraint. """ -function is_constraint_violated( +function _is_constraint_violated( com::CoM, constraint::ReifiedConstraint, fct::Union{MOI.VectorOfVariables,VAF{T}}, @@ -183,9 +176,8 @@ function is_constraint_violated( ) where {A,T<:Real,RS<:ReifiedSet{A}} if all(isfixed(var) for var in com.search_space[constraint.indices]) return !is_constraint_solved( + com, constraint, - fct, - set, [CS.value(var) for var in com.search_space[constraint.indices]], ) end @@ -197,8 +189,6 @@ function is_constraint_violated( return is_constraint_violated( com, inner_constraint, - inner_constraint.fct, - inner_constraint.set, ) end return false diff --git a/src/constraints/svc.jl b/src/constraints/svc.jl index c83d8e14..0e27c8e1 100644 --- a/src/constraints/svc.jl +++ b/src/constraints/svc.jl @@ -3,17 +3,17 @@ =# """ -prune_constraint!(com::CS.CoM, constraint::CS.SingleVariableConstraint, fct::MOI.ScalarAffineFunction{T}, set::LessThan{T}; logs = true) where T <: Real + _prune_constraint!(com::CS.CoM, constraint::CS.SingleVariableConstraint, fct::MOI.ScalarAffineFunction{T}, set::LessThan{T}; logs = false) where T <: Real Support for constraints of the form a <= b where a and b are single variables. This function removes values which aren't possible based on this constraint. """ -function prune_constraint!( +function _prune_constraint!( com::CS.CoM, constraint::CS.SingleVariableConstraint, fct::SAF{T}, set::MOI.LessThan; - logs = true, + logs = false, ) where {T<:Real} lhs = constraint.lhs rhs = constraint.rhs @@ -24,11 +24,18 @@ function prune_constraint!( end """ - less_than(com::CoM, constraint::CS.SingleVariableConstraint, vidx::Int, val::Int) + _still_feasible( + com::CoM, + constraint::CS.SingleVariableConstraint, + fct::SAF{T}, + set::MOI.LessThan, + vidx::Int, + val::Int, + ) where {T<:Real} Checks whether setting an `vidx` to `val` fulfills `constraint` """ -function still_feasible( +function _still_feasible( com::CoM, constraint::CS.SingleVariableConstraint, fct::SAF{T}, @@ -54,7 +61,8 @@ function still_feasible( end end -function is_constraint_solved( +function _is_constraint_solved( + com, constraint::CS.SingleVariableConstraint, fct::SAF{T}, set::MOI.LessThan, @@ -65,7 +73,7 @@ end """ - is_constraint_violated( + _is_constraint_violated( com::CoM, constraint::CS.SingleVariableConstraint, fct::SAF{T}, @@ -75,7 +83,7 @@ end Checks if the constraint is violated as it is currently set. This can happen inside an inactive reified or indicator constraint. """ -function is_constraint_violated( +function _is_constraint_violated( com::CoM, constraint::CS.SingleVariableConstraint, fct::SAF{T}, diff --git a/src/constraints/table.jl b/src/constraints/table.jl index 9c1032a1..6a62af66 100644 --- a/src/constraints/table.jl +++ b/src/constraints/table.jl @@ -264,17 +264,17 @@ function filter_domains(com::CoM, constraint::TableConstraint) end """ - prune_constraint!(com::CS.CoM, constraint::TableConstraint, fct::MOI.VectorOfVariables, set::TableSetInternal; logs = true) + _prune_constraint!(com::CS.CoM, constraint::TableConstraint, fct::MOI.VectorOfVariables, set::TableSetInternal; logs = false) Reduce the number of possibilities given the `TableConstraint`. Return whether still feasible and throws a warning if infeasible and `logs` is set to `true` """ -function prune_constraint!( +function _prune_constraint!( com::CS.CoM, constraint::TableConstraint, fct::MOI.VectorOfVariables, set::TableSetInternal; - logs = true, + logs = false, ) current = constraint.current indices = constraint.indices @@ -331,11 +331,11 @@ function finished_pruning_constraint!( end """ - still_feasible(com::CoM, constraint::TableConstraint, fct::MOI.VectorOfVariables, set::TableSetInternal, vidx::Int, value::Int) + _still_feasible(com::CoM, constraint::TableConstraint, fct::MOI.VectorOfVariables, set::TableSetInternal, vidx::Int, value::Int) Return whether the constraint can be still fulfilled when setting a variable with index `vidx` to `value`. """ -function still_feasible( +function _still_feasible( com::CoM, constraint::TableConstraint, fct::MOI.VectorOfVariables, @@ -551,19 +551,19 @@ function restore_pruning_constraint!( empty!(constraint.changed_vars) end -function is_constraint_solved( +function _is_constraint_solved( + com, constraint::TableConstraint, fct::MOI.VectorOfVariables, set::TableSetInternal, values::Vector{Int}, ) - table = set.table return findfirst(ri -> table[ri, :] == values, 1:size(table)[1]) !== nothing end """ - is_constraint_violated( + _is_constraint_violated( com::CoM, constraint::TableConstraint, fct::MOI.VectorOfVariables, @@ -573,7 +573,7 @@ end Checks if the constraint is violated as it is currently set. This can happen inside an inactive reified or indicator constraint. """ -function is_constraint_violated( +function _is_constraint_violated( com::CoM, constraint::TableConstraint, fct::MOI.VectorOfVariables, @@ -581,9 +581,8 @@ function is_constraint_violated( ) if all(isfixed(var) for var in com.search_space[constraint.indices]) return !is_constraint_solved( + com, constraint, - fct, - set, [CS.value(var) for var in com.search_space[constraint.indices]], ) end diff --git a/src/constraints/xnor.jl b/src/constraints/xnor.jl index 134e834f..7389ff79 100644 --- a/src/constraints/xnor.jl +++ b/src/constraints/xnor.jl @@ -1,3 +1,16 @@ +function set_first_node_call!(constraint::XNorConstraint, val::Bool) + constraint.first_node_call = val + set_first_node_call!(constraint.lhs, val) + set_first_node_call!(constraint.rhs, val) + if constraint.complement_lhs !== nothing + constraint.complement_lhs.first_node_call = val + set_first_node_call!(constraint.complement_lhs, val) + end + if constraint.complement_rhs !== nothing + set_first_node_call!(constraint.complement_rhs, val) + end +end + function init_constraint!( com::CS.CoM, constraint::XNorConstraint, @@ -16,7 +29,7 @@ function init_constraint!( end """ - function is_constraint_violated( + function _is_constraint_violated( com::CoM, constraint::BoolConstraint, fct, @@ -25,14 +38,14 @@ end Check whether one side is solved and other is violated """ -function is_constraint_violated( +function _is_constraint_violated( com::CoM, constraint::BoolConstraint, fct, set::XNorSet, ) - lhs_solved = is_constraint_solved(com, constraint.lhs, constraint.lhs.fct, constraint.lhs.set) - rhs_solved = is_constraint_solved(com, constraint.rhs, constraint.rhs.fct, constraint.rhs.set) + lhs_solved = is_constraint_solved(com, constraint.lhs) + rhs_solved = is_constraint_solved(com, constraint.rhs) # neither of them is solved => it's not violated yet if !lhs_solved && !rhs_solved return false @@ -54,12 +67,12 @@ function is_constraint_violated( end """ - still_feasible(com::CoM, constraint::XNorConstraint, fct, set::XNorSet, vidx::Int, value::Int) + _still_feasible(com::CoM, constraint::XNorConstraint, fct, set::XNorSet, vidx::Int, value::Int) Return whether the constraint can be still fulfilled when setting a variable with index `vidx` to `value`. **Attention:** This assumes that it isn't violated before. """ -function still_feasible( +function _still_feasible( com::CoM, constraint::XNorConstraint, fct, @@ -67,7 +80,7 @@ function still_feasible( vidx::Int, value::Int, ) - lhs_violated = is_constraint_violated(com, constraint.lhs, constraint.lhs.fct, constraint.lhs.set) + lhs_violated = is_constraint_violated(com, constraint.lhs) lhs_feasible = !lhs_violated lhs_solved = false if lhs_feasible @@ -77,12 +90,12 @@ function still_feasible( lhs_indices = constraint.lhs.indices for i in 1:length(lhs_indices) if lhs_indices[i] == vidx - lhs_feasible = still_feasible(com, constraint.lhs, constraint.lhs.fct, constraint.lhs.set, vidx, value) + lhs_feasible = still_feasible(com, constraint.lhs, vidx, value) break end end end - rhs_violated = is_constraint_violated(com, constraint.rhs, constraint.rhs.fct, constraint.rhs.set) + rhs_violated = is_constraint_violated(com, constraint.rhs) rhs_feasible = !rhs_violated rhs_solved = false if rhs_feasible @@ -96,7 +109,7 @@ function still_feasible( rhs_indices = constraint.rhs.indices for i in 1:length(rhs_indices) if rhs_indices[i] == vidx - rhs_feasible = still_feasible(com, constraint.rhs, constraint.rhs.fct, constraint.rhs.set, vidx, value) + rhs_feasible = still_feasible(com, constraint.rhs, vidx, value) break end end @@ -109,26 +122,26 @@ function still_feasible( end """ - prune_constraint!(com::CS.CoM, constraint::XNorConstraint, fct, set::XNorSet; logs = true) + _prune_constraint!(com::CS.CoM, constraint::XNorConstraint, fct, set::XNorSet; logs = false) Reduce the number of possibilities given the `XNorConstraint` by pruning both parts Return whether still feasible """ -function prune_constraint!( +function _prune_constraint!( com::CS.CoM, constraint::XNorConstraint, fct, set::XNorSet; - logs = true, + logs = false, ) - lhs_violated = is_constraint_violated(com, constraint.lhs, constraint.lhs.fct, constraint.lhs.set) - rhs_violated = is_constraint_violated(com, constraint.rhs, constraint.rhs.fct, constraint.rhs.set) + lhs_violated = is_constraint_violated(com, constraint.lhs) + rhs_violated = is_constraint_violated(com, constraint.rhs) if lhs_violated && rhs_violated return true end # check if one is already solved - lhs_solved = is_constraint_solved(com, constraint.lhs, constraint.lhs.fct, constraint.lhs.set) - rhs_solved = is_constraint_solved(com, constraint.rhs, constraint.rhs.fct, constraint.rhs.set) + lhs_solved = is_constraint_solved(com, constraint.lhs) + rhs_solved = is_constraint_solved(com, constraint.rhs) if lhs_solved && rhs_solved return true end @@ -136,21 +149,21 @@ function prune_constraint!( # if one is solved => prune the other if lhs_solved activate_rhs!(com, constraint) - return prune_constraint!(com, constraint.rhs, constraint.rhs.fct, constraint.rhs.set; logs=logs) + return prune_constraint!(com, constraint.rhs; logs=logs) end if rhs_solved activate_lhs!(com, constraint) - return prune_constraint!(com, constraint.lhs, constraint.lhs.fct, constraint.lhs.set; logs=logs) + return prune_constraint!(com, constraint.lhs; logs=logs) end # if one is violated complement prune the other # Todo implement for activated complement constraints if lhs_violated && constraint.complement_rhs !== nothing && !implements_activate(typeof(constraint.complement_rhs), typeof(constraint.complement_rhs.fct), typeof(constraint.complement_rhs.set)) - return prune_constraint!(com, constraint.complement_rhs, constraint.complement_rhs.fct, constraint.complement_rhs.set; logs=logs) + return prune_constraint!(com, constraint.complement_rhs; logs=logs) end if rhs_violated && constraint.complement_lhs !== nothing && !implements_activate(typeof(constraint.complement_lhs), typeof(constraint.complement_lhs.fct), typeof(constraint.complement_lhs.set)) - return prune_constraint!(com, constraint.complement_lhs, constraint.complement_lhs.fct, constraint.complement_lhs.set; logs=logs) + return prune_constraint!(com, constraint.complement_lhs; logs=logs) end return true diff --git a/src/constraints/xor.jl b/src/constraints/xor.jl index 6208a66c..9a6e8256 100644 --- a/src/constraints/xor.jl +++ b/src/constraints/xor.jl @@ -1,3 +1,16 @@ +function set_first_node_call!(constraint::XorConstraint, val::Bool) + constraint.first_node_call = val + set_first_node_call!(constraint.lhs, val) + set_first_node_call!(constraint.rhs, val) + if constraint.complement_lhs !== nothing + constraint.complement_lhs.first_node_call = val + set_first_node_call!(constraint.complement_lhs, val) + end + if constraint.complement_rhs !== nothing + set_first_node_call!(constraint.complement_rhs, val) + end +end + function init_constraint!( com::CS.CoM, constraint::XorConstraint, @@ -16,7 +29,7 @@ function init_constraint!( end """ - function is_constraint_violated( + function _is_constraint_violated( com::CoM, constraint::BoolConstraint, fct, @@ -25,7 +38,7 @@ end Check if both of the inner constraints are violated or whether both are solved """ -function is_constraint_violated( +function _is_constraint_violated( com::CoM, constraint::BoolConstraint, fct, @@ -33,18 +46,18 @@ function is_constraint_violated( ) both_violated = is_lhs_constraint_violated(com, constraint) && is_rhs_constraint_violated(com, constraint) both_violated && return true - lhs_solved = is_constraint_solved(com, constraint.lhs, constraint.lhs.fct, constraint.lhs.set) - rhs_solved = is_constraint_solved(com, constraint.rhs, constraint.rhs.fct, constraint.rhs.set) + lhs_solved = is_constraint_solved(com, constraint.lhs) + rhs_solved = is_constraint_solved(com, constraint.rhs) return lhs_solved && rhs_solved end """ - still_feasible(com::CoM, constraint::XorConstraint, fct, set::XorSet, vidx::Int, value::Int) + _still_feasible(com::CoM, constraint::XorConstraint, fct, set::XorSet, vidx::Int, value::Int) Return whether the constraint can be still fulfilled when setting a variable with index `vidx` to `value`. **Attention:** This assumes that it isn't violated before. """ -function still_feasible( +function _still_feasible( com::CoM, constraint::XorConstraint, fct, @@ -52,7 +65,7 @@ function still_feasible( vidx::Int, value::Int, ) - lhs_violated = is_constraint_violated(com, constraint.lhs, constraint.lhs.fct, constraint.lhs.set) + lhs_violated = is_constraint_violated(com, constraint.lhs) lhs_feasible = !lhs_violated lhs_solved = false if lhs_feasible @@ -62,12 +75,12 @@ function still_feasible( lhs_indices = constraint.lhs.indices for i in 1:length(lhs_indices) if lhs_indices[i] == vidx - lhs_feasible = still_feasible(com, constraint.lhs, constraint.lhs.fct, constraint.lhs.set, vidx, value) + lhs_feasible = still_feasible(com, constraint.lhs, vidx, value) break end end end - rhs_violated = is_constraint_violated(com, constraint.rhs, constraint.rhs.fct, constraint.rhs.set) + rhs_violated = is_constraint_violated(com, constraint.rhs) rhs_feasible = !rhs_violated rhs_solved = false if rhs_feasible @@ -77,7 +90,7 @@ function still_feasible( rhs_indices = constraint.rhs.indices for i in 1:length(rhs_indices) if rhs_indices[i] == vidx - rhs_feasible = still_feasible(com, constraint.rhs, constraint.rhs.fct, constraint.rhs.set, vidx, value) + rhs_feasible = still_feasible(com, constraint.rhs, vidx, value) break end end @@ -94,26 +107,26 @@ function still_feasible( end """ - prune_constraint!(com::CS.CoM, constraint::XorConstraint, fct, set::XorSet; logs = true) + _prune_constraint!(com::CS.CoM, constraint::XorConstraint, fct, set::XorSet; logs = false) Reduce the number of possibilities given the `XorConstraint` by pruning both parts Return whether still feasible """ -function prune_constraint!( +function _prune_constraint!( com::CS.CoM, constraint::XorConstraint, fct, set::XorSet; - logs = true, + logs = false, ) - lhs_violated = is_constraint_violated(com, constraint.lhs, constraint.lhs.fct, constraint.lhs.set) - rhs_violated = is_constraint_violated(com, constraint.rhs, constraint.rhs.fct, constraint.rhs.set) + lhs_violated = is_constraint_violated(com, constraint.lhs) + rhs_violated = is_constraint_violated(com, constraint.rhs) if lhs_violated && rhs_violated return false end # check if one is already solved - lhs_solved = is_constraint_solved(com, constraint.lhs, constraint.lhs.fct, constraint.lhs.set) - rhs_solved = is_constraint_solved(com, constraint.rhs, constraint.rhs.fct, constraint.rhs.set) + lhs_solved = is_constraint_solved(com, constraint.lhs) + rhs_solved = is_constraint_solved(com, constraint.rhs) if lhs_solved && rhs_solved return false end @@ -121,21 +134,21 @@ function prune_constraint!( # if one is solved => complement prune the other # Todo implement for activated complement constraints if lhs_solved && constraint.complement_rhs !== nothing - return prune_constraint!(com, constraint.complement_rhs, constraint.complement_rhs.fct, constraint.complement_rhs.set; logs=logs) + return prune_constraint!(com, constraint.complement_rhs; logs=logs) end if rhs_solved && constraint.complement_lhs !== nothing - return prune_constraint!(com, constraint.complement_lhs, constraint.complement_lhs.fct, constraint.complement_lhs.set; logs=logs) + return prune_constraint!(com, constraint.complement_lhs; logs=logs) end # if both aren't solved yet we only prune if one is violated if !lhs_solved && !rhs_solved if lhs_violated activate_rhs!(com, constraint) - return prune_constraint!(com, constraint.rhs, constraint.rhs.fct, constraint.rhs.set; logs=logs) + return prune_constraint!(com, constraint.rhs; logs=logs) end if rhs_violated activate_lhs!(com, constraint) - return prune_constraint!(com, constraint.lhs, constraint.lhs.fct, constraint.lhs.set; logs=logs) + return prune_constraint!(com, constraint.lhs; logs=logs) end end diff --git a/src/pruning.jl b/src/pruning.jl index 1e25ce96..da776eea 100644 --- a/src/pruning.jl +++ b/src/pruning.jl @@ -75,6 +75,10 @@ function prune!( end end end + for constraint in com.constraints + set_first_node_call!(constraint, true) + end + # while we haven't called every constraint while true @@ -92,7 +96,7 @@ function prune!( constraint = com.constraints[ci] feasible = - prune_constraint!(com, constraint, constraint.fct, constraint.set; logs = false) + prune_constraint!(com, constraint; logs = false) if !pre_backtrack com.info.in_backtrack_calls += 1 else diff --git a/src/type_inits.jl b/src/type_inits.jl index 19cf214b..f7f81d07 100644 --- a/src/type_inits.jl +++ b/src/type_inits.jl @@ -32,6 +32,7 @@ function ConstraintInternals(cidx::Int, fct, set, indices::Vector{Int}) cidx, fct, set, + true, vidx_to_idx, indices, Int[], @@ -111,7 +112,7 @@ function LinearConstraint( end function ReifiedConstraint(std, act_std, inner_constraint, complement_constraint) - return ReifiedConstraint(std, act_std, inner_constraint, complement_constraint, false, 0, false) + return ReifiedConstraint(std, act_std, inner_constraint, complement_constraint, false, 0) end """ diff --git a/src/types.jl b/src/types.jl index f400990c..29a0a87a 100644 --- a/src/types.jl +++ b/src/types.jl @@ -372,13 +372,14 @@ mutable struct ConstraintInternals{ idx::Int fct::FCT set::SET + first_node_call::Bool # true inside prune_constraint! when it's the first prune of the node vidx_to_idx::Dict{Int,Int} indices::Vector{Int} pvals::Vector{Int} is_initialized::Bool - is_activated::Bool + is_activated::Bool # whether the constraint is currently active i.e can be inactive when the activator isn't true is_deactivated::Bool # can be deactivated if it's absorbed by other constraints - bound_rhs::Vector{BoundRhsVariable}# should be set if `update_best_bound` is true + bound_rhs::Vector{BoundRhsVariable} # should be set if `update_best_bound` is true end #==================================================================================== @@ -498,7 +499,6 @@ mutable struct ActivatorConstraintInternals activator_in_inner::Bool inner_activated::Bool inner_activated_in_backtrack_idx::Int - inner_pruned::Bool end mutable struct IndicatorConstraint{C<:Constraint} <: ActivatorConstraint @@ -514,7 +514,6 @@ mutable struct ReifiedConstraint{C<:Constraint, AC<:Union{Constraint,Nothing}} < complement_constraint::AC complement_activated::Bool complement_activated_in_backtrack_idx::Int - complement_pruned::Bool end #==================================================================================== diff --git a/src/util.jl b/src/util.jl index 7882c90a..00a3db72 100644 --- a/src/util.jl +++ b/src/util.jl @@ -102,13 +102,6 @@ function arr2dict(arr) return d end -function is_constraint_solved(com::CS.CoM, constraint::Constraint, fct, set) - variables = com.search_space - !all(isfixed(variables[ind]) for ind in constraint.indices) && return false - values = CS.value.(variables[constraint.indices]) - return is_constraint_solved(constraint, fct, set, values) -end - function is_constraint_solved_when_fixed(com::CS.CoM, constraint::Constraint, fct, set, vidx::Int, value::Int) variables = com.search_space !all(isfixed(variables[ind]) || variables[ind].idx == vidx for ind in constraint.indices) && return false @@ -120,7 +113,7 @@ function is_constraint_solved_when_fixed(com::CS.CoM, constraint::Constraint, fc values[i] = value end end - return is_constraint_solved(constraint, fct, set, values) + return is_constraint_solved(com, constraint, values) end #= @@ -132,6 +125,7 @@ end :indices, :fct, :set, + :first_node_call, :vidx_to_idx, :pvals, :is_initialized, @@ -151,6 +145,7 @@ end :indices, :fct, :set, + :first_node_call, :vidx_to_idx, :pvals, :is_initialized, @@ -173,6 +168,8 @@ end :indices, :fct, :set, + :first_node_call, + :vidx_to_idx, :pvals, :is_initialized, :is_activated, @@ -185,7 +182,6 @@ end :activator_in_inner, :inner_activated, :inner_activated_in_backtrack_idx, - :inner_pruned, ) Core.getproperty(Core.getproperty(c, :act_std), s) else @@ -199,6 +195,8 @@ end :indices, :fct, :set, + :first_node_call, + :vidx_to_idx, :pvals, :is_initialized, :is_activated, @@ -211,7 +209,6 @@ end :activator_in_inner, :inner_activated, :inner_activated_in_backtrack_idx, - :inner_pruned, ) Core.setproperty!(c.act_std, s, v) else @@ -228,6 +225,8 @@ end :indices, :fct, :set, + :first_node_call, + :vidx_to_idx, :pvals, :is_initialized, :is_activated, @@ -255,6 +254,8 @@ end :indices, :fct, :set, + :first_node_call, + :vidx_to_idx, :pvals, :is_initialized, :is_activated, diff --git a/test/constraints/table.jl b/test/constraints/table.jl index 5eb7abb7..9fc2382d 100644 --- a/test/constraints/table.jl +++ b/test/constraints/table.jl @@ -157,8 +157,6 @@ feasible = CS.prune_constraint!( com, constraint, - MOI.VectorOfVariables([x, y, z]), - CS.TableSetInternal(3, table), ) @test feasible # the 3 should be removed from z @@ -203,8 +201,6 @@ feasible = CS.prune_constraint!( com, constraint, - MOI.VectorOfVariables([x, y, z]), - CS.TableSetInternal(3, table), ) @test feasible # only 5:9 should be allowed for x but no other changes @@ -261,8 +257,6 @@ feasible = CS.prune_constraint!( com, constraint, - MOI.VectorOfVariables([x, y, z]), - CS.TableSetInternal(3, table), ) words_after_prune = copy(constraint.current.words) @@ -356,16 +350,12 @@ feasible = CS.prune_constraint!( com, constraint, - MOI.VectorOfVariables([x, y, z]), - CS.TableSetInternal(3, table), ) @test feasible feasible = CS.prune_constraint!( com, constraint2, - MOI.VectorOfVariables([x, y, z]), - CS.TableSetInternal(3, table2), ) @test feasible @@ -470,24 +460,18 @@ feasible = CS.prune_constraint!( com, constraint, - MOI.VectorOfVariables([x, y, z]), - CS.TableSetInternal(3, table), ) @test feasible feasible = CS.prune_constraint!( com, constraint2, - MOI.VectorOfVariables([y, z, a]), - CS.TableSetInternal(3, table2), ) @test feasible feasible = CS.prune_constraint!( com, constraint3, - MOI.VectorOfVariables([y, z, a]), - CS.TableSetInternal(3, table3), ) @test feasible diff --git a/test/general.jl b/test/general.jl index d1b18c88..0d233a3a 100644 --- a/test/general.jl +++ b/test/general.jl @@ -134,9 +134,9 @@ function is_solved(com::CS.CoM) for constraint in com.constraints values = CS.value.(com.search_space[constraint.indices]) c_solved = - CS.is_constraint_solved(constraint, constraint.fct, constraint.set, values) + CS.is_constraint_solved(com, constraint, values) c_violated = - CS.is_constraint_violated(com, constraint, constraint.fct, constraint.set) + CS.is_constraint_violated(com, constraint) if !c_solved || c_violated @error "Constraint $(constraint.idx) is not solved" @error "Info about constraint: $(typeof(constraint)), $(typeof(constraint.fct)), $(typeof(constraint.set))" diff --git a/test/small_special.jl b/test/small_special.jl index 7757e499..f2fd6d03 100644 --- a/test/small_special.jl +++ b/test/small_special.jl @@ -585,16 +585,16 @@ @variable(model, b >= 1, Bin) @variable(model, 0 <= x[1:4] <= 5, Int) @constraint(model, x[1] <= x[3]) - @constraint(model, b => {sum([0.4,0.5,0.7,0.8] .* x) > 9}) - @objective(model, Min, sum([0.4,0.5,0.7,0.8] .* x)) + @constraint(model, b => {sum([0.47,0.501,0.75,0.82] .* x) > 9}) + @objective(model, Min, sum([0.47,0.501,0.75,0.82] .* x)) optimize!(model) CS.get_inner_model(model) @test JuMP.termination_status(model) == MOI.OPTIMAL - @test JuMP.objective_value(model) ≈ 9.1 - @test JuMP.value(x[1]) ≈ 2.0 + @test JuMP.objective_value(model) ≈ 9.003 + @test JuMP.value(x[1]) ≈ 1.0 @test JuMP.value(x[2]) ≈ 3.0 - @test JuMP.value(x[3]) ≈ 4.0 - @test JuMP.value(x[4]) ≈ 5.0 + @test JuMP.value(x[3]) ≈ 5.0 + @test JuMP.value(x[4]) ≈ 4.0 end @testset "AllDifferent except 0" begin diff --git a/test/unit/constraints/alldifferent.jl b/test/unit/constraints/alldifferent.jl index 0fdd9315..776e3d62 100644 --- a/test/unit/constraints/alldifferent.jl +++ b/test/unit/constraints/alldifferent.jl @@ -8,8 +8,8 @@ constraint = get_constraints_by_type(com, CS.AllDifferentConstraint)[1] # doesn't check the length - @test CS.is_constraint_solved(constraint, constraint.fct, constraint.set, [1, 2, 3]) - @test !CS.is_constraint_solved(constraint, constraint.fct, constraint.set, [2, 2, 3]) + @test CS.is_constraint_solved(com, constraint, [1, 2, 3]) + @test !CS.is_constraint_solved(com, constraint, [2, 2, 3]) sorted_min = [1, 1, 2, 2, 3] sorted_max = [5, 5, 4, 4, 2] @@ -25,8 +25,6 @@ @test CS.still_feasible( com, constraint, - constraint.fct, - constraint.set, constr_indices[2], 5, ) @@ -34,8 +32,6 @@ @test !CS.still_feasible( com, constraint, - constraint.fct, - constraint.set, constr_indices[3], 5, ) @@ -50,8 +46,6 @@ @test CS.still_feasible( com, constraint, - constraint.fct, - constraint.set, constr_indices[3], 5, ) @@ -59,13 +53,13 @@ com.c_backtrack_idx = 1 # feasible and no changes - @test CS.prune_constraint!(com, constraint, constraint.fct, constraint.set) + @test CS.prune_constraint!(com, constraint) for ind in constr_indices @test sort(CS.values(com.search_space[ind])) == -5:5 end @test CS.fix!(com, com.search_space[constr_indices[2]], 5) @test CS.rm!(com, com.search_space[constr_indices[1]], 1) - @test CS.prune_constraint!(com, constraint, constraint.fct, constraint.set) + @test CS.prune_constraint!(com, constraint) for ind in constr_indices[3:end] @test sort(CS.values(com.search_space[ind])) == -5:4 end @@ -75,7 +69,7 @@ # 3 and 4 are taken by indices 3 and 4 so not available at other positions @test CS.remove_below!(com, com.search_space[constr_indices[3]], 3) @test CS.remove_below!(com, com.search_space[constr_indices[4]], 3) - @test CS.prune_constraint!(com, constraint, constraint.fct, constraint.set) + @test CS.prune_constraint!(com, constraint) for ind in constr_indices[3:4] @test sort(CS.values(com.search_space[ind])) == 3:4 end @@ -90,14 +84,14 @@ for ind in constr_indices[5:end] @test CS.remove_below!(com, com.search_space[constr_indices[ind]], -4) end - @test CS.prune_constraint!(com, constraint, constraint.fct, constraint.set) + @test CS.prune_constraint!(com, constraint) # but we need -4 to have enough values available @test CS.remove_below!(com, com.search_space[constr_indices[1]], -3) for ind in constr_indices[5:end] @test CS.remove_below!(com, com.search_space[constr_indices[ind]], -3) end - @test !CS.prune_constraint!(com, constraint, constraint.fct, constraint.set) + @test !CS.prune_constraint!(com, constraint) end @testset "all different with gap in variables" begin @@ -109,24 +103,23 @@ end constraint = get_constraints_by_type(com, CS.AllDifferentConstraint)[1] @test CS.is_constraint_solved( + com, constraint, - constraint.fct, - constraint.set, [-2, 0, 7, -5], ) - @test CS.prune_constraint!(com, constraint, constraint.fct, constraint.set) + @test CS.prune_constraint!(com, constraint) constr_indices = constraint.indices for ind in constr_indices @test sort(CS.values(com.search_space[ind])) == [-5, -2, 0, 3, 7] end @test CS.fix!(com, com.search_space[constr_indices[1]], -5) - @test CS.prune_constraint!(com, constraint, constraint.fct, constraint.set) + @test CS.prune_constraint!(com, constraint) for ind in constr_indices[2:4] @test sort(CS.values(com.search_space[ind])) == [-2, 0, 3, 7] end @test CS.rm!(com, com.search_space[constr_indices[2]], -2) - @test CS.prune_constraint!(com, constraint, constraint.fct, constraint.set) + @test CS.prune_constraint!(com, constraint) @test sort(CS.values(com.search_space[2])) == [0, 3, 7] for ind in constr_indices[3:4] @test sort(CS.values(com.search_space[ind])) == [-2, 0, 3, 7] @@ -134,7 +127,7 @@ end @test CS.remove_below!(com, com.search_space[constr_indices[3]], 2) @test CS.remove_below!(com, com.search_space[constr_indices[4]], 2) - @test CS.prune_constraint!(com, constraint, constraint.fct, constraint.set) + @test CS.prune_constraint!(com, constraint) @test CS.isfixed(com.search_space[2]) @test CS.value(com.search_space[2]) == 0 for ind in constr_indices[3:4] @@ -153,20 +146,19 @@ end constraint = get_constraints_by_type(com, CS.AllDifferentConstraint)[1] constr_indices = constraint.indices @test CS.is_constraint_solved( + com, constraint, - constraint.fct, - constraint.set, [0, 1, 2, 3, 1000, 2000], ) - @test CS.prune_constraint!(com, constraint, constraint.fct, constraint.set) + @test CS.prune_constraint!(com, constraint) @test CS.fix!(com, com.search_space[constr_indices[5]], 1000) - @test CS.prune_constraint!(com, constraint, constraint.fct, constraint.set) + @test CS.prune_constraint!(com, constraint) for ind in constr_indices[6:8] @test sort(CS.values(com.search_space[ind])) == 1001:3000 end @test CS.fix!(com, com.search_space[constr_indices[1]], 0) - @test CS.prune_constraint!(com, constraint, constraint.fct, constraint.set) + @test CS.prune_constraint!(com, constraint) for ind in constr_indices[2:4] @test sort(CS.values(com.search_space[ind])) == 1:3 end @@ -184,7 +176,7 @@ end variables = com.search_space @test CS.fix!(com, variables[1], 1; check_feasibility = false) @test CS.fix!(com, variables[2], 1; check_feasibility = false) - @test CS.is_constraint_violated(com, constraint, constraint.fct, constraint.set) + @test CS.is_constraint_violated(com, constraint) m = Model(optimizer_with_attributes(CS.Optimizer, "no_prune" => true, "logging" => [])) @variable(m, -5 <= x[1:10] <= 5, Int) @@ -197,7 +189,7 @@ end variables = com.search_space @test CS.fix!(com, variables[1], 1; check_feasibility = false) @test CS.fix!(com, variables[2], 2; check_feasibility = false) - @test !CS.is_constraint_violated(com, constraint, constraint.fct, constraint.set) + @test !CS.is_constraint_violated(com, constraint) end @testset "all 8queens solutions" begin diff --git a/test/unit/constraints/and.jl b/test/unit/constraints/and.jl index c8852ea0..5cd0752f 100644 --- a/test/unit/constraints/and.jl +++ b/test/unit/constraints/and.jl @@ -9,7 +9,7 @@ constraint = com.constraints[1] @test CS.fix!(com, variables[constraint.indices[1]], 1; check_feasibility = false) @test CS.fix!(com, variables[constraint.indices[2]], 1; check_feasibility = false) - @test CS.is_constraint_violated(com, constraint, constraint.fct, constraint.set) + @test CS.is_constraint_violated(com, constraint) ################# @@ -23,7 +23,7 @@ constraint = com.constraints[1] @test CS.fix!(com, variables[constraint.indices[1]], 1; check_feasibility = false) @test CS.fix!(com, variables[constraint.indices[2]], 2; check_feasibility = false) - @test CS.is_constraint_violated(com, constraint, constraint.fct, constraint.set) + @test CS.is_constraint_violated(com, constraint) ################# @@ -39,7 +39,7 @@ and_constraint = com.constraints[1].inner_constraint @test CS.fix!(com, variables[and_constraint.indices[1]], 0; check_feasibility = false) @test CS.fix!(com, variables[and_constraint.indices[2]], 2; check_feasibility = false) - @test CS.is_constraint_violated(com, and_constraint, and_constraint.fct, and_constraint.set) + @test CS.is_constraint_violated(com, and_constraint) ############################### @@ -55,7 +55,7 @@ and_constraint = com.constraints[1].inner_constraint @test CS.fix!(com, variables[and_constraint.indices[1]], 0; check_feasibility = false) @test CS.fix!(com, variables[and_constraint.indices[2]], 2; check_feasibility = false) - @test CS.is_constraint_violated(com, and_constraint, and_constraint.fct, and_constraint.set) + @test CS.is_constraint_violated(com, and_constraint) ################## @@ -70,7 +70,7 @@ constraint = com.constraints[1] @test CS.fix!(com, variables[constraint.indices[2]], 0; check_feasibility = false) @test CS.fix!(com, variables[constraint.indices[3]], 1; check_feasibility = false) - @test CS.is_constraint_solved(com, constraint, constraint.fct, constraint.set) + @test CS.is_constraint_solved(com, constraint) end @testset "Indicator fixed to 1 And constraint violated or solved?" begin @@ -85,7 +85,7 @@ end constraint = com.constraints[1] @test CS.fix!(com, variables[constraint.indices[2]], 1; check_feasibility = false) @test CS.fix!(com, variables[constraint.indices[3]], 1; check_feasibility = false) - @test CS.is_constraint_violated(com, constraint, constraint.fct, constraint.set) + @test CS.is_constraint_violated(com, constraint) ################# @@ -100,7 +100,7 @@ end constraint = com.constraints[1] @test CS.fix!(com, variables[constraint.indices[2]], 1; check_feasibility = false) @test CS.fix!(com, variables[constraint.indices[3]], 2; check_feasibility = false) - @test CS.is_constraint_violated(com, constraint, constraint.fct, constraint.set) + @test CS.is_constraint_violated(com, constraint) ################# @@ -116,7 +116,7 @@ end and_constraint = com.constraints[1].inner_constraint @test CS.fix!(com, variables[and_constraint.indices[1]], 0; check_feasibility = false) @test CS.fix!(com, variables[and_constraint.indices[2]], 2; check_feasibility = false) - @test CS.is_constraint_violated(com, and_constraint, and_constraint.fct, and_constraint.set) + @test CS.is_constraint_violated(com, and_constraint) m = Model(optimizer_with_attributes(CS.Optimizer, "no_prune" => true, "logging" => [])) @variable(m, b >= 1, Bin) @@ -130,7 +130,7 @@ end and_constraint = com.constraints[1].inner_constraint @test CS.fix!(com, variables[and_constraint.indices[1]], 0; check_feasibility = false) @test CS.fix!(com, variables[and_constraint.indices[2]], 2; check_feasibility = false) - @test CS.is_constraint_violated(com, and_constraint, and_constraint.fct, and_constraint.set) + @test CS.is_constraint_violated(com, and_constraint) ################## @@ -145,7 +145,7 @@ end constraint = com.constraints[1] @test CS.fix!(com, variables[constraint.indices[2]], 0; check_feasibility = false) @test CS.fix!(com, variables[constraint.indices[3]], 1; check_feasibility = false) - @test CS.is_constraint_solved(com, constraint, constraint.fct, constraint.set) + @test CS.is_constraint_solved(com, constraint) end @testset "reified And constraint prune_constraint!" begin @@ -162,7 +162,7 @@ end constr_indices = constraint.indices @test CS.fix!(com, variables[constraint.indices[3]], 0; check_feasibility = false) - @test !CS.prune_constraint!(com, constraint, constraint.fct, constraint.set) + @test !CS.prune_constraint!(com, constraint) end @testset "reified And constraint still feasible" begin @@ -179,7 +179,7 @@ end and_constraint = com.constraints[1].inner_constraint constr_indices = and_constraint.indices - @test CS.prune_constraint!(com, constraint, constraint.fct, constraint.set) + @test CS.prune_constraint!(com, constraint) # set x[2] to 0 => x[1] would need to be 2 which isn't possible - @test !CS.still_feasible(com, and_constraint, and_constraint.fct, and_constraint.set, and_constraint.indices[2], 0) + @test !CS.still_feasible(com, and_constraint, and_constraint.indices[2], 0) end \ No newline at end of file diff --git a/test/unit/constraints/complement.jl b/test/unit/constraints/complement.jl index 66b7f7d1..7d262851 100644 --- a/test/unit/constraints/complement.jl +++ b/test/unit/constraints/complement.jl @@ -9,7 +9,7 @@ constraint = com.constraints[1] @test CS.fix!(com, variables[constraint.indices[1]], 1; check_feasibility = false) @test CS.fix!(com, variables[constraint.indices[2]], 2; check_feasibility = false) - @test CS.is_constraint_solved(com, constraint, constraint.fct, constraint.set) + @test CS.is_constraint_solved(com, constraint) ################# @@ -23,7 +23,7 @@ constraint = com.constraints[1] @test CS.fix!(com, variables[constraint.indices[1]], 1; check_feasibility = false) @test CS.fix!(com, variables[constraint.indices[2]], 1; check_feasibility = false) - @test CS.is_constraint_solved(com, constraint, constraint.fct, constraint.set) + @test CS.is_constraint_solved(com, constraint) ################# @@ -39,7 +39,7 @@ xor_constraint = com.constraints[1].inner_constraint @test CS.fix!(com, variables[xor_constraint.indices[1]], 0; check_feasibility = false) @test CS.fix!(com, variables[xor_constraint.indices[2]], 2; check_feasibility = false) - @test CS.is_constraint_solved(com, xor_constraint, xor_constraint.fct, xor_constraint.set) + @test CS.is_constraint_solved(com, xor_constraint) ################# @@ -55,7 +55,7 @@ xor_constraint = com.constraints[1].inner_constraint @test CS.fix!(com, variables[xor_constraint.indices[1]], 0; check_feasibility = false) @test CS.fix!(com, variables[xor_constraint.indices[2]], 2; check_feasibility = false) - @test CS.is_constraint_solved(com, xor_constraint, xor_constraint.fct, xor_constraint.set) + @test CS.is_constraint_solved(com, xor_constraint) ############################### @@ -72,7 +72,7 @@ xor_constraint = com.constraints[1].inner_constraint @test CS.fix!(com, variables[xor_constraint.indices[1]], 0; check_feasibility = false) @test CS.fix!(com, variables[xor_constraint.indices[2]], 4; check_feasibility = false) - @test !CS.is_constraint_solved(com, xor_constraint, xor_constraint.fct, xor_constraint.set) + @test !CS.is_constraint_solved(com, xor_constraint) ################## @@ -87,7 +87,7 @@ constraint = com.constraints[1] @test CS.fix!(com, variables[constraint.indices[2]], 3; check_feasibility = false) @test CS.fix!(com, variables[constraint.indices[3]], 1; check_feasibility = false) - @test CS.is_constraint_violated(com, constraint, constraint.fct, constraint.set) + @test CS.is_constraint_violated(com, constraint) ################## @@ -103,7 +103,7 @@ constraint = com.constraints[1] @test CS.fix!(com, variables[constraint.indices[2]], 3; check_feasibility = false) @test CS.fix!(com, variables[constraint.indices[3]], 2; check_feasibility = false) - @test CS.is_constraint_violated(com, constraint, constraint.fct, constraint.set) + @test CS.is_constraint_violated(com, constraint) end @testset "complement constraint still feasible" begin @@ -120,7 +120,7 @@ end complement_constraint = com.constraints[1].inner_constraint constr_indices = complement_constraint.indices - @test CS.prune_constraint!(com, constraint, constraint.fct, constraint.set) - @test CS.still_feasible(com, complement_constraint, complement_constraint.fct, complement_constraint.set, complement_constraint.indices[1], 1) - @test !CS.still_feasible(com, complement_constraint, complement_constraint.fct, complement_constraint.set, complement_constraint.indices[1], 2) + @test CS.prune_constraint!(com, constraint) + @test CS.still_feasible(com, complement_constraint, complement_constraint.indices[1], 1) + @test !CS.still_feasible(com, complement_constraint, complement_constraint.indices[1], 2) end \ No newline at end of file diff --git a/test/unit/constraints/equal.jl b/test/unit/constraints/equal.jl index 1f7744f2..2b0e3721 100644 --- a/test/unit/constraints/equal.jl +++ b/test/unit/constraints/equal.jl @@ -8,15 +8,13 @@ constraint = com.constraints[1] # doesn't check the length - @test !CS.is_constraint_solved(constraint, constraint.fct, constraint.set, [1, 2, 3]) - @test CS.is_constraint_solved(constraint, constraint.fct, constraint.set, [2, 2, 2]) + @test !CS.is_constraint_solved(com, constraint, [1, 2, 3]) + @test CS.is_constraint_solved(com, constraint, [2, 2, 2]) constr_indices = constraint.indices @test CS.still_feasible( com, constraint, - constraint.fct, - constraint.set, constr_indices[2], 5, ) @@ -24,16 +22,12 @@ @test !CS.still_feasible( com, constraint, - constraint.fct, - constraint.set, constr_indices[3], 4, ) @test CS.still_feasible( com, constraint, - constraint.fct, - constraint.set, constr_indices[3], 5, ) @@ -50,8 +44,6 @@ @test CS.still_feasible( com, constraint, - constraint.fct, - constraint.set, constr_indices[3], 4, ) @@ -65,12 +57,12 @@ constr_indices = constraint.indices # feasible and no changes - @test CS.prune_constraint!(com, constraint, constraint.fct, constraint.set) + @test CS.prune_constraint!(com, constraint) for ind in constr_indices @test sort(CS.values(com.search_space[ind])) == -5:5 end @test CS.fix!(com, com.search_space[constr_indices[2]], 5) - @test CS.prune_constraint!(com, constraint, constraint.fct, constraint.set) + @test CS.prune_constraint!(com, constraint) for ind in constr_indices @test CS.value(com.search_space[ind]) == 5 @test CS.isfixed(com.search_space[ind]) @@ -87,19 +79,19 @@ # Should be synced to the other variables @test CS.remove_below!(com, com.search_space[constr_indices[3]], 3) - @test CS.prune_constraint!(com, constraint, constraint.fct, constraint.set) + @test CS.prune_constraint!(com, constraint) for ind in constr_indices @test sort(CS.values(com.search_space[ind])) == 3:5 end @test CS.rm!(com, com.search_space[constr_indices[1]], 5) - @test CS.prune_constraint!(com, constraint, constraint.fct, constraint.set) + @test CS.prune_constraint!(com, constraint) for ind in constr_indices @test sort(CS.values(com.search_space[ind])) == 3:4 end @test CS.rm!(com, com.search_space[constr_indices[2]], 3) - @test CS.prune_constraint!(com, constraint, constraint.fct, constraint.set) + @test CS.prune_constraint!(com, constraint) for ind in constr_indices @test CS.value(com.search_space[ind]) == 4 @test CS.isfixed(com.search_space[ind]) @@ -118,7 +110,7 @@ end variables = com.search_space @test CS.fix!(com, variables[1], 3; check_feasibility = false) @test CS.fix!(com, variables[2], 5; check_feasibility = false) - @test CS.is_constraint_violated(com, constraint, constraint.fct, constraint.set) + @test CS.is_constraint_violated(com, constraint) m = Model(optimizer_with_attributes(CS.Optimizer, "no_prune" => true, "logging" => [])) @variable(m, -5 <= x[1:5] <= 5, Int) @@ -131,5 +123,5 @@ end variables = com.search_space @test CS.fix!(com, variables[1], 5; check_feasibility = false) @test CS.fix!(com, variables[2], 5; check_feasibility = false) - @test !CS.is_constraint_violated(com, constraint, constraint.fct, constraint.set) + @test !CS.is_constraint_violated(com, constraint) end diff --git a/test/unit/constraints/equal_to.jl b/test/unit/constraints/equal_to.jl index b4b858db..befb4bd4 100644 --- a/test/unit/constraints/equal_to.jl +++ b/test/unit/constraints/equal_to.jl @@ -71,23 +71,19 @@ end # doesn't check the length # 1+2+1 + constant (1) == 5 - @test CS.is_constraint_solved(constraint, constraint.fct, constraint.set, [1, 2, 1]) - @test !CS.is_constraint_solved(constraint, constraint.fct, constraint.set, [1, 2, 2]) + @test CS.is_constraint_solved(com, constraint, [1, 2, 1]) + @test !CS.is_constraint_solved(com, constraint, [1, 2, 2]) constr_indices = constraint.indices @test !CS.still_feasible( com, constraint, - constraint.fct, - constraint.set, constr_indices[1], -3, ) @test CS.still_feasible( com, constraint, - constraint.fct, - constraint.set, constr_indices[1], 1, ) @@ -97,8 +93,6 @@ end @test !CS.still_feasible( com, constraint, - constraint.fct, - constraint.set, constr_indices[3], 1, ) @@ -114,20 +108,18 @@ end @test CS.still_feasible( com, constraint, - constraint.fct, - constraint.set, constr_indices[3], 1, ) # feasible but remove -3 and 3 - @test CS.prune_constraint!(com, constraint, constraint.fct, constraint.set) + @test CS.prune_constraint!(com, constraint) for ind in constr_indices @test sort(CS.values(com.search_space[ind])) == [1, 2] end @test CS.fix!(com, com.search_space[constr_indices[1]], 2) - @test CS.prune_constraint!(com, constraint, constraint.fct, constraint.set) + @test CS.prune_constraint!(com, constraint) for ind in constr_indices[2:3] @test CS.values(com.search_space[ind]) == [1] end @@ -146,7 +138,7 @@ end variables = com.search_space @test CS.fix!(com, variables[1], 1; check_feasibility = false) @test CS.fix!(com, variables[2], 1; check_feasibility = false) - @test CS.is_constraint_violated(com, constraint, constraint.fct, constraint.set) + @test CS.is_constraint_violated(com, constraint) m = Model(optimizer_with_attributes(CS.Optimizer, "no_prune" => true, "logging" => [])) @variable(m, -5 <= x[1:2] <= 5, Int) @@ -159,7 +151,7 @@ end variables = com.search_space @test CS.fix!(com, variables[1], 5; check_feasibility = false) @test CS.fix!(com, variables[2], 5; check_feasibility = false) - @test !CS.is_constraint_violated(com, constraint, constraint.fct, constraint.set) + @test !CS.is_constraint_violated(com, constraint) end @testset "constraint without variables" begin diff --git a/test/unit/constraints/geqset.jl b/test/unit/constraints/geqset.jl index 910185f1..96cd047d 100644 --- a/test/unit/constraints/geqset.jl +++ b/test/unit/constraints/geqset.jl @@ -9,15 +9,13 @@ constraint = com.constraints[1] # doesn't check the length - @test !CS.is_constraint_solved(constraint, constraint.fct, constraint.set, [1, 2, 3]) - @test CS.is_constraint_solved(constraint, constraint.fct, constraint.set, [3, 2, 1]) + @test !CS.is_constraint_solved(com, constraint, [1, 2, 3]) + @test CS.is_constraint_solved(com, constraint, [3, 2, 1]) constr_indices = constraint.indices @test CS.still_feasible( com, constraint, - constraint.fct, - constraint.set, constr_indices[1], 3, ) @@ -25,16 +23,12 @@ @test !CS.still_feasible( com, constraint, - constraint.fct, - constraint.set, constr_indices[2], 4, ) @test CS.still_feasible( com, constraint, - constraint.fct, - constraint.set, constr_indices[3], 2, ) @@ -51,8 +45,6 @@ @test CS.still_feasible( com, constraint, - constraint.fct, - constraint.set, constr_indices[2], 4, ) @@ -67,12 +59,12 @@ constr_indices = constraint.indices # feasible and no changes - @test CS.prune_constraint!(com, constraint, constraint.fct, constraint.set) + @test CS.prune_constraint!(com, constraint) for ind in constr_indices @test sort(CS.values(com.search_space[ind])) == -5:5 end @test CS.fix!(com, com.search_space[constr_indices[2]], 5) - @test CS.prune_constraint!(com, constraint, constraint.fct, constraint.set) + @test CS.prune_constraint!(com, constraint) @test CS.value(com.search_space[constr_indices[1]]) == 5 @test CS.isfixed(com.search_space[constr_indices[1]]) @@ -88,11 +80,11 @@ # Should be synced to the first variable @test CS.remove_below!(com, com.search_space[constr_indices[3]], 4) - @test CS.prune_constraint!(com, constraint, constraint.fct, constraint.set) + @test CS.prune_constraint!(com, constraint) @test sort(CS.values(com.search_space[constr_indices[1]])) == 4:5 @test CS.rm!(com, com.search_space[constr_indices[1]], 5) - @test CS.prune_constraint!(com, constraint, constraint.fct, constraint.set) + @test CS.prune_constraint!(com, constraint) @test sort(CS.values(com.search_space[constr_indices[2]])) == -5:4 @test sort(CS.values(com.search_space[constr_indices[3]])) == 4:4 end @@ -109,7 +101,7 @@ end variables = com.search_space @test CS.fix!(com, variables[1], 3; check_feasibility = false) @test CS.remove_below!(com, variables[2], 4; check_feasibility = false) - @test CS.is_constraint_violated(com, constraint, constraint.fct, constraint.set) + @test CS.is_constraint_violated(com, constraint) m = Model(optimizer_with_attributes(CS.Optimizer, "no_prune" => true, "logging" => [])) @variable(m, -5 <= x[1:5] <= 5, Int) @@ -122,5 +114,5 @@ end variables = com.search_space @test CS.fix!(com, variables[1], -5; check_feasibility = false) @test CS.fix!(com, variables[2], -5; check_feasibility = false) - @test !CS.is_constraint_violated(com, constraint, constraint.fct, constraint.set) + @test !CS.is_constraint_violated(com, constraint) end diff --git a/test/unit/constraints/indicator.jl b/test/unit/constraints/indicator.jl index 990e822a..316130d9 100644 --- a/test/unit/constraints/indicator.jl +++ b/test/unit/constraints/indicator.jl @@ -8,24 +8,20 @@ com = CS.get_inner_model(m) constraint = get_constraints_by_type(com, CS.IndicatorConstraint)[1] - @test CS.is_constraint_solved(constraint, constraint.fct, constraint.set, [1, 2, 2]) - @test !CS.is_constraint_solved(constraint, constraint.fct, constraint.set, [1, 2, 3]) - @test CS.is_constraint_solved(constraint, constraint.fct, constraint.set, [0, 2, 3]) + @test CS.is_constraint_solved(com, constraint, [1, 2, 2]) + @test !CS.is_constraint_solved(com, constraint, [1, 2, 3]) + @test CS.is_constraint_solved(com, constraint, [0, 2, 3]) constr_indices = constraint.indices @test CS.still_feasible( com, constraint, - constraint.fct, - constraint.set, constr_indices[2], -3, ) @test CS.still_feasible( com, constraint, - constraint.fct, - constraint.set, constr_indices[3], 1, ) @@ -35,8 +31,6 @@ @test !CS.still_feasible( com, constraint, - constraint.fct, - constraint.set, constr_indices[3], -3, ) @@ -52,20 +46,18 @@ @test CS.still_feasible( com, constraint, - constraint.fct, - constraint.set, constr_indices[3], -3, ) - @test CS.prune_constraint!(com, constraint, constraint.fct, constraint.set) + @test CS.prune_constraint!(com, constraint) for ind in constr_indices[2:3] @test sort(CS.values(com.search_space[ind])) == [-3, 1, 2, 3] end @test sort(CS.values(com.search_space[1])) == [0, 1] # feasible but remove -3 @test CS.fix!(com, com.search_space[constr_indices[1]], 1) - @test CS.prune_constraint!(com, constraint, constraint.fct, constraint.set) + @test CS.prune_constraint!(com, constraint) for ind in constr_indices[2:3] @test sort(CS.values(com.search_space[ind])) == [1, 2, 3] end @@ -96,7 +88,7 @@ end 4; check_feasibility = false, ) - @test CS.is_constraint_violated(com, constraint, constraint.fct, constraint.set) + @test CS.is_constraint_violated(com, constraint) m = Model(optimizer_with_attributes(CS.Optimizer, "no_prune" => true, "logging" => [])) @variable(m, b, Bin) @@ -121,7 +113,7 @@ end 3; check_feasibility = false, ) - @test !CS.is_constraint_violated(com, constraint, constraint.fct, constraint.set) + @test !CS.is_constraint_violated(com, constraint) m = Model(optimizer_with_attributes(CS.Optimizer, "no_prune" => true, "logging" => [])) @variable(m, b, Bin) @@ -146,5 +138,5 @@ end 4; check_feasibility = false, ) - @test !CS.is_constraint_violated(com, constraint, constraint.fct, constraint.set) + @test !CS.is_constraint_violated(com, constraint) end diff --git a/test/unit/constraints/less_than.jl b/test/unit/constraints/less_than.jl index 3520ff49..e5cb0539 100644 --- a/test/unit/constraints/less_than.jl +++ b/test/unit/constraints/less_than.jl @@ -8,23 +8,19 @@ com = CS.get_inner_model(m) constraint = com.constraints[1] - @test CS.is_constraint_solved(constraint, constraint.fct, constraint.set, [1, 2, 3]) - @test !CS.is_constraint_solved(constraint, constraint.fct, constraint.set, [3, 2, 1]) + @test CS.is_constraint_solved(com, constraint, [1, 2, 3]) + @test !CS.is_constraint_solved(com, constraint, [3, 2, 1]) constr_indices = constraint.indices @test !CS.still_feasible( com, constraint, - constraint.fct, - constraint.set, constr_indices[3], -5, ) @test CS.still_feasible( com, constraint, - constraint.fct, - constraint.set, constr_indices[3], -4, ) @@ -33,8 +29,6 @@ @test !CS.still_feasible( com, constraint, - constraint.fct, - constraint.set, constr_indices[3], -4, ) @@ -51,8 +45,6 @@ @test CS.still_feasible( com, constraint, - constraint.fct, - constraint.set, constr_indices[3], -4, ) @@ -67,13 +59,13 @@ constraint = com.constraints[1] constr_indices = constraint.indices - @test CS.prune_constraint!(com, constraint, constraint.fct, constraint.set) + @test CS.prune_constraint!(com, constraint) @test sort(CS.values(com.search_space[1])) == -1:5 @test sort(CS.values(com.search_space[2])) == -1:5 @test sort(CS.values(com.search_space[3])) == -4:5 @test CS.fix!(com, com.search_space[constr_indices[3]], -4) - @test CS.prune_constraint!(com, constraint, constraint.fct, constraint.set) + @test CS.prune_constraint!(com, constraint) @test CS.value(com.search_space[1]) == -1 @test CS.value(com.search_space[2]) == -1 @test CS.value(com.search_space[3]) == -4 @@ -94,7 +86,7 @@ end variables = com.search_space @test CS.fix!(com, variables[constraint.indices[1]], 5; check_feasibility = false) @test CS.fix!(com, variables[constraint.indices[2]], 3; check_feasibility = false) - @test CS.is_constraint_violated(com, constraint, constraint.fct, constraint.set) + @test CS.is_constraint_violated(com, constraint) m = Model(optimizer_with_attributes(CS.Optimizer, "no_prune" => true, "logging" => [])) @variable(m, -5 <= x[1:2] <= 5, Int) @@ -106,7 +98,7 @@ end variables = com.search_space @test CS.fix!(com, variables[constraint.indices[1]], 5; check_feasibility = false) - @test !CS.is_constraint_violated(com, constraint, constraint.fct, constraint.set) + @test !CS.is_constraint_violated(com, constraint) end @testset "constraint without variables" begin diff --git a/test/unit/constraints/not_equal.jl b/test/unit/constraints/not_equal.jl index c4162f86..91a45d0f 100644 --- a/test/unit/constraints/not_equal.jl +++ b/test/unit/constraints/not_equal.jl @@ -8,23 +8,19 @@ # doesn't check the length # 1+2+1 + constant (1) == 5 - @test !CS.is_constraint_solved(constraint, constraint.fct, constraint.set, [1, 2, 1]) - @test CS.is_constraint_solved(constraint, constraint.fct, constraint.set, [1, 2, 2]) + @test !CS.is_constraint_solved(com, constraint, [1, 2, 1]) + @test CS.is_constraint_solved(com, constraint, [1, 2, 2]) constr_indices = constraint.indices @test CS.still_feasible( com, constraint, - constraint.fct, - constraint.set, constr_indices[1], -3, ) @test CS.still_feasible( com, constraint, - constraint.fct, - constraint.set, constr_indices[1], 1, ) @@ -33,8 +29,6 @@ @test !CS.still_feasible( com, constraint, - constraint.fct, - constraint.set, constr_indices[3], 1, ) @@ -50,8 +44,6 @@ @test CS.still_feasible( com, constraint, - constraint.fct, - constraint.set, constr_indices[3], 1, ) @@ -66,7 +58,7 @@ CS.fix!(com, com.search_space[constr_indices[1]], 2) CS.fix!(com, com.search_space[constr_indices[2]], 1) - @test CS.prune_constraint!(com, constraint, constraint.fct, constraint.set) + @test CS.prune_constraint!(com, constraint) @test sort(CS.values(com.search_space[constr_indices[3]])) == [-3, 2, 3] end @@ -82,7 +74,7 @@ end variables = com.search_space @test CS.fix!(com, variables[constraint.indices[1]], 5; check_feasibility = false) @test CS.fix!(com, variables[constraint.indices[2]], 2; check_feasibility = false) - @test CS.is_constraint_violated(com, constraint, constraint.fct, constraint.set) + @test CS.is_constraint_violated(com, constraint) m = Model(optimizer_with_attributes(CS.Optimizer, "no_prune" => true, "logging" => [])) @variable(m, -5 <= x[1:2] <= 5, Int) @@ -94,5 +86,5 @@ end variables = com.search_space @test CS.fix!(com, variables[constraint.indices[1]], 5; check_feasibility = false) - @test !CS.is_constraint_violated(com, constraint, constraint.fct, constraint.set) + @test !CS.is_constraint_violated(com, constraint) end diff --git a/test/unit/constraints/or.jl b/test/unit/constraints/or.jl index 41b9e817..c13f1e02 100644 --- a/test/unit/constraints/or.jl +++ b/test/unit/constraints/or.jl @@ -9,7 +9,7 @@ constraint = com.constraints[1] @test CS.fix!(com, variables[constraint.indices[1]], 1; check_feasibility = false) @test CS.fix!(com, variables[constraint.indices[2]], 1; check_feasibility = false) - @test CS.is_constraint_violated(com, constraint, constraint.fct, constraint.set) + @test CS.is_constraint_violated(com, constraint) ################# @@ -24,7 +24,7 @@ constraint = com.constraints[1] @test CS.fix!(com, variables[constraint.indices[2]], 2; check_feasibility = false) @test CS.fix!(com, variables[constraint.indices[3]], 2; check_feasibility = false) - @test CS.is_constraint_violated(com, constraint, constraint.fct, constraint.set) + @test CS.is_constraint_violated(com, constraint) ################# @@ -40,7 +40,7 @@ or_constraint = com.constraints[1].inner_constraint @test CS.fix!(com, variables[or_constraint.indices[1]], 1; check_feasibility = false) @test CS.fix!(com, variables[or_constraint.indices[2]], 1; check_feasibility = false) - @test CS.is_constraint_violated(com, or_constraint, or_constraint.fct, or_constraint.set) + @test CS.is_constraint_violated(com, or_constraint) ############################### @@ -56,7 +56,7 @@ or_constraint = com.constraints[1].inner_constraint @test CS.fix!(com, variables[or_constraint.indices[1]], 1; check_feasibility = false) @test CS.fix!(com, variables[or_constraint.indices[2]], 1; check_feasibility = false) - @test CS.is_constraint_violated(com, or_constraint, or_constraint.fct, or_constraint.set) + @test CS.is_constraint_violated(com, or_constraint) ################## @@ -71,7 +71,7 @@ constraint = com.constraints[1] @test CS.fix!(com, variables[constraint.indices[2]], 1; check_feasibility = false) @test CS.fix!(com, variables[constraint.indices[3]], 1; check_feasibility = false) - @test CS.is_constraint_solved(com, constraint, constraint.fct, constraint.set) + @test CS.is_constraint_solved(com, constraint) end @testset "Indicator fixed to 1 or constraint violated or solved?" begin @@ -86,7 +86,7 @@ end constraint = com.constraints[1] @test CS.fix!(com, variables[constraint.indices[2]], 1; check_feasibility = false) @test CS.fix!(com, variables[constraint.indices[3]], 1; check_feasibility = false) - @test CS.is_constraint_violated(com, constraint, constraint.fct, constraint.set) + @test CS.is_constraint_violated(com, constraint) ################# @@ -101,7 +101,7 @@ end constraint = com.constraints[1] @test CS.fix!(com, variables[constraint.indices[2]], 2; check_feasibility = false) @test CS.fix!(com, variables[constraint.indices[3]], 2; check_feasibility = false) - @test CS.is_constraint_violated(com, constraint, constraint.fct, constraint.set) + @test CS.is_constraint_violated(com, constraint) ################# @@ -117,7 +117,7 @@ end or_constraint = com.constraints[1].inner_constraint @test CS.fix!(com, variables[or_constraint.indices[1]], 1; check_feasibility = false) @test CS.fix!(com, variables[or_constraint.indices[2]], 1; check_feasibility = false) - @test CS.is_constraint_violated(com, or_constraint, or_constraint.fct, or_constraint.set) + @test CS.is_constraint_violated(com, or_constraint) ############################### @@ -133,7 +133,7 @@ end or_constraint = com.constraints[1].inner_constraint @test CS.fix!(com, variables[or_constraint.indices[1]], 1; check_feasibility = false) @test CS.fix!(com, variables[or_constraint.indices[2]], 1; check_feasibility = false) - @test CS.is_constraint_violated(com, or_constraint, or_constraint.fct, or_constraint.set) + @test CS.is_constraint_violated(com, or_constraint) ################## @@ -148,7 +148,7 @@ end constraint = com.constraints[1] @test CS.fix!(com, variables[constraint.indices[2]], 1; check_feasibility = false) @test CS.fix!(com, variables[constraint.indices[3]], 1; check_feasibility = false) - @test CS.is_constraint_solved(com, constraint, constraint.fct, constraint.set) + @test CS.is_constraint_solved(com, constraint) end @testset "reified or constraint prune_constraint!" begin @@ -165,7 +165,7 @@ end constr_indices = constraint.indices @test CS.fix!(com, variables[constraint.indices[2]], 0; check_feasibility = false) - @test CS.prune_constraint!(com, constraint, constraint.fct, constraint.set) + @test CS.prune_constraint!(com, constraint) for v in 0:2 @test !CS.has(variables[constraint.indices[3]], v) end @@ -184,7 +184,7 @@ end constr_indices = constraint.indices @test CS.fix!(com, variables[constraint.indices[2]], 0; check_feasibility = false) - @test CS.prune_constraint!(com, constraint, constraint.fct, constraint.set) + @test CS.prune_constraint!(com, constraint) for v in 0:2 @test !CS.has(variables[constraint.indices[4]], v) end @@ -208,7 +208,7 @@ end constr_indices = or_constraint.indices @test CS.fix!(com, variables[constraint.indices[2]], 0; check_feasibility = false) @test CS.fix!(com, variables[constraint.indices[3]], 0; check_feasibility = false) - @test !CS.still_feasible(com, or_constraint, or_constraint.fct, or_constraint.set, constr_indices[3], 1) + @test !CS.still_feasible(com, or_constraint, constr_indices[3], 1) # swap lhs and rhs m = Model(optimizer_with_attributes(CS.Optimizer, "no_prune" => true, "logging" => [])) @@ -228,5 +228,5 @@ end constr_indices = or_constraint.indices @test CS.fix!(com, variables[constr_indices[2]], 0; check_feasibility = false) @test CS.fix!(com, variables[constr_indices[3]], 0; check_feasibility = false) - @test !CS.still_feasible(com, or_constraint, or_constraint.fct, or_constraint.set, constr_indices[1], 1) + @test !CS.still_feasible(com, or_constraint, constr_indices[1], 1) end \ No newline at end of file diff --git a/test/unit/constraints/reified.jl b/test/unit/constraints/reified.jl index 6797beae..9fd64ba4 100644 --- a/test/unit/constraints/reified.jl +++ b/test/unit/constraints/reified.jl @@ -9,24 +9,20 @@ constraint = com.constraints[1] variables = com.search_space - @test CS.is_constraint_solved(constraint, constraint.fct, constraint.set, [1, 3, 3, 5]) - @test !CS.is_constraint_solved(constraint, constraint.fct, constraint.set, [1, 2, 3, 5]) - @test CS.is_constraint_solved(constraint, constraint.fct, constraint.set, [0, 2, 3, 5]) + @test CS.is_constraint_solved(com, constraint, [1, 3, 3, 5]) + @test !CS.is_constraint_solved(com, constraint, [1, 2, 3, 5]) + @test CS.is_constraint_solved(com, constraint, [0, 2, 3, 5]) constr_indices = constraint.indices @test CS.still_feasible( com, constraint, - constraint.fct, - constraint.set, constr_indices[2], 1, ) @test CS.still_feasible( com, constraint, - constraint.fct, - constraint.set, constr_indices[2], 0, ) @@ -34,8 +30,6 @@ @test !CS.still_feasible( com, constraint, - constraint.fct, - constraint.set, constr_indices[3], 0, ) @@ -48,14 +42,14 @@ CS.reverse_pruning!(com, 1) com.c_backtrack_idx = 1 - @test CS.prune_constraint!(com, constraint, constraint.fct, constraint.set) + @test CS.prune_constraint!(com, constraint) for ind in constr_indices[2:4] @test sort(CS.values(com.search_space[ind])) == [0,1,2,3,4,5] end @test sort(CS.values(com.search_space[constr_indices[1]])) == [0, 1] @test CS.fix!(com, com.search_space[constr_indices[1]], 1) # feasible but remove 0 - @test CS.prune_constraint!(com, constraint, constraint.fct, constraint.set) + @test CS.prune_constraint!(com, constraint) for ind in constr_indices[2:4] @test sort(CS.values(com.search_space[ind])) == [1, 2, 3, 4, 5] end @@ -77,7 +71,7 @@ end @test CS.fix!(com, variables[constraint.indices[2]], 3; check_feasibility = false) @test CS.fix!(com, variables[constraint.indices[3]], 2; check_feasibility = false) @test CS.fix!(com, variables[constraint.indices[4]], 5; check_feasibility = false) - @test CS.is_constraint_violated(com, constraint, constraint.fct, constraint.set) + @test CS.is_constraint_violated(com, constraint) m = Model(optimizer_with_attributes(CS.Optimizer, "no_prune" => true, "logging" => [])) @variable(m, b, Bin) @@ -93,7 +87,7 @@ end @test CS.fix!(com, variables[constraint.indices[2]], 3; check_feasibility = false) @test CS.fix!(com, variables[constraint.indices[3]], 3; check_feasibility = false) @test CS.fix!(com, variables[constraint.indices[4]], 5; check_feasibility = false) - @test !CS.is_constraint_violated(com, constraint, constraint.fct, constraint.set) + @test !CS.is_constraint_violated(com, constraint) m = Model(optimizer_with_attributes(CS.Optimizer, "no_prune" => true, "logging" => [])) @variable(m, b, Bin) @@ -109,7 +103,7 @@ end @test CS.fix!(com, variables[constraint.indices[2]], 3; check_feasibility = false) @test CS.fix!(com, variables[constraint.indices[3]], 3; check_feasibility = false) @test CS.fix!(com, variables[constraint.indices[4]], 5; check_feasibility = false) - @test CS.is_constraint_violated(com, constraint, constraint.fct, constraint.set) + @test CS.is_constraint_violated(com, constraint) end @@ -127,7 +121,7 @@ end @test CS.fix!(com, variables[constraint.indices[1]], 1; check_feasibility = false) @test CS.fix!(com, variables[constraint.indices[2]], 3; check_feasibility = false) @test CS.fix!(com, variables[constraint.indices[3]], 3; check_feasibility = false) - @test CS.is_constraint_violated(com, constraint, constraint.fct, constraint.set) + @test CS.is_constraint_violated(com, constraint) m = Model(optimizer_with_attributes(CS.Optimizer, "no_prune" => true, "logging" => [])) @variable(m, b, Bin) @@ -142,7 +136,7 @@ end @test CS.fix!(com, variables[constraint.indices[1]], 1; check_feasibility = false) @test CS.fix!(com, variables[constraint.indices[2]], 1; check_feasibility = false) @test CS.fix!(com, variables[constraint.indices[3]], 3; check_feasibility = false) - @test !CS.is_constraint_violated(com, constraint, constraint.fct, constraint.set) + @test !CS.is_constraint_violated(com, constraint) m = Model(optimizer_with_attributes(CS.Optimizer, "no_prune" => true, "logging" => [])) @variable(m, b, Bin) @@ -157,7 +151,7 @@ end @test CS.fix!(com, variables[constraint.indices[1]], 0; check_feasibility = false) @test CS.fix!(com, variables[constraint.indices[2]], 3; check_feasibility = false) @test CS.fix!(com, variables[constraint.indices[3]], 3; check_feasibility = false) - @test !CS.is_constraint_violated(com, constraint, constraint.fct, constraint.set) + @test !CS.is_constraint_violated(com, constraint) end @testset "reified complement prune" begin @@ -179,7 +173,7 @@ end # set inactive @test CS.fix!(com, variables[constr_indices[1]], 0; check_feasibility = false) # should prune complement - @test CS.prune_constraint!(com, constraint, constraint.fct, constraint.set) + @test CS.prune_constraint!(com, constraint) for ind in constr_indices[2:4] @test sort(CS.values(com.search_space[ind])) == collect(0:10) @@ -203,7 +197,7 @@ end # set inactive @test CS.fix!(com, variables[constr_indices[1]], 0; check_feasibility = false) # should prune complement - @test CS.prune_constraint!(com, constraint, constraint.fct, constraint.set) + @test CS.prune_constraint!(com, constraint) for ind in constr_indices[2:4] @test sort(CS.values(com.search_space[ind])) == collect(1:5) @@ -229,7 +223,7 @@ end @test CS.fix!(com, variables[constr_indices[2]], 0; check_feasibility = false) @test CS.fix!(com, variables[constr_indices[3]], 5; check_feasibility = false) # should prune complement - @test CS.prune_constraint!(com, constraint, constraint.fct, constraint.set) + @test CS.prune_constraint!(com, constraint) for ind in constr_indices[4] @test sort(CS.values(com.search_space[ind])) == collect(0:4) @@ -255,7 +249,7 @@ end @test CS.fix!(com, variables[constr_indices[2]], 0; check_feasibility = false) @test CS.fix!(com, variables[constr_indices[3]], 5; check_feasibility = false) # should prune complement - @test CS.prune_constraint!(com, constraint, constraint.fct, constraint.set) + @test CS.prune_constraint!(com, constraint) for ind in constr_indices[4] @test sort(CS.values(com.search_space[ind])) == [5] @@ -280,16 +274,12 @@ end @test !CS.still_feasible( com, constraint, - constraint.fct, - constraint.set, constr_indices[1], 1, ) @test CS.still_feasible( com, constraint, - constraint.fct, - constraint.set, constr_indices[1], 0, ) @@ -313,16 +303,12 @@ end @test !CS.still_feasible( com, constraint, - constraint.fct, - constraint.set, constr_indices[1], 0, ) @test CS.still_feasible( com, constraint, - constraint.fct, - constraint.set, constr_indices[1], 1, ) diff --git a/test/unit/constraints/strictly_less_than.jl b/test/unit/constraints/strictly_less_than.jl index 30307ead..c9a5ab9d 100644 --- a/test/unit/constraints/strictly_less_than.jl +++ b/test/unit/constraints/strictly_less_than.jl @@ -8,23 +8,19 @@ com = CS.get_inner_model(m) constraint = com.constraints[1] - @test CS.is_constraint_solved(constraint, constraint.fct, constraint.set, [1, 1, 1]) - @test !CS.is_constraint_solved(constraint, constraint.fct, constraint.set, [1, 1, 2]) + @test CS.is_constraint_solved(com, constraint, [1, 1, 1]) + @test !CS.is_constraint_solved(com, constraint, [1, 1, 2]) constr_indices = constraint.indices @test !CS.still_feasible( com, constraint, - constraint.fct, - constraint.set, constr_indices[3], 6, ) @test CS.still_feasible( com, constraint, - constraint.fct, - constraint.set, constr_indices[3], 5, ) @@ -33,8 +29,6 @@ @test !CS.still_feasible( com, constraint, - constraint.fct, - constraint.set, constr_indices[3], 5, ) @@ -51,8 +45,6 @@ @test CS.still_feasible( com, constraint, - constraint.fct, - constraint.set, constr_indices[3], 5, ) @@ -67,13 +59,13 @@ constraint = com.constraints[1] constr_indices = constraint.indices - @test CS.prune_constraint!(com, constraint, constraint.fct, constraint.set) + @test CS.prune_constraint!(com, constraint) @test sort(CS.values(com.search_space[1])) == -1:5 @test sort(CS.values(com.search_space[2])) == -1:5 @test sort(CS.values(com.search_space[3])) == -5:5 # 6 not possible @test CS.fix!(com, com.search_space[constr_indices[3]], 5) - @test CS.prune_constraint!(com, constraint, constraint.fct, constraint.set) + @test CS.prune_constraint!(com, constraint) @test CS.value(com.search_space[1]) == -1 @test CS.value(com.search_space[2]) == -1 @test CS.value(com.search_space[3]) == 5 @@ -92,8 +84,8 @@ constraint = com.constraints[1] @test constraint.rhs ≈ 3 @test constraint.strict_rhs ≈ 3.999 - @test CS.is_constraint_solved(constraint, constraint.fct, constraint.set, [1, 1, 1]) - @test !CS.is_constraint_solved(constraint, constraint.fct, constraint.set, [1, 1, 2]) + @test CS.is_constraint_solved(com, constraint, [1, 1, 1]) + @test !CS.is_constraint_solved(com, constraint, [1, 1, 2]) m = Model(optimizer_with_attributes(CS.Optimizer, "no_prune" => true, "logging" => [])) @variable(m, -1 <= x <= 5, Int) @@ -106,8 +98,8 @@ constraint = com.constraints[1] @test constraint.rhs ≈ 4 @test constraint.strict_rhs ≈ 4.1 - @test CS.is_constraint_solved(constraint, constraint.fct, constraint.set, [1, 1, 1]) - @test CS.is_constraint_solved(constraint, constraint.fct, constraint.set, [1, 1, 2]) + @test CS.is_constraint_solved(com, constraint, [1, 1, 1]) + @test CS.is_constraint_solved(com, constraint, [1, 1, 2]) m = Model(optimizer_with_attributes(CS.Optimizer, "no_prune" => true, "logging" => [])) @variable(m, -1 <= x <= 5, Int) @@ -119,8 +111,8 @@ constraint = com.constraints[1] @test constraint.strict_rhs ≈ 4.1 - @test CS.is_constraint_solved(constraint, constraint.fct, constraint.set, [1, 1, 1]) - @test !CS.is_constraint_solved(constraint, constraint.fct, constraint.set, [1, 1, 2]) + @test CS.is_constraint_solved(com, constraint, [1, 1, 1]) + @test !CS.is_constraint_solved(com, constraint, [1, 1, 2]) end @testset "StrictlyGreaterThan (bridged)" begin @@ -133,24 +125,20 @@ end com = CS.get_inner_model(m) constraint = com.constraints[1] - @test !CS.is_constraint_solved(constraint, constraint.fct, constraint.set, [-1, 1, 1]) - @test !CS.is_constraint_solved(constraint, constraint.fct, constraint.set, [-1, 1, 2]) - @test CS.is_constraint_solved(constraint, constraint.fct, constraint.set, [-1, 2, 2]) + @test !CS.is_constraint_solved(com, constraint, [-1, 1, 1]) + @test !CS.is_constraint_solved(com, constraint, [-1, 1, 2]) + @test CS.is_constraint_solved(com, constraint, [-1, 2, 2]) constr_indices = constraint.indices @test !CS.still_feasible( com, constraint, - constraint.fct, - constraint.set, constr_indices[3], -6, ) @test CS.still_feasible( com, constraint, - constraint.fct, - constraint.set, constr_indices[3], -5, ) @@ -159,8 +147,6 @@ end @test !CS.still_feasible( com, constraint, - constraint.fct, - constraint.set, constr_indices[3], -5, ) @@ -177,8 +163,6 @@ end @test CS.still_feasible( com, constraint, - constraint.fct, - constraint.set, constr_indices[3], -5, ) @@ -193,13 +177,13 @@ end constraint = com.constraints[1] constr_indices = constraint.indices - @test CS.prune_constraint!(com, constraint, constraint.fct, constraint.set) + @test CS.prune_constraint!(com, constraint) @test sort(CS.values(com.search_space[1])) == -5:1 @test sort(CS.values(com.search_space[2])) == -1:5 @test sort(CS.values(com.search_space[3])) == -5:6 # -6 not possible @test CS.fix!(com, com.search_space[constr_indices[3]], -5) - @test CS.prune_constraint!(com, constraint, constraint.fct, constraint.set) + @test CS.prune_constraint!(com, constraint) @test CS.value(com.search_space[1]) == -5 @test CS.value(com.search_space[2]) == 5 @test CS.value(com.search_space[3]) == -5 @@ -218,9 +202,9 @@ end constraint = com.constraints[1] @test constraint.rhs ≈ -4 @test constraint.strict_rhs ≈ -3.999 - @test !CS.is_constraint_solved(constraint, constraint.fct, constraint.set, [1, 1, 1]) - @test CS.is_constraint_solved(constraint, constraint.fct, constraint.set, [1, 1, 2]) - @test CS.is_constraint_solved(constraint, constraint.fct, constraint.set, [1, 1, 3]) + @test !CS.is_constraint_solved(com, constraint, [1, 1, 1]) + @test CS.is_constraint_solved(com, constraint, [1, 1, 2]) + @test CS.is_constraint_solved(com, constraint, [1, 1, 3]) m = Model(optimizer_with_attributes(CS.Optimizer, "no_prune" => true, "logging" => [])) @variable(m, -1 <= x <= 5, Int) @@ -233,8 +217,8 @@ end constraint = com.constraints[1] @test constraint.rhs ≈ -5 @test constraint.strict_rhs ≈ -4.1 - @test !CS.is_constraint_solved(constraint, constraint.fct, constraint.set, [1, 1, 1]) - @test !CS.is_constraint_solved(constraint, constraint.fct, constraint.set, [1, 1, 2]) + @test !CS.is_constraint_solved(com, constraint, [1, 1, 1]) + @test !CS.is_constraint_solved(com, constraint, [1, 1, 2]) m = Model(optimizer_with_attributes(CS.Optimizer, "no_prune" => true, "logging" => [])) @variable(m, -1 <= x <= 5, Int) @@ -246,8 +230,8 @@ end constraint = com.constraints[1] @test constraint.strict_rhs ≈ -4.1 - @test !CS.is_constraint_solved(constraint, constraint.fct, constraint.set, [1, 1, 1]) - @test CS.is_constraint_solved(constraint, constraint.fct, constraint.set, [1, 1, 3]) + @test !CS.is_constraint_solved(com, constraint, [1, 1, 1]) + @test CS.is_constraint_solved(com, constraint, [1, 1, 3]) end @testset "StrictlyGreaterThan with LP solver" begin @@ -265,8 +249,8 @@ end constraint = com.constraints[1] @test constraint.rhs ≈ -4.2 @test constraint.strict_rhs ≈ -4.1 - @test !CS.is_constraint_solved(constraint, constraint.fct, constraint.set, [1, 1, 1]) - @test CS.is_constraint_solved(constraint, constraint.fct, constraint.set, [1, 1, 3]) + @test !CS.is_constraint_solved(com, constraint, [1, 1, 1]) + @test CS.is_constraint_solved(com, constraint, [1, 1, 3]) end @testset "strictly less than is_constraint_violated test" begin @@ -281,7 +265,7 @@ end variables = com.search_space @test CS.fix!(com, variables[constraint.indices[1]], 5; check_feasibility = false) @test CS.fix!(com, variables[constraint.indices[2]], 2; check_feasibility = false) - @test CS.is_constraint_violated(com, constraint, constraint.fct, constraint.set) + @test CS.is_constraint_violated(com, constraint) m = Model(optimizer_with_attributes(CS.Optimizer, "no_prune" => true, "logging" => [])) @variable(m, -5 <= x[1:2] <= 5, Int) @@ -293,7 +277,7 @@ end variables = com.search_space @test CS.fix!(com, variables[constraint.indices[1]], 5; check_feasibility = false) - @test !CS.is_constraint_violated(com, constraint, constraint.fct, constraint.set) + @test !CS.is_constraint_violated(com, constraint) end @testset "constraint without variables" begin diff --git a/test/unit/constraints/svc.jl b/test/unit/constraints/svc.jl index bb844cb7..d3e51d1d 100644 --- a/test/unit/constraints/svc.jl +++ b/test/unit/constraints/svc.jl @@ -10,16 +10,14 @@ @test constraint isa CS.SingleVariableConstraint # doesn't check the length - @test !CS.is_constraint_solved(constraint, constraint.fct, constraint.set, [3, 2]) - @test CS.is_constraint_solved(constraint, constraint.fct, constraint.set, [2, 2]) - @test CS.is_constraint_solved(constraint, constraint.fct, constraint.set, [1, 2]) + @test !CS.is_constraint_solved(com, constraint, [3, 2]) + @test CS.is_constraint_solved(com, constraint, [2, 2]) + @test CS.is_constraint_solved(com, constraint, [1, 2]) constr_indices = constraint.indices @test CS.still_feasible( com, constraint, - constraint.fct, - constraint.set, constr_indices[2], -5, ) @@ -27,16 +25,12 @@ @test !CS.still_feasible( com, constraint, - constraint.fct, - constraint.set, constr_indices[1], 4, ) @test CS.still_feasible( com, constraint, - constraint.fct, - constraint.set, constr_indices[1], 3, ) @@ -52,8 +46,6 @@ @test CS.still_feasible( com, constraint, - constraint.fct, - constraint.set, constr_indices[1], 4, ) @@ -67,12 +59,12 @@ constraint = com.constraints[1] # feasible and no changes - @test CS.prune_constraint!(com, constraint, constraint.fct, constraint.set) + @test CS.prune_constraint!(com, constraint) for ind in constr_indices @test sort(CS.values(com.search_space[ind])) == -5:5 end @test CS.fix!(com, com.search_space[constr_indices[2]], 4) - @test CS.prune_constraint!(com, constraint, constraint.fct, constraint.set) + @test CS.prune_constraint!(com, constraint) @test sort(CS.values(com.search_space[1])) == -5:4 @@ -86,7 +78,7 @@ # Should be synced to the other variables @test CS.remove_above!(com, com.search_space[constr_indices[2]], 1) - @test CS.prune_constraint!(com, constraint, constraint.fct, constraint.set) + @test CS.prune_constraint!(com, constraint) for ind in constr_indices @test sort(CS.values(com.search_space[ind])) == -5:1 end @@ -104,7 +96,7 @@ end variables = com.search_space @test CS.fix!(com, variables[constraint.indices[1]], 5; check_feasibility = false) - @test CS.is_constraint_violated(com, constraint, constraint.fct, constraint.set) + @test CS.is_constraint_violated(com, constraint) m = Model(optimizer_with_attributes(CS.Optimizer, "no_prune" => true, "logging" => [])) @variable(m, 0 <= x <= 5, Int) @@ -117,5 +109,5 @@ end variables = com.search_space @test CS.fix!(com, variables[constraint.indices[1]], 3; check_feasibility = false) - @test !CS.is_constraint_violated(com, constraint, constraint.fct, constraint.set) + @test !CS.is_constraint_violated(com, constraint) end diff --git a/test/unit/constraints/table.jl b/test/unit/constraints/table.jl index e397799f..ca911c64 100644 --- a/test/unit/constraints/table.jl +++ b/test/unit/constraints/table.jl @@ -26,14 +26,12 @@ @test sort(CS.values(com.search_space[ind])) == 1:4 end - @test !CS.is_constraint_solved(constraint, constraint.fct, constraint.set, [1, 2, 4]) - @test CS.is_constraint_solved(constraint, constraint.fct, constraint.set, [1, 2, 3]) + @test !CS.is_constraint_solved(com, constraint, [1, 2, 4]) + @test CS.is_constraint_solved(com, constraint, [1, 2, 3]) @test CS.still_feasible( com, constraint, - constraint.fct, - constraint.set, constr_indices[1], 4, ) @@ -41,8 +39,6 @@ @test !CS.still_feasible( com, constraint, - constraint.fct, - constraint.set, constr_indices[1], 4, ) @@ -58,8 +54,6 @@ @test CS.still_feasible( com, constraint, - constraint.fct, - constraint.set, constr_indices[1], 4, ) @@ -88,7 +82,7 @@ constr_indices = constraint.indices @test CS.fix!(com, com.search_space[constr_indices[2]], 2) - @test CS.prune_constraint!(com, constraint, constraint.fct, constraint.set) + @test CS.prune_constraint!(com, constraint) for ind in constr_indices[[1, 3]] @test sort(CS.values(com.search_space[ind])) == [1, 3] end @@ -116,7 +110,7 @@ constr_indices = constraint.indices @test CS.fix!(com, com.search_space[constr_indices[2]], 4) - @test CS.prune_constraint!(com, constraint, constraint.fct, constraint.set) + @test CS.prune_constraint!(com, constraint) for ind in constr_indices @test CS.isfixed(com.search_space[ind]) @test CS.value(com.search_space[ind]) == 4 @@ -141,7 +135,7 @@ end variables = com.search_space @test CS.fix!(com, variables[constraint.indices[1]], 1; check_feasibility = false) @test CS.fix!(com, variables[constraint.indices[2]], 3; check_feasibility = false) - @test CS.is_constraint_violated(com, constraint, constraint.fct, constraint.set) + @test CS.is_constraint_violated(com, constraint) m = Model(optimizer_with_attributes(CS.Optimizer, "no_prune" => true, "logging" => [])) @variable(m, 0 <= x <= 5, Int) @@ -160,7 +154,7 @@ end variables = com.search_space @test CS.fix!(com, variables[constraint.indices[1]], 1; check_feasibility = false) @test CS.fix!(com, variables[constraint.indices[2]], 2; check_feasibility = false) - @test !CS.is_constraint_violated(com, constraint, constraint.fct, constraint.set) + @test !CS.is_constraint_violated(com, constraint) end diff --git a/test/unit/constraints/xnor.jl b/test/unit/constraints/xnor.jl index 538411ca..d3b3f254 100644 --- a/test/unit/constraints/xnor.jl +++ b/test/unit/constraints/xnor.jl @@ -9,7 +9,7 @@ constraint = com.constraints[1] @test CS.fix!(com, variables[constraint.indices[1]], 1; check_feasibility = false) @test CS.fix!(com, variables[constraint.indices[2]], 2; check_feasibility = false) - @test CS.is_constraint_solved(com, constraint, constraint.fct, constraint.set) + @test CS.is_constraint_solved(com, constraint) ################# @@ -23,7 +23,7 @@ constraint = com.constraints[1] @test CS.fix!(com, variables[constraint.indices[1]], 1; check_feasibility = false) @test CS.fix!(com, variables[constraint.indices[2]], 1; check_feasibility = false) - @test CS.is_constraint_solved(com, constraint, constraint.fct, constraint.set) + @test CS.is_constraint_solved(com, constraint) ################# @@ -39,7 +39,7 @@ xor_constraint = com.constraints[1].inner_constraint @test CS.fix!(com, variables[xor_constraint.indices[1]], 0; check_feasibility = false) @test CS.fix!(com, variables[xor_constraint.indices[2]], 2; check_feasibility = false) - @test CS.is_constraint_solved(com, xor_constraint, xor_constraint.fct, xor_constraint.set) + @test CS.is_constraint_solved(com, xor_constraint) ############################### @@ -55,7 +55,7 @@ xor_constraint = com.constraints[1].inner_constraint @test CS.fix!(com, variables[xor_constraint.indices[1]], 0; check_feasibility = false) @test CS.fix!(com, variables[xor_constraint.indices[2]], 4; check_feasibility = false) - @test !CS.is_constraint_solved(com, xor_constraint, xor_constraint.fct, xor_constraint.set) + @test !CS.is_constraint_solved(com, xor_constraint) ################## @@ -70,7 +70,7 @@ constraint = com.constraints[1] @test CS.fix!(com, variables[constraint.indices[2]], 0; check_feasibility = false) @test CS.fix!(com, variables[constraint.indices[3]], 1; check_feasibility = false) - @test CS.is_constraint_violated(com, constraint, constraint.fct, constraint.set) + @test CS.is_constraint_violated(com, constraint) ################## @@ -86,7 +86,7 @@ constraint = com.constraints[1] @test CS.fix!(com, variables[constraint.indices[2]], 0; check_feasibility = false) @test CS.fix!(com, variables[constraint.indices[3]], 1; check_feasibility = false) - @test CS.is_constraint_violated(com, constraint, constraint.fct, constraint.set) + @test CS.is_constraint_violated(com, constraint) ################## @@ -101,7 +101,7 @@ constraint = com.constraints[1] @test CS.fix!(com, variables[constraint.indices[2]], 0; check_feasibility = false) @test CS.fix!(com, variables[constraint.indices[3]], 1; check_feasibility = false) - @test CS.is_constraint_violated(com, constraint, constraint.fct, constraint.set) + @test CS.is_constraint_violated(com, constraint) end @testset "Indicator fixed to 1 xnor constraint violated or solved?" begin @@ -116,7 +116,7 @@ end constraint = com.constraints[1] @test CS.fix!(com, variables[constraint.indices[2]], 1; check_feasibility = false) @test CS.fix!(com, variables[constraint.indices[3]], 1; check_feasibility = false) - @test CS.is_constraint_solved(com, constraint, constraint.fct, constraint.set) + @test CS.is_constraint_solved(com, constraint) ################# @@ -132,7 +132,7 @@ end constraint = com.constraints[1] @test CS.fix!(com, variables[constraint.indices[2]], 1; check_feasibility = false) @test CS.fix!(com, variables[constraint.indices[3]], 1; check_feasibility = false) - @test CS.is_constraint_solved(com, constraint, constraint.fct, constraint.set) + @test CS.is_constraint_solved(com, constraint) ################# @@ -148,7 +148,7 @@ end xor_constraint = com.constraints[1].inner_constraint @test CS.fix!(com, variables[xor_constraint.indices[1]], 0; check_feasibility = false) @test CS.fix!(com, variables[xor_constraint.indices[2]], 2; check_feasibility = false) - @test CS.is_constraint_solved(com, xor_constraint, xor_constraint.fct, xor_constraint.set) + @test CS.is_constraint_solved(com, xor_constraint) ################## @@ -163,7 +163,7 @@ end constraint = com.constraints[1] @test CS.fix!(com, variables[constraint.indices[2]], 0; check_feasibility = false) @test CS.fix!(com, variables[constraint.indices[3]], 0; check_feasibility = false) - @test CS.is_constraint_violated(com, constraint, constraint.fct, constraint.set) + @test CS.is_constraint_violated(com, constraint) end @testset "reified xnor constraint prune_constraint!" begin @@ -180,7 +180,7 @@ end constr_indices = constraint.indices @test CS.fix!(com, variables[constraint.indices[3]], 0; check_feasibility = false) - @test CS.prune_constraint!(com, constraint, constraint.fct, constraint.set) + @test CS.prune_constraint!(com, constraint) @test sort(CS.values(m, x[1])) == [0,1,2] end @@ -198,9 +198,9 @@ end xor_constraint = com.constraints[1].inner_constraint constr_indices = xor_constraint.indices - @test CS.prune_constraint!(com, constraint, constraint.fct, constraint.set) - @test CS.still_feasible(com, xor_constraint, xor_constraint.fct, xor_constraint.set, xor_constraint.indices[2], 0) - @test CS.still_feasible(com, xor_constraint, xor_constraint.fct, xor_constraint.set, xor_constraint.indices[2], 3) + @test CS.prune_constraint!(com, constraint) + @test CS.still_feasible(com, xor_constraint, xor_constraint.indices[2], 0) + @test CS.still_feasible(com, xor_constraint, xor_constraint.indices[2], 3) end @testset "xnor constraint still feasible" begin @@ -215,9 +215,9 @@ end xnor_constraint = com.constraints[1] constr_indices = xnor_constraint.indices - @test CS.still_feasible(com, xnor_constraint, xnor_constraint.fct, xnor_constraint.set, 1, 0) + @test CS.still_feasible(com, xnor_constraint, 1, 0) @test CS.fix!(com, variables[2], 1; check_feasibility = false) - @test !CS.still_feasible(com, xnor_constraint, xnor_constraint.fct, xnor_constraint.set, 1, 3) + @test !CS.still_feasible(com, xnor_constraint, 1, 3) ### @@ -232,9 +232,9 @@ end xnor_constraint = com.constraints[1] constr_indices = xnor_constraint.indices - @test CS.still_feasible(com, xnor_constraint, xnor_constraint.fct, xnor_constraint.set, 2, 0) + @test CS.still_feasible(com, xnor_constraint, 2, 0) @test CS.fix!(com, variables[1], 1; check_feasibility = false) - @test !CS.still_feasible(com, xnor_constraint, xnor_constraint.fct, xnor_constraint.set, 2, 3) + @test !CS.still_feasible(com, xnor_constraint, 2, 3) end @@ -251,7 +251,7 @@ end constr_indices = xnor_constraint.indices # is already solved as both are violated no pruning possible - @test CS.prune_constraint!(com, xnor_constraint, xnor_constraint.fct, xnor_constraint.set) + @test CS.prune_constraint!(com, xnor_constraint) ### @@ -267,7 +267,7 @@ end constr_indices = xnor_constraint.indices # is already solved as both are subconstraints are solved => no pruning possible - @test CS.prune_constraint!(com, xnor_constraint, xnor_constraint.fct, xnor_constraint.set) + @test CS.prune_constraint!(com, xnor_constraint) ### @@ -283,7 +283,7 @@ end constr_indices = xnor_constraint.indices # lhs solved => rhs must be solved - @test CS.prune_constraint!(com, xnor_constraint, xnor_constraint.fct, xnor_constraint.set) + @test CS.prune_constraint!(com, xnor_constraint) @test CS.values(variables[2]) == [5] ### @@ -300,7 +300,7 @@ end constr_indices = xnor_constraint.indices # lhs violated => rhs must be complement solved - @test CS.prune_constraint!(com, xnor_constraint, xnor_constraint.fct, xnor_constraint.set) + @test CS.prune_constraint!(com, xnor_constraint) @test sort!(CS.values(variables[2])) == [2,3,4] ### @@ -317,7 +317,7 @@ end constr_indices = xnor_constraint.indices # rhs violated => lhs must be complement solved - @test CS.prune_constraint!(com, xnor_constraint, xnor_constraint.fct, xnor_constraint.set) + @test CS.prune_constraint!(com, xnor_constraint) # the variables can't be 0 as otherwise we can't fullfil the complement x[1]+x[2] > 5 @test !CS.has(variables[1], 0) @test !CS.has(variables[2], 0) diff --git a/test/unit/constraints/xor.jl b/test/unit/constraints/xor.jl index ad26ab8c..be81b50a 100644 --- a/test/unit/constraints/xor.jl +++ b/test/unit/constraints/xor.jl @@ -9,7 +9,7 @@ constraint = com.constraints[1] @test CS.fix!(com, variables[constraint.indices[1]], 1; check_feasibility = false) @test CS.fix!(com, variables[constraint.indices[2]], 2; check_feasibility = false) - @test CS.is_constraint_violated(com, constraint, constraint.fct, constraint.set) + @test CS.is_constraint_violated(com, constraint) ################# @@ -23,7 +23,7 @@ constraint = com.constraints[1] @test CS.fix!(com, variables[constraint.indices[1]], 1; check_feasibility = false) @test CS.fix!(com, variables[constraint.indices[2]], 1; check_feasibility = false) - @test CS.is_constraint_violated(com, constraint, constraint.fct, constraint.set) + @test CS.is_constraint_violated(com, constraint) ################# @@ -39,7 +39,7 @@ xor_constraint = com.constraints[1].inner_constraint @test CS.fix!(com, variables[xor_constraint.indices[1]], 0; check_feasibility = false) @test CS.fix!(com, variables[xor_constraint.indices[2]], 2; check_feasibility = false) - @test CS.is_constraint_violated(com, xor_constraint, xor_constraint.fct, xor_constraint.set) + @test CS.is_constraint_violated(com, xor_constraint) ############################### @@ -55,7 +55,7 @@ xor_constraint = com.constraints[1].inner_constraint @test CS.fix!(com, variables[xor_constraint.indices[1]], 0; check_feasibility = false) @test CS.fix!(com, variables[xor_constraint.indices[2]], 4; check_feasibility = false) - @test !CS.is_constraint_violated(com, xor_constraint, xor_constraint.fct, xor_constraint.set) + @test !CS.is_constraint_violated(com, xor_constraint) ################## @@ -70,7 +70,7 @@ constraint = com.constraints[1] @test CS.fix!(com, variables[constraint.indices[2]], 0; check_feasibility = false) @test CS.fix!(com, variables[constraint.indices[3]], 1; check_feasibility = false) - @test CS.is_constraint_solved(com, constraint, constraint.fct, constraint.set) + @test CS.is_constraint_solved(com, constraint) ################## @@ -86,7 +86,7 @@ constraint = com.constraints[1] @test CS.fix!(com, variables[constraint.indices[2]], 0; check_feasibility = false) @test CS.fix!(com, variables[constraint.indices[3]], 1; check_feasibility = false) - @test CS.is_constraint_solved(com, constraint, constraint.fct, constraint.set) + @test CS.is_constraint_solved(com, constraint) ################## @@ -101,7 +101,7 @@ constraint = com.constraints[1] @test CS.fix!(com, variables[constraint.indices[2]], 0; check_feasibility = false) @test CS.fix!(com, variables[constraint.indices[3]], 1; check_feasibility = false) - @test CS.is_constraint_solved(com, constraint, constraint.fct, constraint.set) + @test CS.is_constraint_solved(com, constraint) end @testset "Indicator fixed to 1 xor constraint violated or solved?" begin @@ -116,7 +116,7 @@ end constraint = com.constraints[1] @test CS.fix!(com, variables[constraint.indices[2]], 1; check_feasibility = false) @test CS.fix!(com, variables[constraint.indices[3]], 1; check_feasibility = false) - @test CS.is_constraint_violated(com, constraint, constraint.fct, constraint.set) + @test CS.is_constraint_violated(com, constraint) ################# @@ -132,7 +132,7 @@ end constraint = com.constraints[1] @test CS.fix!(com, variables[constraint.indices[2]], 1; check_feasibility = false) @test CS.fix!(com, variables[constraint.indices[3]], 1; check_feasibility = false) - @test CS.is_constraint_violated(com, constraint, constraint.fct, constraint.set) + @test CS.is_constraint_violated(com, constraint) ################# @@ -148,7 +148,7 @@ end xor_constraint = com.constraints[1].inner_constraint @test CS.fix!(com, variables[xor_constraint.indices[1]], 0; check_feasibility = false) @test CS.fix!(com, variables[xor_constraint.indices[2]], 2; check_feasibility = false) - @test CS.is_constraint_violated(com, xor_constraint, xor_constraint.fct, xor_constraint.set) + @test CS.is_constraint_violated(com, xor_constraint) ################## @@ -163,7 +163,7 @@ end constraint = com.constraints[1] @test CS.fix!(com, variables[constraint.indices[2]], 0; check_feasibility = false) @test CS.fix!(com, variables[constraint.indices[3]], 0; check_feasibility = false) - @test CS.is_constraint_solved(com, constraint, constraint.fct, constraint.set) + @test CS.is_constraint_solved(com, constraint) end @testset "reified xor constraint prune_constraint!" begin @@ -180,7 +180,7 @@ end constr_indices = constraint.indices @test CS.fix!(com, variables[constraint.indices[3]], 0; check_feasibility = false) - @test CS.prune_constraint!(com, constraint, constraint.fct, constraint.set) + @test CS.prune_constraint!(com, constraint) @test sort(CS.values(m, x[1])) == [3,4,5] end @@ -198,10 +198,10 @@ end xor_constraint = com.constraints[1].inner_constraint constr_indices = xor_constraint.indices - @test CS.prune_constraint!(com, constraint, constraint.fct, constraint.set) + @test CS.prune_constraint!(com, constraint) # set x[2] to 0 - @test CS.still_feasible(com, xor_constraint, xor_constraint.fct, xor_constraint.set, xor_constraint.indices[2], 0) - @test CS.still_feasible(com, xor_constraint, xor_constraint.fct, xor_constraint.set, xor_constraint.indices[2], 3) + @test CS.still_feasible(com, xor_constraint, xor_constraint.indices[2], 0) + @test CS.still_feasible(com, xor_constraint, xor_constraint.indices[2], 3) end @testset "reified xor constraint prune_constraint" begin @@ -218,7 +218,7 @@ end xor_constraint = com.constraints[1].inner_constraint constr_indices = xor_constraint.indices - @test !CS.prune_constraint!(com, constraint, constraint.fct, constraint.set) + @test !CS.prune_constraint!(com, constraint) ########################## @@ -235,7 +235,7 @@ end xor_constraint = com.constraints[1].inner_constraint constr_indices = xor_constraint.indices - @test !CS.prune_constraint!(com, constraint, constraint.fct, constraint.set) + @test !CS.prune_constraint!(com, constraint) ########################## @@ -252,5 +252,5 @@ end xor_constraint = com.constraints[1].inner_constraint constr_indices = xor_constraint.indices - @test CS.prune_constraint!(com, constraint, constraint.fct, constraint.set) + @test CS.prune_constraint!(com, constraint) end From b9ca8230a57f031fde51b725aa37c04a1532ed42 Mon Sep 17 00:00:00 2001 From: Ole Kroeger Date: Sun, 22 Aug 2021 22:22:49 +0200 Subject: [PATCH 07/10] removed recompute_lc_extrema! from linear prune --- src/constraints/linear_constraints.jl | 1 - test/unit/constraints/equal_to.jl | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/src/constraints/linear_constraints.jl b/src/constraints/linear_constraints.jl index 891e1a84..c1e176ad 100644 --- a/src/constraints/linear_constraints.jl +++ b/src/constraints/linear_constraints.jl @@ -278,7 +278,6 @@ function _prune_constraint!( logs = false, ) where {T<:Real} constraint.currently_pruning = true - recompute_lc_extrema!(com, constraint, fct) isfeasible = _prune_constraint_actual!(com, constraint, fct, set; logs=logs) constraint.currently_pruning = false return isfeasible diff --git a/test/unit/constraints/equal_to.jl b/test/unit/constraints/equal_to.jl index befb4bd4..7e005164 100644 --- a/test/unit/constraints/equal_to.jl +++ b/test/unit/constraints/equal_to.jl @@ -114,6 +114,7 @@ end # feasible but remove -3 and 3 + CS.set_first_node_call!(constraint, true) @test CS.prune_constraint!(com, constraint) for ind in constr_indices @test sort(CS.values(com.search_space[ind])) == [1, 2] From 06fe2e60848a1f5e664fcf21e0f3b925caab9edd Mon Sep 17 00:00:00 2001 From: Ole Kroeger Date: Sat, 11 Sep 2021 12:43:12 +0200 Subject: [PATCH 08/10] call set_first_node_call! in set_bounds! --- .github/workflows/ci.yml | 2 +- src/ConstraintSolver.jl | 19 +++++++++++++++++++ src/pruning.jl | 4 ---- 3 files changed, 20 insertions(+), 5 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2a6cda6a..78aaff35 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -11,7 +11,7 @@ jobs: matrix: version: - '1.2' - - '1.5' + - '1.6' os: - ubuntu-latest - macOS-latest diff --git a/src/ConstraintSolver.jl b/src/ConstraintSolver.jl index c556bca0..27f3557b 100644 --- a/src/ConstraintSolver.jl +++ b/src/ConstraintSolver.jl @@ -381,6 +381,13 @@ Return if simple removable is still feasible """ function set_bounds!(com, backtrack_obj) vidx = backtrack_obj.vidx + + # set all first node calls to true as there might have been a reverse pruning + # Todo: Actually only do this when there was reverse pruning... + for constraint in com.constraints + set_first_node_call!(constraint, true) + end + !remove_above!(com, com.search_space[vidx], backtrack_obj.ub) && return false !remove_below!(com, com.search_space[vidx], backtrack_obj.lb) && return false return true @@ -757,6 +764,13 @@ function solve!(com::CS.CoM) options.no_prune && return :NotSolved + # set for all constraints that a new round of pruning is initialized + # therefore every constraint should know that when it is called + # it will be the first time in a new round + for constraint in com.constraints + set_first_node_call!(constraint, true) + end + # check if all feasible even if for example everything is fixed feasible = prune!(com; pre_backtrack = true, initial_check = true) # finished pruning will be called in second call a few lines down... @@ -780,6 +794,11 @@ function solve!(com::CS.CoM) push!(com.solutions, new_sol_obj) return :Solved end + + for constraint in com.constraints + set_first_node_call!(constraint, true) + end + feasible = prune!(com; pre_backtrack = true) call_finished_pruning!(com) diff --git a/src/pruning.jl b/src/pruning.jl index da776eea..d2521d44 100644 --- a/src/pruning.jl +++ b/src/pruning.jl @@ -75,10 +75,6 @@ function prune!( end end end - for constraint in com.constraints - set_first_node_call!(constraint, true) - end - # while we haven't called every constraint while true From 82b89fc05924bbcde9c872b66387e3b3ac137dcc Mon Sep 17 00:00:00 2001 From: Ole Kroeger Date: Sat, 11 Sep 2021 12:47:58 +0200 Subject: [PATCH 09/10] added stuff to benchmark/Project.toml --- benchmark/Manifest.toml | 342 +++++++++++++++++++++++++++++++++++++++- benchmark/Project.toml | 3 + 2 files changed, 342 insertions(+), 3 deletions(-) diff --git a/benchmark/Manifest.toml b/benchmark/Manifest.toml index 4312dda5..faa91463 100644 --- a/benchmark/Manifest.toml +++ b/benchmark/Manifest.toml @@ -3,11 +3,17 @@ [[ArgTools]] uuid = "0dad84c5-d112-42e6-8d28-ef12dabb789f" +[[ArnoldiMethod]] +deps = ["LinearAlgebra", "Random", "StaticArrays"] +git-tree-sha1 = "f87e559f87a45bece9c9ed97458d3afe98b1ebb9" +uuid = "ec485272-7323-5ecc-a04f-4719b315124d" +version = "0.1.0" + [[Arpack]] -deps = ["Arpack_jll", "Libdl", "LinearAlgebra", "Logging"] -git-tree-sha1 = "dadb9a82914224b22e5f2b73a82fd5de46d3cf16" +deps = ["Arpack_jll", "Libdl", "LinearAlgebra"] +git-tree-sha1 = "2ff92b71ba1747c5fdd541f8fc87736d82f40ec9" uuid = "7d9fca2a-8960-54d3-9f78-7d1dccf2cb97" -version = "0.5.2" +version = "0.4.0" [[Arpack_jll]] deps = ["Libdl", "OpenBLAS_jll", "Pkg"] @@ -21,22 +27,188 @@ uuid = "56f22d72-fd6d-98f1-02f0-08ddc0907c33" [[Base64]] uuid = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f" +[[BenchmarkTools]] +deps = ["JSON", "Logging", "Printf", "Statistics", "UUIDs"] +git-tree-sha1 = "42ac5e523869a84eac9669eaceed9e4aa0e1587b" +uuid = "6e4b80f9-dd63-53aa-95a3-0cdb28fa8baf" +version = "1.1.4" + +[[Bzip2_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "19a35467a82e236ff51bc17a3a44b69ef35185a2" +uuid = "6e34b625-4abd-537c-b88f-471c36dfa7a0" +version = "1.0.8+0" + +[[Calculus]] +deps = ["LinearAlgebra"] +git-tree-sha1 = "f641eb0a4f00c343bbc32346e1217b86f3ce9dad" +uuid = "49dc2e85-a5d0-5ad3-a950-438e2897f1b9" +version = "0.5.1" + +[[ChainRulesCore]] +deps = ["Compat", "LinearAlgebra", "SparseArrays"] +git-tree-sha1 = "30ee06de5ff870b45c78f529a6b093b3323256a3" +uuid = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" +version = "1.3.1" + +[[CodecBzip2]] +deps = ["Bzip2_jll", "Libdl", "TranscodingStreams"] +git-tree-sha1 = "2e62a725210ce3c3c2e1a3080190e7ca491f18d7" +uuid = "523fee87-0ab8-5b00-afb7-3ecf72e48cfd" +version = "0.7.2" + +[[CodecZlib]] +deps = ["TranscodingStreams", "Zlib_jll"] +git-tree-sha1 = "ded953804d019afa9a3f98981d99b33e3db7b6da" +uuid = "944b1d66-785c-5afd-91f1-9de20f533193" +version = "0.7.0" + +[[CommonSubexpressions]] +deps = ["MacroTools", "Test"] +git-tree-sha1 = "7b8a93dba8af7e3b42fecabf646260105ac373f7" +uuid = "bbf7d656-a473-5ed7-a52c-81e309532950" +version = "0.3.0" + +[[Compat]] +deps = ["Base64", "Dates", "DelimitedFiles", "Distributed", "InteractiveUtils", "LibGit2", "Libdl", "LinearAlgebra", "Markdown", "Mmap", "Pkg", "Printf", "REPL", "Random", "SHA", "Serialization", "SharedArrays", "Sockets", "SparseArrays", "Statistics", "Test", "UUIDs", "Unicode"] +git-tree-sha1 = "6071cb87be6a444ac75fdbf51b8e7273808ce62f" +uuid = "34da2185-b29b-5c13-b0c7-acf172513d20" +version = "3.35.0" + [[CompilerSupportLibraries_jll]] deps = ["Artifacts", "Libdl"] uuid = "e66e0078-7015-5450-92f7-15fbd957f2ae" +[[ConstraintProgrammingExtensions]] +deps = ["LinearAlgebra", "MathOptInterface", "Test"] +git-tree-sha1 = "989acd05e57112a5fd1bc8849ebc398a614aa010" +uuid = "b65d079e-ed98-51d9-b0db-edee61a5c5f8" +version = "0.3.2" + +[[ConstraintSolver]] +deps = ["ConstraintProgrammingExtensions", "DataStructures", "Formatting", "JSON", "JuMP", "LightGraphs", "MathOptInterface", "MatrixNetworks", "Random", "Statistics", "StatsBase", "StatsFuns"] +path = ".." +uuid = "e0e52ebd-5523-408d-9ca3-7641f1cd1405" +version = "0.7.0" + +[[DataAPI]] +git-tree-sha1 = "bec2532f8adb82005476c141ec23e921fc20971b" +uuid = "9a962f9c-6df0-11e9-0e5d-c546b8b5ee8a" +version = "1.8.0" + +[[DataStructures]] +deps = ["Compat", "InteractiveUtils", "OrderedCollections"] +git-tree-sha1 = "7d9d316f04214f7efdbb6398d545446e246eff02" +uuid = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8" +version = "0.18.10" + [[Dates]] deps = ["Printf"] uuid = "ade2ca70-3891-5945-98fb-dc099432e06a" +[[DelimitedFiles]] +deps = ["Mmap"] +uuid = "8bb1440f-4735-579b-a4ab-409b98df4dab" + +[[DiffResults]] +deps = ["StaticArrays"] +git-tree-sha1 = "c18e98cba888c6c25d1c3b048e4b3380ca956805" +uuid = "163ba53b-c6d8-5494-b064-1a9d43ac40c5" +version = "1.0.3" + +[[DiffRules]] +deps = ["NaNMath", "Random", "SpecialFunctions"] +git-tree-sha1 = "3ed8fa7178a10d1cd0f1ca524f249ba6937490c0" +uuid = "b552c78f-8df3-52c6-915a-8e097449b14b" +version = "1.3.0" + +[[Distributed]] +deps = ["Random", "Serialization", "Sockets"] +uuid = "8ba89e20-285c-5b6f-9357-94700520ee1b" + +[[DocStringExtensions]] +deps = ["LibGit2"] +git-tree-sha1 = "a32185f5428d3986f47c2ab78b1f216d5e6cc96f" +uuid = "ffbed154-4ef7-542d-bbb7-c09d3a79fcae" +version = "0.8.5" + [[Downloads]] deps = ["ArgTools", "LibCURL", "NetworkOptions"] uuid = "f43a241f-c20a-4ad4-852c-f6b1247861c6" +[[Formatting]] +deps = ["Printf"] +git-tree-sha1 = "8339d61043228fdd3eb658d86c926cb282ae72a8" +uuid = "59287772-0a20-5a39-b81b-1366585eb4c0" +version = "0.4.2" + +[[ForwardDiff]] +deps = ["CommonSubexpressions", "DiffResults", "DiffRules", "LinearAlgebra", "NaNMath", "Printf", "Random", "SpecialFunctions", "StaticArrays"] +git-tree-sha1 = "b5e930ac60b613ef3406da6d4f42c35d8dc51419" +uuid = "f6369f11-7733-5829-9624-2563aa707210" +version = "0.10.19" + +[[HTTP]] +deps = ["Base64", "Dates", "IniFile", "Logging", "MbedTLS", "NetworkOptions", "Sockets", "URIs"] +git-tree-sha1 = "60ed5f1643927479f845b0135bb369b031b541fa" +uuid = "cd3eb016-35fb-5094-929b-558a96fad6f3" +version = "0.9.14" + +[[Inflate]] +git-tree-sha1 = "f5fc07d4e706b84f72d54eedcc1c13d92fb0871c" +uuid = "d25df0c9-e2be-5dd7-82c8-3ad0b3e990b9" +version = "0.1.2" + +[[IniFile]] +deps = ["Test"] +git-tree-sha1 = "098e4d2c533924c921f9f9847274f2ad89e018b8" +uuid = "83e8ac13-25f8-5344-8a64-a9f2b223428f" +version = "0.5.0" + [[InteractiveUtils]] deps = ["Markdown"] uuid = "b77e0a4c-d291-57a0-90e8-8db25a27a240" +[[IrrationalConstants]] +git-tree-sha1 = "f76424439413893a832026ca355fe273e93bce94" +uuid = "92d709cd-6900-40b7-9082-c6be49f344b6" +version = "0.1.0" + +[[IterTools]] +git-tree-sha1 = "05110a2ab1fc5f932622ffea2a003221f4782c18" +uuid = "c8e1da08-722c-5040-9ed9-7db0dc04731e" +version = "1.3.0" + +[[JLLWrappers]] +deps = ["Preferences"] +git-tree-sha1 = "642a199af8b68253517b80bd3bfd17eb4e84df6e" +uuid = "692b3bcd-3c85-4b1f-b108-f13ce0eb3210" +version = "1.3.0" + +[[JSON]] +deps = ["Dates", "Mmap", "Parsers", "Unicode"] +git-tree-sha1 = "8076680b162ada2a031f707ac7b4953e30667a37" +uuid = "682c06a0-de6a-54ab-a142-c8b1cf79cde6" +version = "0.21.2" + +[[JSONSchema]] +deps = ["HTTP", "JSON", "URIs"] +git-tree-sha1 = "2f49f7f86762a0fbbeef84912265a1ae61c4ef80" +uuid = "7d188eb4-7ad8-530c-ae41-71a32a6d4692" +version = "0.3.4" + +[[JuMP]] +deps = ["Calculus", "DataStructures", "ForwardDiff", "JSON", "LinearAlgebra", "MathOptInterface", "MutableArithmetics", "NaNMath", "Printf", "Random", "SparseArrays", "SpecialFunctions", "Statistics"] +git-tree-sha1 = "4358b7cbf2db36596bdbbe3becc6b9d87e4eb8f5" +uuid = "4076af6c-e467-56ae-b986-b466b2749572" +version = "0.21.10" + +[[KahanSummation]] +deps = ["Test"] +git-tree-sha1 = "1f01068b28d3ad83d4d1212a0ce8d7ecacb33482" +uuid = "8e2b3108-d4c1-50be-a7a2-16352aec75c3" +version = "0.1.0" + [[LibCURL]] deps = ["LibCURL_jll", "MozillaCACerts_jll"] uuid = "b27032c2-a3e7-50c8-80cd-2d36dbcbfd21" @@ -56,24 +228,80 @@ uuid = "29816b5a-b9ab-546f-933c-edad1886dfa8" [[Libdl]] uuid = "8f399da3-3557-5675-b5ff-fb832c97cbdb" +[[LightGraphs]] +deps = ["ArnoldiMethod", "DataStructures", "Distributed", "Inflate", "LinearAlgebra", "Random", "SharedArrays", "SimpleTraits", "SparseArrays", "Statistics"] +git-tree-sha1 = "432428df5f360964040ed60418dd5601ecd240b6" +uuid = "093fc24a-ae57-5d10-9952-331d41423f4d" +version = "1.3.5" + [[LinearAlgebra]] deps = ["Libdl"] uuid = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" +[[LogExpFunctions]] +deps = ["ChainRulesCore", "DocStringExtensions", "IrrationalConstants", "LinearAlgebra"] +git-tree-sha1 = "86197a8ecb06e222d66797b0c2d2f0cc7b69e42b" +uuid = "2ab3a3ac-af41-5b50-aa03-7779005ae688" +version = "0.3.2" + [[Logging]] uuid = "56ddb016-857b-54e1-b83d-db4d58db5568" +[[MacroTools]] +deps = ["Markdown", "Random"] +git-tree-sha1 = "0fb723cd8c45858c22169b2e42269e53271a6df7" +uuid = "1914dd2f-81c6-5fcd-8719-6d5c9610ff09" +version = "0.5.7" + [[Markdown]] deps = ["Base64"] uuid = "d6f4376e-aef5-505a-96c1-9c027394607a" +[[MathOptInterface]] +deps = ["BenchmarkTools", "CodecBzip2", "CodecZlib", "JSON", "JSONSchema", "LinearAlgebra", "MutableArithmetics", "OrderedCollections", "SparseArrays", "Test", "Unicode"] +git-tree-sha1 = "575644e3c05b258250bb599e57cf73bbf1062901" +uuid = "b8f27783-ece8-5eb3-8dc8-9495eed66fee" +version = "0.9.22" + +[[MatrixNetworks]] +deps = ["Arpack", "DataStructures", "DelimitedFiles", "IterTools", "KahanSummation", "LinearAlgebra", "Printf", "Random", "SparseArrays", "Statistics"] +git-tree-sha1 = "f6794d987d426bab570aabb2d03e2f40ca4fc438" +uuid = "4f449596-a032-5618-b826-5a251cb6dc11" +version = "1.0.2" + +[[MbedTLS]] +deps = ["Dates", "MbedTLS_jll", "Random", "Sockets"] +git-tree-sha1 = "1c38e51c3d08ef2278062ebceade0e46cefc96fe" +uuid = "739be429-bea8-5141-9913-cc70e7f3736d" +version = "1.0.3" + [[MbedTLS_jll]] deps = ["Artifacts", "Libdl"] uuid = "c8ffd9c3-330d-5841-b78e-0817d7145fa1" +[[Missings]] +deps = ["DataAPI"] +git-tree-sha1 = "2ca267b08821e86c5ef4376cffed98a46c2cb205" +uuid = "e1d29d7a-bbdc-5cf2-9ac0-f12de2c33e28" +version = "1.0.1" + +[[Mmap]] +uuid = "a63ad114-7e13-5084-954f-fe012c677804" + [[MozillaCACerts_jll]] uuid = "14a3606d-f60d-562e-9121-12d972cd8159" +[[MutableArithmetics]] +deps = ["LinearAlgebra", "SparseArrays", "Test"] +git-tree-sha1 = "3927848ccebcc165952dc0d9ac9aa274a87bfe01" +uuid = "d8a4904e-b15c-11e9-3269-09a3773c0cb0" +version = "0.2.20" + +[[NaNMath]] +git-tree-sha1 = "bfe47e760d60b82b66b61d2d44128b62e3a369fb" +uuid = "77ba4419-2d1f-58cd-9bb1-8ffee604a2e3" +version = "0.3.5" + [[NetworkOptions]] uuid = "ca575930-c2e3-43a9-ace4-1e988b2c1908" @@ -81,10 +309,33 @@ uuid = "ca575930-c2e3-43a9-ace4-1e988b2c1908" deps = ["Artifacts", "CompilerSupportLibraries_jll", "Libdl"] uuid = "4536629a-c528-5b80-bd46-f80d51c5b363" +[[OpenSpecFun_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "13652491f6856acfd2db29360e1bbcd4565d04f1" +uuid = "efe28fd5-8261-553b-a9e1-b2916fc3738e" +version = "0.5.5+0" + +[[OrderedCollections]] +git-tree-sha1 = "85f8e6578bf1f9ee0d11e7bb1b1456435479d47c" +uuid = "bac558e1-5e72-5ebc-8fee-abe8a469f55d" +version = "1.4.1" + +[[Parsers]] +deps = ["Dates"] +git-tree-sha1 = "438d35d2d95ae2c5e8780b330592b6de8494e779" +uuid = "69de0a69-1ddd-5017-9359-2bf0b02dc9f0" +version = "2.0.3" + [[Pkg]] deps = ["Artifacts", "Dates", "Downloads", "LibGit2", "Libdl", "Logging", "Markdown", "Printf", "REPL", "Random", "SHA", "Serialization", "TOML", "Tar", "UUIDs", "p7zip_jll"] uuid = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f" +[[Preferences]] +deps = ["TOML"] +git-tree-sha1 = "00cfd92944ca9c760982747e9a1d0d5d86ab1e5a" +uuid = "21216c6a-2e73-6563-6e65-726566657250" +version = "1.2.2" + [[Printf]] deps = ["Unicode"] uuid = "de0858da-6303-5e67-8744-51eddeeeb8d7" @@ -97,15 +348,85 @@ uuid = "3fa0cd96-eef1-5676-8a61-b3b8758bbffb" deps = ["Serialization"] uuid = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" +[[Reexport]] +git-tree-sha1 = "45e428421666073eab6f2da5c9d310d99bb12f9b" +uuid = "189a3867-3050-52da-a836-e630ba90ab69" +version = "1.2.2" + +[[Rmath]] +deps = ["Random", "Rmath_jll"] +git-tree-sha1 = "bf3188feca147ce108c76ad82c2792c57abe7b1f" +uuid = "79098fc4-a85e-5d69-aa6a-4863f24498fa" +version = "0.7.0" + +[[Rmath_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "68db32dff12bb6127bac73c209881191bf0efbb7" +uuid = "f50d1b31-88e8-58de-be2c-1cc44531875f" +version = "0.3.0+0" + [[SHA]] uuid = "ea8e919c-243c-51af-8825-aaa63cd721ce" [[Serialization]] uuid = "9e88b42a-f829-5b0c-bbe9-9e923198166b" +[[SharedArrays]] +deps = ["Distributed", "Mmap", "Random", "Serialization"] +uuid = "1a1011a3-84de-559e-8e89-a11a2f7dc383" + +[[SimpleTraits]] +deps = ["InteractiveUtils", "MacroTools"] +git-tree-sha1 = "5d7e3f4e11935503d3ecaf7186eac40602e7d231" +uuid = "699a6c99-e7fa-54fc-8d76-47d257e15c1d" +version = "0.9.4" + [[Sockets]] uuid = "6462fe0b-24de-5631-8697-dd941f90decc" +[[SortingAlgorithms]] +deps = ["DataStructures"] +git-tree-sha1 = "b3363d7460f7d098ca0912c69b082f75625d7508" +uuid = "a2af1166-a08f-5f64-846c-94a0d3cef48c" +version = "1.0.1" + +[[SparseArrays]] +deps = ["LinearAlgebra", "Random"] +uuid = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" + +[[SpecialFunctions]] +deps = ["ChainRulesCore", "LogExpFunctions", "OpenSpecFun_jll"] +git-tree-sha1 = "a322a9493e49c5f3a10b50df3aedaf1cdb3244b7" +uuid = "276daf66-3868-5448-9aa4-cd146d93841b" +version = "1.6.1" + +[[StaticArrays]] +deps = ["LinearAlgebra", "Random", "Statistics"] +git-tree-sha1 = "3240808c6d463ac46f1c1cd7638375cd22abbccb" +uuid = "90137ffa-7385-5640-81b9-e52037218182" +version = "1.2.12" + +[[Statistics]] +deps = ["LinearAlgebra", "SparseArrays"] +uuid = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" + +[[StatsAPI]] +git-tree-sha1 = "1958272568dc176a1d881acb797beb909c785510" +uuid = "82ae8749-77ed-4fe6-ae5f-f523153014b0" +version = "1.0.0" + +[[StatsBase]] +deps = ["DataAPI", "DataStructures", "LinearAlgebra", "Missings", "Printf", "Random", "SortingAlgorithms", "SparseArrays", "Statistics", "StatsAPI"] +git-tree-sha1 = "8cbbc098554648c84f79a463c9ff0fd277144b6c" +uuid = "2913bbd2-ae8a-5f71-8c99-4fb6c76f3a91" +version = "0.33.10" + +[[StatsFuns]] +deps = ["ChainRulesCore", "IrrationalConstants", "LogExpFunctions", "Reexport", "Rmath", "SpecialFunctions"] +git-tree-sha1 = "46d7ccc7104860c38b11966dd1f72ff042f382e4" +uuid = "4c63d2b9-4356-54db-8cca-17b64c39e42c" +version = "0.9.10" + [[TOML]] deps = ["Dates"] uuid = "fa267f1f-6049-4f14-aa54-33bafae1ed76" @@ -114,6 +435,21 @@ uuid = "fa267f1f-6049-4f14-aa54-33bafae1ed76" deps = ["ArgTools", "SHA"] uuid = "a4e569a6-e804-4fa4-b0f3-eef7a1d5b13e" +[[Test]] +deps = ["InteractiveUtils", "Logging", "Random", "Serialization"] +uuid = "8dfed614-e22c-5e08-85e1-65c5234f0b40" + +[[TranscodingStreams]] +deps = ["Random", "Test"] +git-tree-sha1 = "216b95ea110b5972db65aa90f88d8d89dcb8851c" +uuid = "3bb67fe8-82b1-5028-8e26-92a6c54297fa" +version = "0.9.6" + +[[URIs]] +git-tree-sha1 = "97bbe755a53fe859669cd907f2d96aee8d2c1355" +uuid = "5c2747f8-b7ea-4ff2-ba2e-563bfd36b1d4" +version = "1.3.0" + [[UUIDs]] deps = ["Random", "SHA"] uuid = "cf7118a7-6976-5b1a-9a39-7adc72f591a4" diff --git a/benchmark/Project.toml b/benchmark/Project.toml index 166cb13a..66d8c10f 100644 --- a/benchmark/Project.toml +++ b/benchmark/Project.toml @@ -1,2 +1,5 @@ [deps] Arpack = "7d9fca2a-8960-54d3-9f78-7d1dccf2cb97" +ConstraintSolver = "e0e52ebd-5523-408d-9ca3-7641f1cd1405" +JuMP = "4076af6c-e467-56ae-b986-b466b2749572" +MathOptInterface = "b8f27783-ece8-5eb3-8dc8-9495eed66fee" From 7541a8a6c07f04dcd1ecbb73067eb5cf07ff5c77 Mon Sep 17 00:00:00 2001 From: Ole Kroeger Date: Tue, 26 Oct 2021 16:18:58 +0200 Subject: [PATCH 10/10] check whether reverse prune was needed --- src/ConstraintSolver.jl | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/src/ConstraintSolver.jl b/src/ConstraintSolver.jl index 27f3557b..6ef3b52f 100644 --- a/src/ConstraintSolver.jl +++ b/src/ConstraintSolver.jl @@ -214,13 +214,15 @@ end Change the state of the search space given the current position in the tree (`from_nidx`) and the index we want to change to (`to_nidx`) +Return whether reverse_pruning! was called """ function checkout_from_to!(com::CS.CoM, from_nidx::Int, to_nidx::Int) backtrack_vec = com.backtrack_vec from = backtrack_vec[from_nidx] to = backtrack_vec[to_nidx] + # if the parent of to is the current node then we don't have to do anything if to.parent_idx == from.idx - return + return false end reverse_pruning!(com, from.idx) @@ -237,7 +239,7 @@ function checkout_from_to!(com::CS.CoM, from_nidx::Int, to_nidx::Int) depth -= 1 end if parent_nidx == to.parent_idx - return + return true else from = parent end @@ -256,7 +258,7 @@ function checkout_from_to!(com::CS.CoM, from_nidx::Int, to_nidx::Int) to = parent if backtrack_vec[prune_steps[1]].parent_idx == from.parent_idx !isempty(prune_steps) && restore_prune!(com, prune_steps) - return + return true end end @assert from.depth == to.depth @@ -271,6 +273,7 @@ function checkout_from_to!(com::CS.CoM, from_nidx::Int, to_nidx::Int) end !isempty(prune_steps) && restore_prune!(com, prune_steps) + return true end """ @@ -374,18 +377,19 @@ function add2backtrack_vec!( end """ - set_bounds!(com, backtrack_obj) + set_bounds!(com, backtrack_obj, needed_reverse_prune::Bool) Set lower/upper bounds for the current variable index `backtrack_obj.vidx`. Return if simple removable is still feasible """ -function set_bounds!(com, backtrack_obj) +function set_bounds!(com, backtrack_obj, needed_reverse_prune::Bool) vidx = backtrack_obj.vidx # set all first node calls to true as there might have been a reverse pruning - # Todo: Actually only do this when there was reverse pruning... - for constraint in com.constraints - set_first_node_call!(constraint, true) + if needed_reverse_prune + for constraint in com.constraints + set_first_node_call!(constraint, true) + end end !remove_above!(com, com.search_space[vidx], backtrack_obj.ub) && return false @@ -450,9 +454,11 @@ If last id is not 0 then changes from last_id to new_id and sets `com.c_backtrac function checkout_new_node!(com::CS.CoM, last_id, new_id) if last_id != 0 com.c_backtrack_idx = 0 - checkout_from_to!(com, last_id, new_id) + needed_reverse_prune = checkout_from_to!(com, last_id, new_id) com.c_backtrack_idx = new_id + return needed_reverse_prune end + return false end """ @@ -587,7 +593,7 @@ function backtrack!( vidx = backtrack_obj.vidx com.c_backtrack_idx = backtrack_obj.idx - checkout_new_node!(com, last_backtrack_id, backtrack_obj.idx) + needed_reverse_prune = checkout_new_node!(com, last_backtrack_id, backtrack_obj.idx) # if backtracking was started # => remove all values which are root infeasible @@ -609,7 +615,7 @@ function backtrack!( last_backtrack_id = backtrack_obj.idx # limit the variable bounds - if !set_bounds!(com, backtrack_obj) + if !set_bounds!(com, backtrack_obj, needed_reverse_prune) update_log_node!(com, last_backtrack_id; feasible = false) continue end