-
Notifications
You must be signed in to change notification settings - Fork 16
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
$or works differently than I expected #10
Comments
Don't worry, you don't have a misunderstanding of how loco works... It's either a bug with $or, I'll get back to you on this as soon as I get the chance to investigate further. Thanks for finding this issue. |
Hi James, This is a bug within Choco, so unfortunately it is beyond my control for now. The Choco mod constraint is actually represented as an intricate composition of multiple constraints (division, addition, etc), so somehow nesting it in the For now, a workaround would be: (solutions [($in :x 1 10)
($in :_x-mod-3 0 2)
($in :_x-mod-5 0 4)
($= :_x-mod-3 ($mod :x 3))
($= :_x-mod-5 ($mod :x 5))
($or ($= :_x-mod-3 0)
($= :_x-mod-5 0))])
=> ({:x 6} {:x 3} {:x 9} {:x 10} {:x 5}) |
Thanks for figuring it out, and for posting the workaround. Does the workaround have a strong negative impact on performance? I ask because I'm seeing poor performance compared to (time (reduce + (map :x (solutions [($in :x 1 10e4)
($in :_x-mod-3 0 2)
($in :_x-mod-5 0 4)
($= :_x-mod-3 ($mod :x 3))
($= :_x-mod-5 ($mod :x 5))
($or ($= :_x-mod-3 0)
($= :_x-mod-5 0))])))) Whereas this takes ~30ms: (time (reduce + (map :x (for [x (range 1 10e4)
:when (or (= 0 (mod x 3))
(= 0 (mod x 5)))]
{:x x})))) And By the way, are you worried by the lack of recent updates for Choco? |
In my experience, Choco has not been very good at handling domains that large. This particular problem seems not very applicable to Constraint Programming because it's a very simple constraint on a very large domain. Also, I wouldn't expect that my workaround alone is making it this slow. A lot of the slowness you're experiencing is most likely coming from the propagator having to iterate through each possible That said, if you are trying to apply Loco to a domain this large, you'll want to be using bounded variables instead of enumerated ones (the default). That way, Choco is not storing every value from 1 to 10,000 in an array somewhere, which normally would help the propagation but in this case is hurting it. On my machine, changing it to |
Constraint Programming is a totally new approach for me, so I'm still trying to figure out which problems it's well suited to. Thanks for taking the time to explain why it's not well suited in this case. |
Learning as well, I am going to plus-one that thank you of yours 😄 |
Hi guys, @aengelberg, I have provided a clean workaround for the mod problem here: chocoteam/choco-solver#272 @Misophistful, we are used to releasing the code every 3-6 months, but our development branch is often updated. @ALL Please do not hesitate to post messages on our forum (http://choco-solver.org/?q=Forum) or on Github if you have any request or simply to inform us about your usage of Choco! |
I have encoded it in Choco to see what it gives. I got the following model: public void testEuler(){ It deals with 10^5 in 0.5 seconds, so there is no problem with a large domain in itself. See that there are only two variables but the sum is computed with a callback. @Misophistful CP is used to solve harder problems that require to trigger sophisticated algorithms and explore a search space (apply decisions). A simple and classical example is the sudoku problem (solved in a few ms with CP). In practice, CP is often used for planning and scheduling applications (human resources, manufacturing, etc.). This Euler problem is not relevant to CP because it can be solved with a simple "for" loop. Solving it with a CP solver is like hunting a bee with a bazooka. |
@jgFages Using the enumerated "mod" variable is clever (I would have never thought to do that!) but I think your custom aggregator would not give the right answer, because now multiple solutions are being generated for multiples of 15. For example, n = 15, mod = 3, and n = 15, mod = 5. Now 15 is counted twice in the result. And thanks for the further clarification about what types of problems CP is meant for. I'm glad to have an actual CP expert join the discussion. ;-) |
You are right I have not seen this! Although it is not that straightforward, you can solve this efficiently by specifying a search heuristic : s.set(ISF.lexico_LB(number), new Once(new IntVar[]{mod},ISF.lexico_var_selector(),ISF.min_value_selector())); It will first branch on "number" and then branch ONCE on "mod" (given the current value of number, it will not try different values for the latter). |
I've just started playing with
loco
, but I've hit an immediate brick wall where$or
isn't behaving how I expected it to.I'm trying to solve Project Euler problem 1, which is nice and easy with the
for
macro:But my first attempt at a similar approach with
loco
didn't work:I'm guessing that I've totally misunderstood how
$or
should be used, so I'd really appreciate a prod in the right direction.Thanks for your work on this cool project.
Cheers,
James
The text was updated successfully, but these errors were encountered: