def exploreRectangleBasically(self, R, lp, ubSet): newY = (R.z1[1] + R.z2[1]) / 2.0 if params.verbosity > 1: print '(BBM) \tnewY:', newY boundRight = self.right if newY - R.z2[1] >= params.inputData.z2Epsilon: z1Bar = self.solveLexmin(lp, 1, self.right, newY, ubSet, R) else: if params.verbosity > 1: print '(BBM)\tskipping too small bottom rectangle' z1Bar = R.z2 if params.verbosity > 1: print '(BBM) \tz1Bar:', z1Bar if z1Bar and z1Bar[0] <= R.z2[0] - params.inputData.z1Epsilon: self.pushIfMust(Rectangle(z1Bar, R.z2)) print util.TS() + '\tNew solution:\tz1 =', z1Bar[0], \ '\tz2 =', z1Bar[1] newX = z1Bar[0] - params.inputData.z1Epsilon if params.verbosity > 1: print '(BBM) \tnewX:', newX boundTop = self.top if newX - R.z1[0] >= params.inputData.z1Epsilon: z2Bar = self.solveLexmin(lp, 2, newX, boundTop, ubSet, R) else: if params.verbosity > 1: print '(BBM)\tskipping too small top rectangle' z2Bar = R.z1 if params.verbosity > 1: print '(BBM) \tz2Bar:', z2Bar if z2Bar and z2Bar[0] >= R.z1[0] + params.inputData.z1Epsilon: self.pushIfMust(Rectangle(R.z1, z2Bar)) print util.TS() + '\tNew solution:\tz1 =', z2Bar[0], \ '\tz2 =', z2Bar[1]
def search(self, lp, ubSet): # initialisations... self.right = lp.validBoundRight or params.inputData.boundRight() self.top = lp.validBoundTop or params.inputData.boundTop() print 'Starting balanced box method with boundRight =', self.right, print 'and boundTop =', self.top # queue of boxes that still need to be processed try: # extreme points #zT = lp.lexmin(1, self.right, self.top, ubSet) zT = self.solveLexmin(lp, 1, self.right, self.top, ubSet) print util.TS() + '\t\tzT:\tz1 =', zT[0], '\tz2 =', zT[1] #zB = lp.lexmin(2, self.right, self.top, ubSet) zB = self.solveLexmin(lp, 2, self.right, self.top, ubSet) print util.TS() + '\t\tzB:\tz1 =', zB[0], '\tz2 =', zB[1] self.area = (zB[0] - zT[0]) * (zT[1] - zB[1]) if params.verbosity > 1: print 'Area of initial rectangle:', self.area # add the first box to the list of boxes that need to be processed self.pushIfMust(Rectangle(zT, zB)) # main loop while not self.queue.empty(): R = self.queue.pop() self.exploreRectangle(R, lp, ubSet) # we're done except util.TimeLimitReachedException as e: print e print util.TS() + '\tbalanced box method is over'
def exploreRectangleWithHarvesting(self, R, lp, ubSet): # step 1: solve a weighted sum with equal weights self.solveWS(lp, 1, 1, R.z2[0], R.z1[1], ubSet) # step 2: harvest solutions if self.relaxed: lHat = self.getIntegerSolutionsFromRect(R, self.harvested) else: lHat = self.getIntegerSolutionsFromRect( R, lp.getSolutionPoolVectors()) lHat.filterWith(ubSet) # special case: no solution was harvested if len(lHat.solutions) == 0: self.exploreRectangleBasically(R, lp, ubSet) return done = False # main loop while len(lHat.solutions) > 0 and not done: z1Hat = lHat.solutions[-1] Rb = Rectangle((R.z1[0], z1Hat.z2 - params.inputData.z2Epsilon), R.z2) z1Bar = self.solveLexmin(lp, 1, R.z2[0], Rb.z1[1], ubSet, R) if not z1Bar: return if z1Bar and not util.closeEnough(z1Bar, R.z2): # no need to add z1Bar, it's already in ubSet print util.TS() + '\tNew solution:\tz1 =', z1Bar[0], \ '\tz2 =', z1Bar[1] self.pushIfMust(Rectangle(z1Bar, R.z2)) Rt = Rectangle(R.z1, (z1Bar[0] - params.inputData.z1Epsilon, z1Hat.z2)) if z1Hat.z1 < z1Bar[0] - util.epsilon: z2Bar = self.solveWS(lp, 1, 0, Rt.z2[0], z1Hat.z2, ubSet) else: lHat.solutions = [ zi for zi in lHat.solutions if (zi.z1, zi.z2) in Rt and zi != z1Hat ] z2Bar = self.solveLexmin(lp, 2, Rt.z2[0], Rt.z1[1], ubSet, R) if z2Bar and not util.closeEnough(z2Bar, R.z1): tmpR = Rectangle(R.z1, z2Bar) lHat.solutions = [ zi for zi in lHat.solutions if (zi.z1, zi.z2) in tmpR and zi != z1Hat and (zi.z1, zi.z2) != z2Bar ] if len(lHat.solutions) == 0: done = True # no need to add z2Bar here, it's already in ubSet print util.TS() + '\tNew solution:\tz1 =', z2Bar[0], \ '\tz2 =', z2Bar[1] self.pushIfMust(Rectangle(R.z1, z2Bar)) else: R.z2 = z2Bar
def storePoints(self, fName): f = file(fName, 'w') for s in self.solutions: f.write(str(s.z1) + '\t' + str(s.z2) + '\n') f.close() print util.TS(), '\tStored UB set to', fName, print '(' + str(len(self.solutions)) + ' solutions)'
def solve(self, lp, ub, firstObj): # initialisations... right = lp.validBoundRight or params.inputData.boundRight() top = lp.validBoundTop or params.inputData.boundTop() localRight, localTop = right, top print util.TS(), '\tStarting bi-directional epsilon-constraint', print 'with boundRight =', right, 'and boundTop =', top currentObj = firstObj lastFound = None try: while True: z1, z2 = None, None r, t = (right, localTop) if currentObj == 1 else (localRight, top) if self.relaxed: point = self.solver.solve(lp, currentObj, r, t, ub) else: point = lp.lexmin(currentObj, r, t, ub) if point: z1, z2 = point if lastFound and util.closeEnough(point, lastFound): print util.TS() + '\tepsilon-constraint', print 'framework is over' return else: lastFound = point if params.verbosity > 0: print util.TS() + '\tNew solution:\tz1 =', z1, \ '\tz2 =', z2 if currentObj == 1: localTop = z2 - params.inputData.z2Epsilon currentObj = 2 else: localRight = z1 - params.inputData.z1Epsilon currentObj = 1 except util.TimeLimitReachedException as e: print e print util.TS() + '\tepsilon-constraint framework is over'
def solve(self, lp, ub, singleObj): # initialisations... right = lp.validBoundRight or params.inputData.boundRight() top = lp.validBoundTop or params.inputData.boundTop() print util.TS(), '\tStarting epsilon-constraint', print 'with boundRight =', right, 'and boundTop =', top if singleObj == 1: print '\t\tOptimising z1 first' elif singleObj == 2: print '\t\tOptimising z2 first' else: print 'Error: invalid objective:', singleObj sys.exit(22) try: while True: z1, z2 = None, None if self.relaxed: point = self.solver.solve(lp, singleObj, right, top, ub) else: point = lp.lexmin(singleObj, right, top, ub) if point: z1, z2 = point # if z1 is None: print util.TS() + '\tepsilon-constraint', print 'framework is over' return else: if params.verbosity > 0: print util.TS() + '\tNew solution:\tz1 =', z1, \ '\tz2 =', z2 if singleObj == 1: top = z2 - params.inputData.z2Epsilon else: right = z1 - params.inputData.z1Epsilon except util.TimeLimitReachedException as e: print e print util.TS() + '\tepsilon-constraint framework is over'
def updateStatusIfNeeded(): if self.__class__.nNodes % 50 == 0: print util.TS(), '\tBIOBAB:\t', len(self.queue), print 'nodes \t|UB|:', len(ub.solutions)
def search(self, node, ub, branchers=[ ClosestToOneBinaryPriorityBrancher(), OftenFractionalBinaryPriorityBrancher(), FractionalOnAverageBinaryPriorityBrancher(), FractionalAverageBinaryPriorityBrancher(), ], bounder=Bounder(), wrapped=False): # def updateStatusIfNeeded(): if self.__class__.nNodes % 50 == 0: print util.TS(), '\tBIOBAB:\t', len(self.queue), print 'nodes \t|UB|:', len(ub.solutions) # osbStats = [] if not wrapped: print util.TS() + '\tstarting bi-objective branch-and-bound (' + \ self.strategy + ')' self.queue.push(node) while not self.queue.empty(): node = self.queue.pop() self.__class__.nNodes += 1 if params.verbosity == 1 and not wrapped: updateStatusIfNeeded() elif params.verbosity > 1: prefix = len(node.branchingDecisions) * '+-' print util.TS() + '\t', prefix, print '[f1 <=', str( node.right), '| f2 <=', str(node.top) + ']', print node.branchingDecisions, \ '(' + str(len(self.queue)) + ' nodes, |UB| =', \ str(len(ub.solutions)) + ')' node.applyBranchingDecisions() try: lb = bounder.bound(node, ub) except util.TimeLimitReachedException as e: if not wrapped: print e return else: raise e node.cancelBranchingDecisions() # if params.verbosity > 2: print print 'LB:', lb print # if not lb.isLeaf(): if not params.objectiveSpaceBranching: subLBs = [lb] else: subLBs = lb.split(node, ub) if len(subLBs) > 1: osbStats.append((node.depth, len(subLBs))) for slb in subLBs: for brancher in branchers: branches = brancher.branch(slb) if len(branches) > 0: for branch in branches: self.queue.push(\ self.nodeClass(node.lp, min(node.right, slb.right()), min(node.top, slb.top()), node.branchingDecisions + \ [ branch ], node.depth + 1 ) ) break if not wrapped: print util.TS() + '\tbi-objective branch-and-bound is over' if params.verbosity > 0 and not wrapped: print 'stats on OSB:', osbStats
def storeSolutions(self, baseName): for i, s in enumerate(self.solutions): s.storeSolution(baseName) print util.TS(), '\tStored', len(self.solutions), print 'solutions with basename:', baseName