Wikunia / ConstraintSolver.jl

ConstraintSolver in Julia: Blog posts ->
https://opensourc.es/blog/constraint-solver-1
MIT License
136 stars 14 forks source link

Problem with `<` in certain cases. #239

Closed hakank closed 3 years ago

hakank commented 3 years ago

I'm using the new ConstraintSolver v0.6.1 which allows < constraints to be used. Most of my previous models which used ... <= ... - 1 works, but one model don't work: http://hakank.org/julia/constraints/golomb_ruler.jl

The offending constraint is

@constraint(model, x[2] - x[1] < x[n] - x[n-1])

which throws this stacktrace:

ERROR: InexactError: Int64(-Inf)
Stacktrace:
  [1] Int64
    @ ./float.jl:723 [inlined]
  [2] convert
    @ ./number.jl:7 [inlined]
  [3] get_safe_lower_threshold(com::ConstraintSolver.ConstraintSolverModel{Float64}, val::Float64, divider::Float64)
    @ ConstraintSolver ~/.julia/packages/ConstraintSolver/RgG7X/src/util.jl:36
  [4] prune_constraint!(com::ConstraintSolver.ConstraintSolverModel{Float64}, constraint::ConstraintSolver.LinearConstraint{Float64}, fct::MathOptInterface.ScalarAffineFunction{Float64}, set::ConstraintSolver.Strictly{Float64, MathOptInterface.LessThan{Float64}}; logs::Bool)
    @ ConstraintSolver ~/.julia/packages/ConstraintSolver/RgG7X/src/constraints/linear_constraints.jl:302
  [5] prune!(com::ConstraintSolver.ConstraintSolverModel{Float64}; pre_backtrack::Bool, all::Bool, only_once::Bool, initial_check::Bool)
    @ ConstraintSolver ~/.julia/packages/ConstraintSolver/RgG7X/src/pruning.jl:97
  [6] solve!(com::ConstraintSolver.ConstraintSolverModel{Float64})
    @ ConstraintSolver ~/.julia/packages/ConstraintSolver/RgG7X/src/ConstraintSolver.jl:742
  [7] optimize!(model::ConstraintSolver.Optimizer)
    @ ConstraintSolver ~/.julia/packages/ConstraintSolver/RgG7X/src/MOI_wrapper/MOI_wrapper.jl:165
  [8] optimize!
    @ ~/.julia/packages/MathOptInterface/ZJFKw/src/Bridges/bridge_optimizer.jl:264 [inlined]
  [9] optimize!(m::MathOptInterface.Utilities.CachingOptimizer{MathOptInterface.AbstractOptimizer, MathOptInterface.Utilities.UniversalFallback{MathOptInterface.Utilities.Model{Float64}}})
    @ MathOptInterface.Utilities ~/.julia/packages/MathOptInterface/ZJFKw/src/Utilities/cachingoptimizer.jl:215
 [10] optimize!(model::Model, optimizer_factory::Nothing; bridge_constraints::Bool, ignore_optimize_hook::Bool, kwargs::Base.Iterators.Pairs{Union{}, Union{}, Tuple{}, NamedTuple{(), Tuple{}}})
    @ JuMP ~/.julia/packages/JuMP/e0Uc2/src/optimizer_interface.jl:130
 [11] optimize!
    @ ~/.julia/packages/JuMP/e0Uc2/src/optimizer_interface.jl:106 [inlined]
 [12] golomb_ruler(n::Int64, print_solutions::Bool, all_solutions::Bool)
    @ Main ~/julia/constraints/golomb_ruler.jl:94
 [13] macro expansion
    @ ./timing.jl:206 [inlined]
 [14] top-level scope
    @ ~/julia/constraints/golomb_ruler.jl:125
 [15] include(fname::String)
    @ Base.MainInclude ./client.jl:444
 [16] top-level scope
    @ ./timing.jl:206 [inlined]
 [17] top-level scope
    @ ./REPL[16]:0
 [18] eval
    @ ./boot.jl:360 [inlined]

It seems that the problem is that the LHS is an expression, since the following works, i.e. moving one of the two LHS terms to RHS:

constraint(model, x[2] < x[n] - x[n-1] + x[1])
Wikunia commented 3 years ago

This should fix the case but be careful as

@constraint(model, x[2] < x[n] - x[n-1] + x[1])

fails for n = 2 which is the starting value in your example.

hakank commented 3 years ago

Thanks.

Yes, for n=2 this symmetry breaking constraint yield an infeasible solution, and I'll have to take care of this.

hakank commented 3 years ago

Ah, the error is only thrown for n=2 (which you surely have realized).

Wikunia commented 3 years ago

Yes. I've slightly changed the PR such that the terms with 0 coefficient get removed. Thanks again for testing it out and opening the issue!