General VRP constraints design discussion
Nobody has claimed this yet.
- Dominant language
- Ruby
- Stars
- 222
- Forks
- 42
- Avg merge
- 20h 35m
- Merged PRs (30d)
- 2
Description
#93 was closed in favor of 44eb655 with the comment:
If quadratic constraints are needed, it should be possible to use
index_expression(..., check_linear: false)to extend this.
I'm not sure I understand whether this will cover everything. Just to explain the motivation, I don't personally know of a significant use case for quadratic expressions is the sense of multiplying one scalar by another scalar, though maybe someone has one. The use case I am most familiar with is about disjunctions; if you have a constraint of the form some_dimension.CumulVar(A) - somedimension.CumulVar(B) <= const, there is a gotcha in or-tools where when a node becomes inactive, the cumul values associated with the node are not zeroed out, and the constraint can end up applying eliminating the solution.
Therefore the standard expression when disjunctions may apply is actually ActiveVar(A)*some_dimension.CumulVar(A) - ActiveVar(B)*some_dimension.CumulVar(B) <= const. ActiveVar being the or-tools "booleans" that indicate whether a node is active.
Or (eg. in pickup-delivery cases where the pickup and delivery are not a specific pair and may be independently deactivated) even ActiveVar(A)*ActiveVar(B)*some_dimension.CumulVar(A) - ActiveVar(A)*ActiveVar(B)*some_dimension.CumulVar(B) <= const.
I think this can be done because it's still a sum-of-products type expression, which I believe is what index_expression supports.
But I don't think it can implement arbitrary forms like ActiveVar(A)*ActiveVar(B)*(some_dimension.CumulVar(A) - some_dimension.CumulVar(B)) <= const, or ActiveVar(A)(some_dimension.CumulVar(A) - constA) - ActiveVar(B)(some_dimension.CumulVar(B) - constB) <= constC`? You'd need to rewrite into a form that has one sum-of-products on each side of the op, and if you need more than two, it won't be possible. The forms won't necessarily have equivalent performance, though I have no idea how to test that out.
So I think this would still cover a lot of people's use cases, but I guess I'm struggling to understand design intent of doing the work in index_expression instead of making the Expression support just pass everything through and letting or-tools figure it out? My understanding is that the Python bindings pass through any expression, though I haven't tested them so I could be wrong.
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the index_expression and Expression entry points, then review issue #93 and commit 44eb655. Compare the documented expression forms with the disjunction examples and the stated Python-binding behavior. Done means agreeing on the supported constraint forms and recording a clear implementation scope or design decision.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- ruby
- Domain
- api
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Needs clarification
- Newbie friendliness
- 25/100