From beeb84bfcb8872002bf2297d12a8a9efa5a08960 Mon Sep 17 00:00:00 2001 From: Stefan Vigerske Date: Thu, 22 Oct 2026 16:48:30 +0200 Subject: [PATCH] handle =unbd= from solu file --- ipet/validation/Validation.py | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/ipet/validation/Validation.py b/ipet/validation/Validation.py index 8f89ff7..91d2f8d 100644 --- a/ipet/validation/Validation.py +++ b/ipet/validation/Validation.py @@ -20,6 +20,7 @@ class SolufileMarkers: OPT = "=opt=" INF = "=inf=" + UNBD = "=unbd=" BEST = "=best=" UNKN = "=unkn=" BESTDUAL = "=bestdual=" @@ -172,6 +173,8 @@ def readSoluFile(self, solufilename : str) -> dict: elif marker == SolufileMarkers.INF: infotuple[self.__primalidx__] = self.__infeas__ + elif marker == SolufileMarkers.UNBD: + infotuple[self.__dualidx__] = self.__infeas__ soludict[problemname] = tuple(infotuple) return soludict @@ -287,7 +290,7 @@ def getReferencePb(self, problemname : str) -> float: """ reference = self.referencedict.get(problemname, (None, None)) - if self.isUnkn(reference) or self.isInf(reference) or self.isFeas(reference): + if self.isUnkn(reference) or self.isInf(reference) or self.isFeas(reference) or self.isUnbounded(reference): return None else: return reference[self.__primalidx__] @@ -307,7 +310,7 @@ def getReferenceDb(self, problemname : str) -> float: """ reference = self.referencedict.get(problemname, (None, None)) - if self.isUnkn(reference) or self.isInf(reference) or self.isFeas(reference): + if self.isUnkn(reference) or self.isInf(reference) or self.isFeas(reference) or self.isUnbounded(reference): return None else: return reference[self.__dualidx__] @@ -385,6 +388,22 @@ def isInf(self, referencetuple : tuple) -> bool: """ return referencetuple[self.__primalidx__] == self.__infeas__ + def isUnbounded(self, referencetuple : tuple) -> bool: + """is this an unbounded reference? + + Parameters: + ----------- + + referencetuple : tuple + tuple containing a primal and dual reference bound + + Return: + ------- + bool + True if reference bound is unbounded, False otherwise + """ + return referencetuple[self.__dualidx__] == self.__infeas__ + def isFeas(self, referencetuple): """is this a feasible reference? @@ -483,6 +502,10 @@ def isReferenceConsistent(self, x : pd.Series) -> str : if sstatus != SolverStatusCodes.Infeasible and not pd.isna(pb) and not isInf(pb): return ProblemStatusCodes.FailSolOnInfeasibleInstance + elif self.isUnbounded(reference): + if sstatus != SolverStatusCodes.Unbounded and not pd.isna(db) and not isInf(db): + return ProblemStatusCodes.FailDualBound + elif self.isFeas(reference): if sstatus == SolverStatusCodes.Infeasible: return ProblemStatusCodes.FailDualBound