ConvertTight: Detect and fix infeasibility

This commit is contained in:
2021-01-12 10:05:57 -06:00
parent e59386f941
commit f77d1d5de9
6 changed files with 112 additions and 5 deletions

View File

@@ -33,6 +33,7 @@ class GurobiSolver(InternalSolver):
"""
if params is None:
params = {}
params["InfUnbdInfo"] = True
from gurobipy import GRB
self.GRB = GRB
@@ -132,7 +133,6 @@ class GurobiSolver(InternalSolver):
if iteration_cb is None:
iteration_cb = lambda: False
while True:
logger.debug("Solving MIP...")
with RedirectOutput(streams):
if lazy_cb is None:
self.model.optimize()
@@ -176,6 +176,13 @@ class GurobiSolver(InternalSolver):
var = self._all_vars[var_name][index]
return self._get_value(var)
def is_infeasible(self):
return self.model.status in [self.GRB.INFEASIBLE, self.GRB.INF_OR_UNBD]
def get_farkas_dual(self, cid):
c = self.model.getConstrByName(cid)
return c.farkasDual
def _get_value(self, var):
if self.cb_where == self.GRB.Callback.MIPSOL:
return self.model.cbGetSolution(var)
@@ -280,6 +287,10 @@ class GurobiSolver(InternalSolver):
c = self.model.getConstrByName(cid)
c.Sense = sense
def get_constraint_sense(self, cid):
c = self.model.getConstrByName(cid)
return c.Sense
def set_constraint_rhs(self, cid, rhs):
c = self.model.getConstrByName(cid)
c.RHS = rhs

View File

@@ -191,6 +191,23 @@ class InternalSolver(ABC):
"""
pass
@abstractmethod
def is_infeasible(self):
"""
Returns True if the model has been proved to be infeasible.
Must be called after solve.
"""
pass
@abstractmethod
def get_farkas_dual(self, cid):
"""
If the model is infeasible, returns a portion of the infeasibility certificate
corresponding to the given constraint. If the model is feasible, calling this
function raises an error.
"""
pass
@abstractmethod
def is_constraint_satisfied(self, cobj):
pass
@@ -199,6 +216,10 @@ class InternalSolver(ABC):
def set_constraint_sense(self, cid, sense):
pass
@abstractmethod
def get_constraint_sense(self, cid):
pass
@abstractmethod
def set_constraint_rhs(self, cid, rhs):
pass

View File

@@ -258,5 +258,14 @@ class BasePyomoSolver(InternalSolver):
def set_constraint_sense(self, cid, sense):
raise Exception("Not implemented")
def get_constraint_sense(self, cid):
raise Exception("Not implemented")
def set_constraint_rhs(self, cid, rhs):
raise Exception("Not implemented")
def is_infeasible(self):
raise Exception("Not implemented")
def get_farkas_dual(self, cid):
raise Exception("Not implemented")