ConvertTight: Detect and fix sub-optimality

This commit is contained in:
2021-01-12 11:56:25 -06:00
parent c9ad7a3f56
commit d67af4a26b
5 changed files with 109 additions and 28 deletions

View File

@@ -162,6 +162,12 @@ class GurobiSolver(InternalSolver):
"Warm start value": self._extract_warm_start_value(log),
}
def get_sense(self):
if self.model.modelSense == 1:
return "min"
else:
return "max"
def get_solution(self):
self._raise_if_callback()
@@ -179,9 +185,12 @@ class GurobiSolver(InternalSolver):
def is_infeasible(self):
return self.model.status in [self.GRB.INFEASIBLE, self.GRB.INF_OR_UNBD]
def get_farkas_dual(self, cid):
def get_dual(self, cid):
c = self.model.getConstrByName(cid)
return c.farkasDual
if self.is_infeasible():
return c.farkasDual
else:
return c.pi
def _get_value(self, var):
if self.cb_where == self.GRB.Callback.MIPSOL:

View File

@@ -200,11 +200,20 @@ class InternalSolver(ABC):
pass
@abstractmethod
def get_farkas_dual(self, cid):
def get_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.
If the model is feasible and has been solved to optimality, returns the optimal
value of the dual variable associated with this constraint. If the model is infeasible,
returns a portion of the infeasibility certificate corresponding to the given constraint.
Solve must be called prior to this method.
"""
pass
@abstractmethod
def get_sense(self):
"""
Returns the sense of the problem (either "min" or "max").
"""
pass

View File

@@ -267,5 +267,8 @@ class BasePyomoSolver(InternalSolver):
def is_infeasible(self):
raise Exception("Not implemented")
def get_farkas_dual(self, cid):
def get_dual(self, cid):
raise Exception("Not implemented")
def get_sense(self):
raise Exception("Not implemented")