def rankPerformance(self, sInst): ### Accepting the opt sense from result tables, if given if self.nOptSenseGiven != -2: self.nOptSense = self.nOptSenseGiven ### Compare methods on this instance: if not self.fContr and self.nReported == len(self.lResLogs): if len(self.lNOFZN) == 1: self.matrRanking[self.lNOFZN[0], "ONFZ"] += 1 self.matrRankingMsg[self.lNOFZN[0], "ONFZ"].append( \ str(sInst) + ": the ONLY NON-FLATTENED") elif len(self.lOpt) == 1: self.matrRanking[self.lOpt[0], "OOpt"] += 1 self.matrRankingMsg[self.lOpt[0], "OOpt"].append( \ str(sInst) + ": the ONLY OPTIMAL") elif len(self.lSatAll) == 1: self.matrRanking[self.lSatAll[0], "OSaC"] += 1 self.matrRankingMsg[self.lSatAll[0], "OSaC"].append( \ str(sInst) + ": the ONLY SAT-COMPLETE") elif len(self.lOpt) == 0 and len(self.lFeas) == 1: self.matrRanking[self.lFeas[0], "OFeas"] += 1 self.matrRankingMsg[self.lFeas[0], "OFeas"].append( \ str(sInst) + ": the ONLY FEASIBLE") elif len(self.lSatAll) == 0 and len(self.lSat) == 1: self.matrRanking[self.lSat[0], "OSat"] += 1 self.matrRankingMsg[self.lSat[0], "OSat"].append( \ str(sInst) + ": the ONLY SAT") elif len(self.lOpt) == 0 and len(self.lFeas) > 1: self.nNoOptAndAtLeast2Feas += 1 elif len(self.lInfeas) == 1: self.matrRanking[self.lInfeas[0], "OInfeas"] += 1 self.matrRankingMsg[self.lInfeas[0], "OInfeas"].append( \ str(sInst) + ": the ONLY INFeasible") if not self.fContr \ and 0==len(self.lInfeas) and 1<len(self.lFeas) and 0!=self.nOptSense: self.lPrimBnd.sort() if self.nOptSense > 0: self.lPrimBnd.reverse() dBnd, dNM = zip(*self.lPrimBnd) dBetter = (dBnd[0] - dBnd[1]) * self.nOptSense if 1e-2 < dBetter: ## Param? TODO self.matrRanking[dNM[0], "BPri"] += 1 self.matrRankingMsg[dNM[0], "BPri"].append( str(sInst) \ + ": the best OBJ VALUE by " + str(dBetter) \ + "\n PRIMAL BOUNDS AVAILABLE: " + strNL( "\n ", self.lPrimBnd)) if not self.fContr \ and 0==len(self.lInfeas) and 1<len(self.lDualBnd) and 0!=self.nOptSense: self.lDualBnd.sort() if self.nOptSense < 0: self.lDualBnd.reverse() dBnd, dNM = zip(*self.lDualBnd) dBetter = (dBnd[1] - dBnd[0]) * self.nOptSense if 1e-2 < dBetter: ## Param/adaptive? TODO self.matrRanking[dNM[0], "BDua"] += 1 self.matrRankingMsg[dNM[0], "BDua"].append( str(sInst) \ + ": the best DUAL BOUND by " + str(dBetter) \ + "\n DUAL BOUNDS AVAILABLE: " + strNL( "\n ", self.lDualBnd))
def checkContradictions(self, sInst): self.fContr = False if len(self.lOpt) + len(self.lFeas) + len(self.lSatAll) + len( self.lSat) > 0 and len(self.lInfeas) > 0: self.nContrStatus += 1 self.fContr = True print( "CONTRADICTION of STATUS: instance " + str(sInst) + ": " + \ "\n OPTIMAL: " + strNL( "\n ", self.lOpt) + \ "\n FEAS: " + strNL( "\n ", self.lFeas) + \ "\n SAT_COMPLETE: " + strNL( "\n ", self.lSatAll) + \ "\n SAT: " + strNL( "\n ", self.lSat) + \ "\n INFEAS: " + strNL( "\n ", self.lInfeas), file= self.ioContrStatus ) if len(self.mOptVal) > 1: self.nContrOptVal += 1 self.fContr = True print( "CONTRADICTION of OPTIMAL VALUES: " + str(sInst) + \ ": " + strNL( "\n ", self.mOptVal.items()), file=self.ioContrOptVal ) self.nOptSense = 0 ## Take as SAT by default if len(self.lPrimBnd) > 0 and len(self.lDualBnd) > 0 and len( self.lOpt) < self.nReported: lKeysP, lValP = zip(*self.lPrimBnd) lKeysD, lValD = zip(*self.lDualBnd) nPMin, nPMax, nDMin, nDMax = \ min(lKeysP), max(lKeysP), \ min(lKeysD), max(lKeysD) if nPMax <= nDMin + 1e-6 and nPMin < nDMax - 1e-6: self.nOptSense = 1 ## maximize elif nPMin >= nDMax - 1e-6 and nPMax > nDMin + 1e-6: self.nOptSense = -1 ## minimize elif nPMax > nDMin + 1e-6 and nPMin < nDMax - 1e-6 or \ nPMin < nDMax - 1e-6 and nPMax > nDMin + 1e-6: self.nContrBounds += 1 self.fContr = True print( "CONTRADICTION of BOUNDS: instance " + str(sInst) + \ ":\n PRIMALS: " + strNL( "\n ", self.lPrimBnd) + \ ",\n DUALS: " + strNL( "\n ", self.lDualBnd), file = self.ioContrBounds ) else: self.nOptSense = 0 ## SAT if 1 == len(self.sSenses) and self.nOptSense != 0: if self.nOptSense != self.nOptSenseGiven: ## access the 'given' opt sense print( "CONTRADICITON of IMPLIED OBJ SENSE: Instance "+ str(sInst) + \ ": primal bounds " + strNL( "\n ", self.lPrimBnd) + \ " and dual bounds "+ strNL( "\n ", self.lDualBnd) + \ " together imply opt sense " + str(self.nOptSense) + \ ", while result logs say "+ str(self.nOptSenseGiven), file=self.ioContrBounds )