-
Notifications
You must be signed in to change notification settings - Fork 25
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
DirectVariable prototype #121
base: master
Are you sure you want to change the base?
Conversation
Yes, I like this idea a lot. |
@@ -387,3 +387,31 @@ def deepcopy(self, memodict={}): | |||
""" | |||
copied_args = self._deepcopy_args(memodict) | |||
return Xor(copied_args) | |||
|
|||
class NativeConstraint(Expression): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't we want to subclass GlobalConstraint
for this? Then current transformations will be able to work as is
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, because then the decompose()
function should be supported, while the idea is that this can only be used directly.
transformations should continue to work though... it should handle any expression (e.g. leave these as is)
Hello All, I employ the ortools interval constraints quite a bit in my code. I'd love to use this NativeConstraint to get all my problem's constraints into the cpmpy model.constraints list (we make use of this downstream, and having some constraints only in the ortools solver makes the code messy). Unfortunately, the ortools interval constraints mix the concept of constraint and variable by requiring that the constraint itself be named (see docs). Since string values can't be part of the Below are screenshots of an example test (I put it as a new case in the Thanks again for the wonderful package! |
Apologies, there is a typo in the above code. The |
Hi Max, |
Yes, the name and more examples.
I think the IntervalVar of Max is really the missing piece. But the provided example is not enough: it mixes variable and constraint indeed, with as purpose to be used in other constraints (e.g. AddCumulative). So, what do we need to do to support that? Perhaps we need to add to our ORT object a
meaning that if you do
or so? If we can think of a clean way to have both NativeConstraint and these intervalvar/optionalvars, then we greatly increase the things we can model in CPMpy (for this and future solvers) |
|
Could you work out an example to see if that would work? |
# Conflicts: # cpmpy/solvers/ortools.py
I implemented the DirectVar idea for OR-Tools. It is surprisingly elegant. I only had to make minor changes to |
@@ -387,3 +387,31 @@ def deepcopy(self, memodict={}): | |||
""" | |||
copied_args = self._deepcopy_args(memodict) | |||
return Xor(copied_args) | |||
|
|||
class NativeConstraint(Expression): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, because then the decompose()
function should be supported, while the idea is that this can only be used directly.
transformations should continue to work though... it should handle any expression (e.g. leave these as is)
cpmpy/expressions/__init__.py
Outdated
@@ -18,8 +18,8 @@ | |||
|
|||
# we only import methods/classes that are used for modelling | |||
# others need to be imported by the developer explicitely | |||
from .variables import boolvar, intvar, cpm_array | |||
from .variables import boolvar, intvar, cpm_array, DirectVar |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
for user-facing functions we are using lowercase (e.g. boolvar, intvar) I think I will lowercase this too
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
or is this the _impl and should we allow shape=... too
also, there is a difference between the name of a variable and the name of the internal API call...
will think some more about it
I've did the reverse exercise: how would we want to model with these new capabilities? See 'examples/jobshop_ortools.py' added, a slight modification from jobshop.py, where I use the current 'direct solver access' capabilities of CPMpy to create custom variables and constraints. Current, variables: # make intervalvars... ensures start + dur = end
intervals = np.zeros(shape=(machines_count,jobs_count), dtype=object)
for m in all_machines:
for j in all_jobs:
intervals[m,j] = model.ort_model.NewIntervalVar(
model.solver_var(start_time[m,j]), jobs_data[j,m], model.solver_var(end_time[m,j]), f"interval[{m},{j}]") where we should discuss what we want, for example maximal convenience could be with: intervals = directvar("NewIntervalVar", [start_time, jobs_data.T, end_time], shape=start_time.shape, name="interval") where side-note: in ortools creating these variables ensures that their constraints are ensured. It is a mix of variable and constraint... so we should probably allow to m += intervals because people might create intervalvars without using them in future constraints while still wanting the relation between start/size/end to be enforced... Then, the overlap constraint is with current direct access: for j in all_jobs:
model.ort_model.AddNoOverlap(intervals[:,j]) and could become: for j in all_jobs:
model += DirectConstraint("AddNoOverlap", intervals[:,j]) Please comment @IgnaceBleukx and others watching this. |
That would absolutely be the preferred way of doing things indeed. I hadn't thought of adding a
This is very easy to do right? Very similar to something like Now most of the Fuzz-test bugs are fixed, I think this pull request and the bounds-computation issues are highest on the wishlist! |
…ecific SolverLookup calls in the examples
Converted to (lesser priority) draft. Please say something here if a 'DirectVariable' is what you need, we need a bit more use cases/testing before merging this. |
# Conflicts: # cpmpy/expressions/__init__.py # cpmpy/expressions/globalconstraints.py # cpmpy/expressions/variables.py # cpmpy/solvers/ortools.py # tests/test_direct.py
# Conflicts: # cpmpy/solvers/exact.py
I have worked some more on this feature, also adding tests for all solvers and some documentation in Should be ready for review |
See #74
A proposal to make native constraints (API calls) more accessible, like we use global constraints.