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) )
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)
def excessCap(self): """Compute excess capacity for every course""" f = lambda c: e_cap(c, c.assignedRoom) return map(f, self.courses_filt)
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)
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)
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))
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)
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)