I'm trying to write a custom value propagator for SCIP. I have some complex logic that can detect additional values that can also be fixed whenever one or several are fixed (via the branching mechanism). I have the code below that apparently makes everything be infeasible (which is not correct). My questions for it:
class MyPropagator(scip.Prop):
def propexec(self, proptiming):
vars = self.model.getVars(transformed=False)
hit_some = False
node = self.model.getCurrentNode()
for var in vars:
if self.model.isFeasEQ(var.getLbLocal(), var.getUbLocal()): # is fixed in subtree?
impossible, wants_fix = self.check_constraints(var.name)
if impossible:
return {"result": scip.scip.PY_SCIP_RESULT.CUTOFF}
for key_var, value in wants_fix: # fix each of these in the subtree
self.model.chgVarLbNode(node, key_var, value)
self.model.chgVarUbNode(node, key_var, value)
hit_some = True
if hit_some:
return {"result": scip.scip.PY_SCIP_RESULT.REDUCEDDOM}
return {"result": scip.scip.PY_SCIP_RESULT.DIDNOTFIND}
chgVarLb
instead of chgVarLbNoode
. It will automatically add the bound change correctly as a local change to the current node.getVars
is fine, as long as you use the transformed ones.