示例#1
0
    def updateObjFcnAndSolve(self, score_weights, pref_weight, e_cap_weight, 
            congestion_weight, dept_fairness, b2b_weight):
        """choiceweights should be in order [1st choice, 2nd choice, etc]"""
        pref_weight = max(pref_weight, self.config.EPS_SAFETY_OVERRIDE)

        #normalize the score weights
        max_weight = float(max(score_weights))
        if max_weight == 0:
            max_weight = 1.
        score_weights = [w/max_weight for w in score_weights]

        #check to see if fairness constraints are already there
        if self.hasDeptFairness:
            const_names = ["DeptFairness_%s" % dept for dept in self.getDepts()]
            self.m.linear_constraints.delete(const_names)                        

        self.addDeptFairnessConstraints(score_weights)

        #normalize weights to make comparable
        e_cap_weight /= float(-len(self.course_list))
        pref_weight /= float(len(self.course_list))
        
        #VG better performance if we don't normalize here...
        #b2b_weight /= float(len(self.b2b_vars) + 1 ) #add 1 for safety

        obj_coefs = []
        for c, r, t, var in self.vars:
            #ecap weight
            coef_ecap = helpers.e_cap(c, r) * e_cap_weight

            #preference business
            coef_pref = 0
            for ix in range(len(c.roomPrefs)):
                if c.roomPrefs[ix] == r:
                    coef_pref += score_weights[ix]
            for ix in range(len(c.timePrefs)):
                if c.timePrefs[ix] == t:
                    coef_pref += score_weights[ix]

            #add large penalty if day string doesn't match prefferred
            coef_pref_day = 0.
            if not c.isPreferredDays(t):
                coef_pref_day = -self.config.SOFT_CNST_PENALTY

            obj_coefs.append(coef_pref * pref_weight + coef_ecap + coef_pref_day)
            
        self.m.objective.set_sense(self.m.objective.sense.maximize)

        #add the maxCong
        vars_only = [v for c, r, t, v in self.vars]
        vars_only += [self.maxCongVar]
        obj_coefs += [-congestion_weight]

        #add minDeptFairness
        vars_only += [self.minDept]
        obj_coefs += [dept_fairness]

        #add the bonuses for b2b teaching
        vars_only += self.b2b_vars        
        obj_coefs += [b2b_weight] * len(self.b2b_vars)

        self.m.objective.set_linear(zip(vars_only, obj_coefs))
        self.m.solve()
        
        solution = self.m.solution
        
        #Debug
        #print solution.get_status(), solution.status[solution.get_status()], 

        if solution.get_status() not in  (101, 102):  #fix this
            sol_status = solution.get_status()

            #probably infeasible
            self.m.conflict.refine(self.m.conflict.all_constraints())
            self.m.conflict.write("infeasible_conflict")

            self.m.write("ses.lp")
            print "VG Sol_status", sol_status
            print "VG solution string", solution.status[sol_status]
            raise ses.SESError("Optimizer did not solve. Check ses.lp Status and infeasible_conflict: %s %s" % 
                    (solution.status[sol_status], sol_status) ) 
示例#2
0
    def updateObjFcnAndSolve(self, score_weights, pref_weight, e_cap_weight,
                             congestion_weight, dept_fairness, b2b_weight):
        """choiceweights should be in order [1st choice, 2nd choice, etc]"""
        pref_weight = max(pref_weight, self.config.EPS_SAFETY_OVERRIDE)

        #normalize the score weights
        max_weight = float(max(score_weights))
        if max_weight == 0:
            max_weight = 1.
        score_weights = [w / max_weight for w in score_weights]

        #check to see if fairness constraints are already there
        if self.FairnessConstraints:
            [self.m.remove(const) for const in self.FairnessConstraints]

        self.FairnessConstraints = []
        self.addDeptFairnessConstraints(score_weights)

        #Normalize weights to make order unity
        e_cap_weight /= float(-len(self.course_list))
        pref_weight /= float(len(self.course_list))

        obj = grb.LinExpr()
        for c, r, t, var in self.vars:
            obj += helpers.e_cap(c, r) * e_cap_weight * var

        #add the preference weights
        for c, r, t, var in self.vars:
            for ix in range(len(c.roomPrefs)):
                if c.roomPrefs[ix] == r:
                    obj += score_weights[ix] * pref_weight * var
            for ix in range(len(c.timePrefs)):
                if c.timePrefs[ix] == t:
                    obj += score_weights[ix] * pref_weight * var

            #add large penalty if day string doesn't match prefferred
            if not c.isPreferredDays(t):
                obj -= self.config.SOFT_CNST_PENALTY * var

        #add the maxCong, minDeptFairness
        obj += -congestion_weight * self.maxCongVar
        obj += dept_fairness * self.minDept

        #add the bonuses for b2b teaching
        obj += grb.quicksum(b2b_weight * v for v in self.b2b_vars)

        self.m.setObjective(obj, grb.GRB.MAXIMIZE)
        self.m.optimize()

        if self.m.status == grb.GRB.status.INF_OR_UNBD:
            self.m.params.presolve = 0
            self.m.optimize()

        if self.m.status == grb.GRB.status.INFEASIBLE:
            self.m.computeIIS()
            self.m.write("infeasible_conflict.ilp")
            raise ses.SESError(
                "Optimization Infeasible.  Check file infeasible_conflict.ilp")
        elif self.m.status <> grb.GRB.status.OPTIMAL:
            self.m.write("ses.lp")
            raise SESError("Optimizer did not solve. Check ses.lp Status: %d" %
                           self.m.status)
示例#3
0
 def excessCap(self):
     """Compute excess capacity for every course"""
     f = lambda c: e_cap(c, c.assignedRoom)
     return map(f, self.courses_filt)
示例#4
0
    def updateObjFcnAndSolve(self, score_weights, pref_weight, e_cap_weight, 
            congestion_weight, dept_fairness, b2b_weight):
        """choiceweights should be in order [1st choice, 2nd choice, etc]"""
        pref_weight = max(pref_weight, self.config.EPS_SAFETY_OVERRIDE)

        #normalize the score weights
        max_weight = float(max(score_weights))
        if max_weight == 0:
            max_weight = 1.
        score_weights = [w/max_weight for w in score_weights]

        #check to see if fairness constraints are already there
        if self.FairnessConstraints:
            [self.m.remove(const) for const in self.FairnessConstraints]

        self.FairnessConstraints = []
        self.addDeptFairnessConstraints(score_weights)

        #Normalize weights to make order unity
        e_cap_weight /= float(-len(self.course_list))
        pref_weight /= float(len(self.course_list))

        obj = grb.LinExpr()
        for c, r, t, var in self.vars:
            obj += helpers.e_cap(c, r) * e_cap_weight * var
        
        #add the preference weights
        for c, r, t, var in self.vars:
            for ix in range(len(c.roomPrefs)):
                if c.roomPrefs[ix] == r:
                    obj += score_weights[ix] * pref_weight * var
            for ix in range(len(c.timePrefs)):
                if c.timePrefs[ix] == t:
                    obj += score_weights[ix] * pref_weight * var
        
            #add large penalty if day string doesn't match prefferred
            if not c.isPreferredDays(t):
                obj -= self.config.SOFT_CNST_PENALTY * var

        #add the maxCong, minDeptFairness
        obj += -congestion_weight * self.maxCongVar
        obj += dept_fairness * self.minDept
        
        #add the bonuses for b2b teaching
        obj += grb.quicksum(b2b_weight * v for v in self.b2b_vars)        


        self.m.setObjective(obj, grb.GRB.MAXIMIZE)
        self.m.optimize()
        
        if self.m.status == grb.GRB.status.INF_OR_UNBD:
            self.m.params.presolve = 0
            self.m.optimize()
    
        if self.m.status == grb.GRB.status.INFEASIBLE:
            self.m.computeIIS()
            self.m.write("infeasible_conflict.ilp")
            raise ses.SESError("Optimization Infeasible.  Check file infeasible_conflict.ilp")
        elif self.m.status <> grb.GRB.status.OPTIMAL:
            self.m.write("ses.lp")
            raise SESError("Optimizer did not solve. Check ses.lp Status: %d" % self.m.status) 
示例#5
0
 def summarizeExcessCap(self):
     """Compute Avg Excess capacity"""
     f = lambda c: e_cap(c, c.assignedRoom)
     return 100 * sum(map(f, self.courses_filt))/len(self.courses_filt)
示例#6
0
    def updateObjFcnAndSolve(self, score_weights, pref_weight, e_cap_weight,
                             congestion_weight, dept_fairness, b2b_weight):
        """choiceweights should be in order [1st choice, 2nd choice, etc]"""
        pref_weight = max(pref_weight, self.config.EPS_SAFETY_OVERRIDE)

        #normalize the score weights
        max_weight = float(max(score_weights))
        if max_weight == 0:
            max_weight = 1.
        score_weights = [w / max_weight for w in score_weights]

        #check to see if fairness constraints are already there
        if self.hasDeptFairness:
            const_names = [
                "DeptFairness_%s" % dept for dept in self.getDepts()
            ]
            self.m.linear_constraints.delete(const_names)

        self.addDeptFairnessConstraints(score_weights)

        #normalize weights to make comparable
        e_cap_weight /= float(-len(self.course_list))
        pref_weight /= float(len(self.course_list))

        #VG better performance if we don't normalize here...
        #b2b_weight /= float(len(self.b2b_vars) + 1 ) #add 1 for safety

        obj_coefs = []
        for c, r, t, var in self.vars:
            #ecap weight
            coef_ecap = helpers.e_cap(c, r) * e_cap_weight

            #preference business
            coef_pref = 0
            for ix in range(len(c.roomPrefs)):
                if c.roomPrefs[ix] == r:
                    coef_pref += score_weights[ix]
            for ix in range(len(c.timePrefs)):
                if c.timePrefs[ix] == t:
                    coef_pref += score_weights[ix]

            #add large penalty if day string doesn't match prefferred
            coef_pref_day = 0.
            if not c.isPreferredDays(t):
                coef_pref_day = -self.config.SOFT_CNST_PENALTY

            obj_coefs.append(coef_pref * pref_weight + coef_ecap +
                             coef_pref_day)

        self.m.objective.set_sense(self.m.objective.sense.maximize)

        #add the maxCong
        vars_only = [v for c, r, t, v in self.vars]
        vars_only += [self.maxCongVar]
        obj_coefs += [-congestion_weight]

        #add minDeptFairness
        vars_only += [self.minDept]
        obj_coefs += [dept_fairness]

        #add the bonuses for b2b teaching
        vars_only += self.b2b_vars
        obj_coefs += [b2b_weight] * len(self.b2b_vars)

        self.m.objective.set_linear(zip(vars_only, obj_coefs))
        self.m.solve()

        solution = self.m.solution

        #Debug
        #print solution.get_status(), solution.status[solution.get_status()],

        if solution.get_status() not in (101, 102):  #fix this
            sol_status = solution.get_status()

            #probably infeasible
            self.m.conflict.refine(self.m.conflict.all_constraints())
            self.m.conflict.write("infeasible_conflict")

            self.m.write("ses.lp")
            print "VG Sol_status", sol_status
            print "VG solution string", solution.status[sol_status]
            raise ses.SESError(
                "Optimizer did not solve. Check ses.lp Status and infeasible_conflict: %s %s"
                % (solution.status[sol_status], sol_status))
示例#7
0
 def excessCap(self):
     """Compute excess capacity for every course"""
     f = lambda c: e_cap(c, c.assignedRoom)
     return map(f, self.courses_filt)
示例#8
0
 def summarizeExcessCap(self):
     """Compute Avg Excess capacity"""
     f = lambda c: e_cap(c, c.assignedRoom)
     return 100 * sum(map(f, self.courses_filt)) / len(self.courses_filt)
示例#9
0
 def test_e_cap(self):
     self.assertEqual(helpers.e_cap(self.course3, self.room3), 0)
     self.assertEqual(helpers.e_cap(self.course3, self.room1), 0.15)