Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature "And" constraint #244

Merged
merged 30 commits into from
Feb 12, 2021
Merged

Feature "And" constraint #244

merged 30 commits into from
Feb 12, 2021

Conversation

Wikunia
Copy link
Owner

@Wikunia Wikunia commented Jan 28, 2021

First part of #205 but only for the right hand side.

Currently this does only parsing stuff and creating the AndConstraint. It also obviously only implements && for now and not ||.
Todo:

  • Implement the usual constraint functions

  • Somehow understand why two or more && seem to create extra variables

  • Bridge to support >= and >

    • LHS
    • RHS
    • Both LHS and RHS (figure out why this doesn't work atm)
    • Probably do all in a single run for a certain subbridge to avoid creating too many subsubsubbridges or some kind of recursion
    • For several && constraints
  • test cases

    • Unit tests for reified
    • Unit tests inside indicator
    • Small real test case
    • Test with several && in one constraint
    • Test with brackets around several &&
  • Documentation changes?

  • Changelog

  • Check if active in init_constraint!

I'll most likely create other PRs to support more of #205 in the future. This PR might already be enough for #213 though

@Wikunia Wikunia marked this pull request as draft January 28, 2021 11:30
@codecov
Copy link

codecov bot commented Jan 28, 2021

Codecov Report

Merging #244 (0e6d1ef) into master (d5e7753) will increase coverage by 0.16%.
The diff coverage is 97.94%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master     #244      +/-   ##
==========================================
+ Coverage   96.51%   96.67%   +0.16%     
==========================================
  Files          39       48       +9     
  Lines        3439     3761     +322     
==========================================
+ Hits         3319     3636     +317     
- Misses        120      125       +5     
Impacted Files Coverage Δ
src/MOI_wrapper/Bridges/strictly_greater_than.jl 66.66% <ø> (ø)
src/constraints/all_different.jl 100.00% <ø> (ø)
src/constraints/equal_set.jl 95.60% <ø> (ø)
src/constraints/geqset.jl 100.00% <ø> (ø)
src/constraints/linear_constraints.jl 96.98% <ø> (ø)
src/constraints/table.jl 99.23% <ø> (ø)
src/MOI_wrapper/or.jl 89.47% <89.47%> (ø)
src/MOI_wrapper/and.jl 90.47% <90.47%> (ø)
src/MOI_wrapper/Bridges/bool.jl 96.66% <96.66%> (ø)
src/constraints/or.jl 97.72% <97.72%> (ø)
... and 24 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update d5e7753...0e6d1ef. Read the comment docs.

@Wikunia
Copy link
Owner Author

Wikunia commented Feb 5, 2021

Hi @hakank,

this PR is ready for your tests 😄

It implements && inside reified and indicator constraints but only on the right hand side of the => or :=.

One example is your alldifferent except 0 from #202 which can be done by using a reified constraint instead of directly having the && at the left hand side.

m = Model(CS.Optimizer)
@variable(m, 0 <= x[1:5] <= 3, Int)
len = length(x)
for i in 2:len, j in 1:i-1
    b = @variable(m, binary=true)
    @constraint(m, b := {x[i] != 0 && x[j] != 0})
    @constraint(m, b => {x[i] != x[j]} ) 
end
@objective(m, Max, sum(x))
optimize!(m)

I only implement <= and < directly and >= and > are transformed. That was the most challenging part of this PR so that would benefit most from testing.

I'll of course test this further in the next couple of days but I think it's ready for your review.

Thanks in advance!

@Wikunia Wikunia marked this pull request as ready for review February 5, 2021 18:13
@hakank
Copy link

hakank commented Feb 6, 2021

I have now checked all my models (http://hakank.org/julia/constraints/ ), and changed the following to use && instead:

http://hakank.org/julia/constraints/a_round_of_golf.jl
http://hakank.org/julia/constraints/breaking_news.jl
http://hakank.org/julia/constraints/monks_and_doors.jl
http://hakank.org/julia/constraints/tourist_site_competition.jl

http://hakank.org/julia/constraints/constraints_utils.jl (changed all_different_except_c) and is tested by http://hakank.org/julia/constraints/all_different_except_0.jl

I couldn't see any performance changes in these models.

There was, however one model that was much slower with && for some reason: http://hakank.org/julia/constraints/steiner_and.jl (compared with the original http://hakank.org/julia/constraints/steiner.jl Here is the diff:

23a24,26
>   This version use && instead of a couple of Bin variables, but it's 
>   very slow. Why?
> 
85,86c88,89
<             b1 = @variable(model, [1:n], Bin)
<             b2 = @variable(model, [1:n], Bin)
---
>             # b1 = @variable(model, [1:n], Bin)
>             # b2 = @variable(model, [1:n], Bin)
89,92c92,95
<                 @constraint(model, b1[k] := {x[i,k] == 1})
<                 @constraint(model, b2[k] := {x[j,k] == 1})
<                 @constraint(model, b[k] := { b1[k] + b2[k] == 2 })
<                 # @constraint(model, b[k] := { x[i,k] == 1 && x[j,k] == 1 })
---
>                 # @constraint(model, b1[k] := {x[i,k] == 1})
>                 # @constraint(model, b2[k] := {x[j,k] == 1})
>                 # @constraint(model, b[k] := { b1[k] + b2[k] == 2 })
>                 @constraint(model, b[k] := { x[i,k] == 1 && x[j,k] == 1 })

The original model (steiner.jl) solved n=[3,7,9] in 0.25s, 0.04s, 0.21s respectively.
The && variant solved n=3 in 0.19s but timed out (>16s) on n=7.

@Wikunia Wikunia mentioned this pull request Feb 7, 2021
10 tasks
@Wikunia
Copy link
Owner Author

Wikunia commented Feb 7, 2021

Regarding your test case which is slower. I mentioned it in our chat but to have it here as well:
This is due to the fact that I haven't implement the "anti" constraint yet but that should be easy to add after #245 is tested and merged after this. 😉
Thanks again a lot for testing!

@Wikunia
Copy link
Owner Author

Wikunia commented Feb 12, 2021

Benchmark Report for ConstraintSolver

Job Properties

  • Time of benchmarks:
    • Target: 12 Feb 2021 - 16:55
    • Baseline: 12 Feb 2021 - 17:10
  • Package commits:
    • Target: cd744a
    • Baseline: c97c28
  • Julia commits:
    • Target: 788b2c
    • Baseline: 788b2c
  • Julia command flags:
    • Target: -O3
    • Baseline: -O3
  • Environment variables:
    • Target: None
    • Baseline: None

Results

A ratio greater than 1.0 denotes a possible regression (marked with ❌), while a ratio less
than 1.0 denotes a possible improvement (marked with ✅). Only significant results - results
that indicate possible regressions or improvements - are shown below (thus, an empty table means that all
benchmark results remained invariant between builds).

ID time ratio memory ratio
["eternity", "5x5_all"] 1.05 (5%) ❌ 1.00 (1%)
["eternity", "5x5_opt"] 0.82 (5%) ✅ 1.00 (1%)
["eternity", "5x5_opt_ind"] 1.06 (5%) ❌ 1.00 (1%)
["eternity", "5x5_opt_rei"] 1.07 (5%) ❌ 1.00 (1%)
["eternity", "6x5"] 1.07 (5%) ❌ 1.00 (1%)
["eternity", "6x5_ABS"] 0.82 (5%) ✅ 1.00 (1%)
["graph_coloring", "US_50colors+equal"] 1.05 (5%) ❌ 1.01 (1%)
["graph_coloring", "US_50colors+equal_ABS"] 0.94 (5%) ✅ 1.00 (1%)
["graph_coloring", "US_8+equal"] 0.85 (5%) ✅ 1.01 (1%)
["graph_coloring", "US_8+equal_ABS"] 0.93 (5%) ✅ 1.00 (1%)
["graph_coloring", "le450_5d"] 1.11 (5%) ❌ 1.00 (1%)
["graph_coloring", "queen7_7"] 1.11 (5%) ❌ 1.00 (1%)
["killer_sudoku", "niall_5501_special"] 0.88 (5%) ✅ 1.00 (1%)
["lp", "issue_83"] 1.01 (5%) 1.01 (1%) ❌
["scheduling", "all_different_except_0_len12"] 0.93 (5%) ✅ 1.00 (1%)
["scheduling", "furniture_moving"] 0.93 (5%) ✅ 1.00 (1%)
["scheduling", "organize_day"] 1.03 (5%) 1.02 (1%) ❌
["sudoku", "top95_1"] 1.12 (5%) ❌ 1.02 (1%) ❌
["sudoku", "top95_11"] 1.17 (5%) ❌ 1.01 (1%)
["sudoku", "top95_16"] 0.95 (5%) ✅ 1.01 (1%)
["sudoku", "top95_21"] 1.06 (5%) ❌ 1.02 (1%) ❌
["sudoku", "top95_26"] 0.94 (5%) ✅ 1.02 (1%) ❌
["sudoku", "top95_31"] 1.22 (5%) ❌ 1.01 (1%)
["sudoku", "top95_36"] 1.08 (5%) ❌ 1.02 (1%) ❌
["sudoku", "top95_41"] 1.01 (5%) 1.01 (1%) ❌
["sudoku", "top95_46"] 1.13 (5%) ❌ 1.01 (1%) ❌
["sudoku", "top95_51"] 1.05 (5%) 1.01 (1%) ❌
["sudoku", "top95_56"] 1.05 (5%) ❌ 1.01 (1%)
["sudoku", "top95_6"] 1.01 (5%) 1.02 (1%) ❌
["sudoku", "top95_61"] 0.86 (5%) ✅ 1.01 (1%) ❌
["sudoku", "top95_66"] 0.91 (5%) ✅ 1.01 (1%)
["sudoku", "top95_71"] 1.06 (5%) ❌ 1.02 (1%) ❌
["sudoku", "top95_76"] 1.09 (5%) ❌ 1.01 (1%) ❌
["sudoku", "top95_81"] 1.10 (5%) ❌ 1.02 (1%) ❌
["sudoku", "top95_86"] 1.03 (5%) 1.01 (1%) ❌
["sudoku", "top95_91"] 1.10 (5%) ❌ 1.01 (1%) ❌

Benchmark Group List

Here's a list of all the benchmark groups executed by this job:

  • ["eternity"]
  • ["graph_coloring"]
  • ["killer_sudoku"]
  • ["lp"]
  • ["scheduling"]
  • ["sudoku"]

Julia versioninfo

Target

Julia Version 1.5.3
Commit 788b2c77c1 (2020-11-09 13:37 UTC)
Platform Info:
  OS: Linux (x86_64-pc-linux-gnu)
  uname: Linux 5.10.13-arch1-2 #1 SMP PREEMPT Sat, 06 Feb 2021 11:07:29 +0000 x86_64 unknown
  CPU: AMD Ryzen 7 PRO 4750U with Radeon Graphics: 
                 speed         user         nice          sys         idle          irq
       #1-16  1397 MHz    1851575 s    1584148 s     661709 s   27648504 s          0 s
       
  Memory: 38.482669830322266 GB (1459.4375 MB free)
  Uptime: 67071.0 sec
  Load Avg:  2.72998046875  2.5009765625  2.7802734375
  WORD_SIZE: 64
  LIBM: libopenlibm
  LLVM: libLLVM-9.0.1 (ORCJIT, znver2)

Baseline

Julia Version 1.5.3
Commit 788b2c77c1 (2020-11-09 13:37 UTC)
Platform Info:
  OS: Linux (x86_64-pc-linux-gnu)
  uname: Linux 5.10.13-arch1-2 #1 SMP PREEMPT Sat, 06 Feb 2021 11:07:29 +0000 x86_64 unknown
  CPU: AMD Ryzen 7 PRO 4750U with Radeon Graphics: 
                 speed         user         nice          sys         idle          irq
       #1-16  1397 MHz    1962785 s    1649652 s     684176 s   28867718 s          0 s
       
  Memory: 38.482669830322266 GB (1306.19140625 MB free)
  Uptime: 67961.0 sec
  Load Avg:  2.1474609375  2.68505859375  2.8154296875
  WORD_SIZE: 64
  LIBM: libopenlibm
  LLVM: libLLVM-9.0.1 (ORCJIT, znver2)

* parse || and have OrSet
* is_boolset_supported
* implementation of || constraint
* fixed active
* bugfix pvals and basic unit test cases
* added to changelog
* added to docs/supported
* still_feasible bugfix and test case
* some more tests
* extra test cases
* anti constraint but bug in steiner
* changed benchmark for all_different_except_c
* moved the test...
* clean benchmark all_different_except_0
* calculate less in or and && (break early)
* support boolean constraints outside reified and indicator
* changelog & supported docs
* test for bool outside and finished bridge
@Wikunia Wikunia merged commit 0f63f16 into master Feb 12, 2021
@Wikunia Wikunia deleted the feature-and-constraint branch February 12, 2021 21:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants