示例#1
0
 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]
示例#2
0
 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'
示例#3
0
 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
示例#4
0
 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'
示例#7
0
 def updateStatusIfNeeded():
     if self.__class__.nNodes % 50 == 0:
         print util.TS(), '\tBIOBAB:\t', len(self.queue),
         print 'nodes \t|UB|:', len(ub.solutions)
示例#8
0
    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
示例#9
0
 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