loco icon indicating copy to clipboard operation
loco copied to clipboard

Wrong result when using :minimize on product of negative vars

Open yuhan0 opened this issue 6 years ago • 3 comments

I'm trying to use Loco to minimize the sum of squared errors in a constraint problem, however it seems that the solver is giving the wrong result when the variable ranges go into the negative numbers:

(solutions
  [($in :e -5 5)]
  :minimize ($* :e :e))
;; => ({:e 5})

Oddly enough, creating a temporary variable solves the issue in this case, but not in a larger model involving multiple squared vars.

(solutions
  [($in :e -5 5)
   ($in :sse -1000 1000 :bounded)
   ($= :sse ($* :e :e))]
  :minimize :sse)
;; => ({:e 0, :sse 0})

Am I doing something wrong here? The docstring for $* says

One of the arguments can be a number greater than or equal to -1.

which is confusing as to whether it handles both arguments being negative.

yuhan0 avatar Feb 25 '19 06:02 yuhan0

You're right, something seems off here. As an experiment I changed the boundaries of your :sse variable to [-25,25], to mimic what Loco is doing behind the scenes in your first example, and was able to reproduce the bizarre result:

user> (solutions
        [($in :e -5 5)
         ($in :sse -25 25)
         ($= :sse ($* :e :e))]
        :minimize :sse)
({:e -5, :sse -25})

It's possible there's a bug in Choco, but it would need more investigation and might not even get fixed upstream since I'm not depending on the latest major version of Choco. If I'm ever able to dust off and improve this project, my first TODO item is to update that dependency, which would give us more reliability in the underlying engine.

aengelberg avatar Feb 25 '19 07:02 aengelberg

Just wanted to say that I've been trying out various constraint solvers and Loco had far by the most elegant and functional API for declaring constraint problems, I'm just slightly wary of the correctness of its solutions after encountering the above bug.

Is there anything I could help with upgrading to the latest upstream Choco version?

yuhan0 avatar Mar 18 '19 10:03 yuhan0

Can confirm that this was due to a bug in the Choco library, and not in the loco source. I'm working on a fork together with @aengelberg in https://github.com/mortenschioler/loco. The upstream dependency to Choco is updated in [io.github.mortenschioler/loco "0.3.2"], which I confirmed fixed the issue.

;; with `[org.choco-solver/choco-solver "0.3.0"], as in `[loco/loco "0.3.1"]:
(solutions
  [($in :e -5 5)]
  :minimize ($* :e :e))
=> ({:e 5})

;; with `[org.choco-solver/choco-solver "0.3.3"], as in `[io.github.mortenschioler/loco "0.3.2"]:
(solutions
  [($in :e -5 5)]
  :minimize ($* :e :e))
=> ({:e 0})

mortenschioler avatar Mar 17 '23 11:03 mortenschioler