-
Notifications
You must be signed in to change notification settings - Fork 18
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/feasibility #120
Feature/feasibility #120
Conversation
dwave/optimization/model.pyx
Outdated
elif index < 0: # allow negative indexing | ||
index += num_states | ||
|
||
return self._graph.feasible(self.states._states[index]) |
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.
I suspect it seg-faults because you need to initialize the state before calling the feasible method. This should be the cause if in your test, when calling it, you set a state and then called the feasible method right after
So you can add some python tests! :)
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.
Sorry, I think I was unclear earlier. I meant here
self._graph.initialize_state(self.states._states[index])
return self._graph.feasible(self.states._states[index])
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.
Ahh gotcha. Sorry, just my unfamiliarity with the codebase. Anything after initializing the state I'd need to clean up?
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.
I think that should be it.. there are two things worth remembering here. The C++ method initialize_state()
initialize all nodes in the graph (eagerly) to their value given the decision variables. If you were to check every single constraint from the python side, then it would be lazily from checking each constraint. Worth keeping this in mind in case one deals with models with very deep graphs on the objective side and simple constraints on the decisions (kinda a worst case scenario)
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.
I'll try doing some performance analysis and see if there's a significant cost with the eager initialization. Also could test with common problem types (i.e. models created by the generator functions) and see if it makes any difference
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.
The more I think about it, the more I think we should not expose the C++ method and just do a pure python
def feasible(self, int index = 0):
"""Check the feasibility of the state at the input index.
Args:
index: index of the state to check for feasibility.
Returns:
Feasibility of the state.
"""
return all(sym.state(index) for sym in self.iter_constraints())
sure there will be a minor performance hit. But this covers all of the edge cases (unitilized states, unresolved states, out of bounds indexing, no constraints, etc.)
If we later find it to be an issue, we can do the more performant thing. But IMO it won't be that much better after we do all of the edge case handling.
There was a bug when checking the index against the state size (used the ...
>>> i = model.integer()
>>> c = model.constant(5)
>>> model.add_constraint(i <= c)
>>> model.feasible(0)
...
ValueError: index 0 is out of range # Expected behavior
>>> model.states.resize(1)
>>> i.set_state(0, 1) # Feasible state
>>> model.feasible(0)
Process finished with exit code 139 (interrupted by signal 11:SIGSEGV) Could it be something to do with the |
raise ValueError(f"index out of range: {index}") | ||
elif index < 0: # allow negative indexing | ||
index += num_states | ||
|
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.
maybe we can also return True if number of constraints is 0
4046792
to
cda746e
Compare
cda746e
to
b8dae2f
Compare
dwave/optimization/model.pyx
Outdated
elif index < 0: # allow negative indexing | ||
index += num_states | ||
|
||
return self._graph.feasible(self.states._states[index]) |
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.
The more I think about it, the more I think we should not expose the C++ method and just do a pure python
def feasible(self, int index = 0):
"""Check the feasibility of the state at the input index.
Args:
index: index of the state to check for feasibility.
Returns:
Feasibility of the state.
"""
return all(sym.state(index) for sym in self.iter_constraints())
sure there will be a minor performance hit. But this covers all of the edge cases (unitilized states, unresolved states, out of bounds indexing, no constraints, etc.)
If we later find it to be an issue, we can do the more performant thing. But IMO it won't be that much better after we do all of the edge case handling.
Co-authored-by: Alexander Condello <arcondello@gmail.com>
Co-authored-by: Alexander Condello <arcondello@gmail.com>
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.
LGTM, will merge when/if the CI passes
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.
LGTM
@arcondello adds a
feasible()
method to theModel
class to make it easier for users to check the feasibility of a model state without manually checking the state of each constraint symbol. Addresses #82Current work will build, but throws a segfault when I try to actually call the method in Python.