use of org.cpsolver.studentsct.model.CourseRequest in project cpsolver by UniTime.
the class Test method section.
public boolean section(Student original) {
OnlineSectioningModel model = new TestModel(iModel.getProperties());
model.setOverExpectedCriterion(iModel.getOverExpectedCriterion());
Student student = new Student(original.getId());
Hashtable<CourseRequest, Set<Section>> preferredSectionsForCourse = new Hashtable<CourseRequest, Set<Section>>();
Map<Long, Section> classTable = new HashMap<Long, Section>();
synchronized (iModel) {
for (Request request : original.getRequests()) {
Request clonnedRequest = addRequest(student, original, request, classTable, model);
Enrollment enrollment = assignment().getValue(request);
if (enrollment != null && enrollment.isCourseRequest()) {
Set<Section> sections = new HashSet<Section>();
for (Section section : enrollment.getSections()) sections.add(classTable.get(section.getId()));
preferredSectionsForCourse.put((CourseRequest) clonnedRequest, sections);
}
}
}
model.addStudent(student);
model.setDistanceConflict(new DistanceConflict(iModel.getDistanceConflict().getDistanceMetric(), model.getProperties()));
model.setTimeOverlaps(new TimeOverlapsCounter(null, model.getProperties()));
for (LinkedSections link : iModel.getLinkedSections()) {
List<Section> sections = new ArrayList<Section>();
for (Offering offering : link.getOfferings()) for (Subpart subpart : link.getSubparts(offering)) for (Section section : link.getSections(subpart)) {
Section x = classTable.get(section.getId());
if (x != null)
sections.add(x);
}
if (sections.size() >= 2)
model.addLinkedSections(link.isMustBeUsed(), sections);
}
OnlineSectioningSelection selection = null;
if (model.getProperties().getPropertyBoolean("StudentWeights.MultiCriteria", true)) {
selection = new MultiCriteriaBranchAndBoundSelection(iModel.getProperties());
} else {
selection = new SuggestionSelection(model.getProperties());
}
selection.setModel(model);
selection.setPreferredSections(preferredSectionsForCourse);
selection.setRequiredSections(new Hashtable<CourseRequest, Set<Section>>());
selection.setRequiredFreeTimes(new HashSet<FreeTimeRequest>());
long t0 = JProf.currentTimeMillis();
Assignment<Request, Enrollment> newAssignment = new AssignmentMap<Request, Enrollment>();
BranchBoundNeighbour neighbour = selection.select(newAssignment, student);
long time = JProf.currentTimeMillis() - t0;
inc("[C] CPU Time", time);
if (neighbour == null) {
inc("[F] Failure");
} else {
if (iSuggestions) {
StudentPreferencePenalties penalties = new StudentPreferencePenalties(StudentPreferencePenalties.sDistTypePreference);
double maxOverExpected = 0;
int assigned = 0;
double penalty = 0.0;
Hashtable<CourseRequest, Set<Section>> enrollments = new Hashtable<CourseRequest, Set<Section>>();
List<RequestSectionPair> pairs = new ArrayList<RequestSectionPair>();
for (int i = 0; i < neighbour.getAssignment().length; i++) {
Enrollment enrl = neighbour.getAssignment()[i];
if (enrl != null && enrl.isCourseRequest() && enrl.getAssignments() != null) {
assigned++;
for (Section section : enrl.getSections()) {
maxOverExpected += model.getOverExpected(newAssignment, section, enrl.getRequest());
pairs.add(new RequestSectionPair(enrl.variable(), section));
}
enrollments.put((CourseRequest) enrl.variable(), enrl.getSections());
penalty += penalties.getPenalty(enrl);
}
}
penalty /= assigned;
inc("[S] Initial Penalty", penalty);
double nrSuggestions = 0.0, nrAccepted = 0.0, totalSuggestions = 0.0, nrTries = 0.0;
for (int i = 0; i < pairs.size(); i++) {
RequestSectionPair pair = pairs.get(i);
SuggestionsBranchAndBound suggestionBaB = null;
if (model.getProperties().getPropertyBoolean("StudentWeights.MultiCriteria", true)) {
suggestionBaB = new MultiCriteriaBranchAndBoundSuggestions(model.getProperties(), student, newAssignment, new Hashtable<CourseRequest, Set<Section>>(), new HashSet<FreeTimeRequest>(), enrollments, pair.getRequest(), pair.getSection(), null, maxOverExpected, iModel.getProperties().getPropertyBoolean("StudentWeights.PriorityWeighting", true));
} else {
suggestionBaB = new SuggestionsBranchAndBound(model.getProperties(), student, newAssignment, new Hashtable<CourseRequest, Set<Section>>(), new HashSet<FreeTimeRequest>(), enrollments, pair.getRequest(), pair.getSection(), null, maxOverExpected);
}
long x0 = JProf.currentTimeMillis();
TreeSet<SuggestionsBranchAndBound.Suggestion> suggestions = suggestionBaB.computeSuggestions();
inc("[S] Suggestion CPU Time", JProf.currentTimeMillis() - x0);
totalSuggestions += suggestions.size();
if (!suggestions.isEmpty())
nrSuggestions += 1.0;
nrTries += 1.0;
SuggestionsBranchAndBound.Suggestion best = null;
for (SuggestionsBranchAndBound.Suggestion suggestion : suggestions) {
int a = 0;
double p = 0.0;
for (int j = 0; j < suggestion.getEnrollments().length; j++) {
Enrollment e = suggestion.getEnrollments()[j];
if (e != null && e.isCourseRequest() && e.getAssignments() != null) {
p += penalties.getPenalty(e);
a++;
}
}
p /= a;
if (a > assigned || (assigned == a && p < penalty)) {
best = suggestion;
}
}
if (best != null) {
nrAccepted += 1.0;
Enrollment[] e = best.getEnrollments();
for (int j = 0; j < e.length; j++) if (e[j] != null && e[j].getAssignments() == null)
e[j] = null;
neighbour = new BranchBoundNeighbour(student, best.getValue(), e);
assigned = 0;
penalty = 0.0;
enrollments.clear();
pairs.clear();
for (int j = 0; j < neighbour.getAssignment().length; j++) {
Enrollment enrl = neighbour.getAssignment()[j];
if (enrl != null && enrl.isCourseRequest() && enrl.getAssignments() != null) {
assigned++;
for (Section section : enrl.getSections()) pairs.add(new RequestSectionPair(enrl.variable(), section));
enrollments.put((CourseRequest) enrl.variable(), enrl.getSections());
penalty += penalties.getPenalty(enrl);
}
}
penalty /= assigned;
inc("[S] Improved Penalty", penalty);
}
}
inc("[S] Final Penalty", penalty);
if (nrSuggestions > 0) {
inc("[S] Classes with suggestion", nrSuggestions);
inc("[S] Avg. # of suggestions", totalSuggestions / nrSuggestions);
inc("[S] Suggestion acceptance rate [%]", nrAccepted / nrSuggestions);
} else {
inc("[S] Student with no suggestions available", 1.0);
}
if (!pairs.isEmpty())
inc("[S] Probability that a class has suggestions [%]", nrSuggestions / nrTries);
}
List<Enrollment> enrollments = new ArrayList<Enrollment>();
i: for (int i = 0; i < neighbour.getAssignment().length; i++) {
Request request = original.getRequests().get(i);
Enrollment clonnedEnrollment = neighbour.getAssignment()[i];
if (clonnedEnrollment != null && clonnedEnrollment.getAssignments() != null) {
if (request instanceof FreeTimeRequest) {
enrollments.add(((FreeTimeRequest) request).createEnrollment());
} else {
for (Course course : ((CourseRequest) request).getCourses()) if (course.getId() == clonnedEnrollment.getCourse().getId())
for (Config config : course.getOffering().getConfigs()) if (config.getId() == clonnedEnrollment.getConfig().getId()) {
Set<Section> assignments = new HashSet<Section>();
for (Subpart subpart : config.getSubparts()) for (Section section : subpart.getSections()) {
if (clonnedEnrollment.getSections().contains(section)) {
assignments.add(section);
}
}
Reservation reservation = null;
if (clonnedEnrollment.getReservation() != null) {
for (Reservation r : course.getOffering().getReservations()) if (r.getId() == clonnedEnrollment.getReservation().getId()) {
reservation = r;
break;
}
}
enrollments.add(new Enrollment(request, clonnedEnrollment.getPriority(), course, config, assignments, reservation));
continue i;
}
}
}
}
synchronized (iModel) {
for (Request r : original.getRequests()) {
Enrollment e = assignment().getValue(r);
r.setInitialAssignment(e);
if (e != null)
updateSpace(assignment(), e, true);
}
for (Request r : original.getRequests()) if (assignment().getValue(r) != null)
assignment().unassign(0, r);
boolean fail = false;
for (Enrollment enrl : enrollments) {
if (iModel.conflictValues(assignment(), enrl).isEmpty()) {
assignment().assign(0, enrl);
} else {
fail = true;
break;
}
}
if (fail) {
for (Request r : original.getRequests()) if (assignment().getValue(r) != null)
assignment().unassign(0, r);
for (Request r : original.getRequests()) if (r.getInitialAssignment() != null)
assignment().assign(0, r.getInitialAssignment());
for (Request r : original.getRequests()) if (assignment().getValue(r) != null)
updateSpace(assignment(), assignment().getValue(r), false);
} else {
for (Enrollment enrl : enrollments) updateSpace(assignment(), enrl, false);
}
if (fail)
return false;
}
neighbour.assign(newAssignment, 0);
int a = 0, u = 0, np = 0, zp = 0, pp = 0, cp = 0;
double over = 0;
double p = 0.0;
for (Request r : student.getRequests()) {
if (r instanceof CourseRequest) {
Enrollment e = newAssignment.getValue(r);
if (e != null) {
for (Section s : e.getSections()) {
if (s.getPenalty() < 0.0)
np++;
if (s.getPenalty() == 0.0)
zp++;
if (s.getPenalty() > 0.0)
pp++;
if (s.getLimit() > 0) {
p += s.getPenalty();
cp++;
}
over += model.getOverExpected(newAssignment, s, r);
}
a++;
} else {
u++;
}
}
}
inc("[A] Student");
if (over > 0.0)
inc("[O] Over", over);
if (a > 0)
inc("[A] Assigned", a);
if (u > 0)
inc("[A] Not Assigned", u);
inc("[V] Value", neighbour.value(newAssignment));
if (zp > 0)
inc("[P] Zero penalty", zp);
if (np > 0)
inc("[P] Negative penalty", np);
if (pp > 0)
inc("[P] Positive penalty", pp);
if (cp > 0)
inc("[P] Average penalty", p / cp);
}
inc("[T0] Time <10ms", time < 10 ? 1 : 0);
inc("[T1] Time <100ms", time < 100 ? 1 : 0);
inc("[T2] Time <250ms", time < 250 ? 1 : 0);
inc("[T3] Time <500ms", time < 500 ? 1 : 0);
inc("[T4] Time <1s", time < 1000 ? 1 : 0);
inc("[T5] Time >=1s", time >= 1000 ? 1 : 0);
return true;
}
use of org.cpsolver.studentsct.model.CourseRequest in project cpsolver by UniTime.
the class StudentByRequestDate method getRequestDate.
public Long getRequestDate(Student s) {
long total = 0, cnt = 0;
for (Request r : s.getRequests()) {
if (r instanceof CourseRequest) {
CourseRequest cr = (CourseRequest) r;
if (cr.getTimeStamp() != null) {
total += cr.getTimeStamp();
cnt++;
}
}
}
if (cnt > 0)
return total / cnt;
return Long.MAX_VALUE;
}
use of org.cpsolver.studentsct.model.CourseRequest in project cpsolver by UniTime.
the class StudentChoiceOrder method avgNrChoices.
/**
* Average number of choices for each student
* @param student given student
* @return average number of choices of the given student
*/
public double avgNrChoices(Student student) {
int nrRequests = 0;
int nrChoices = 0;
for (Request request : student.getRequests()) {
if (request instanceof CourseRequest) {
CourseRequest cr = (CourseRequest) request;
if (iCriticalOnly && (!iPriority.isCritical(cr) || cr.isAlternative()))
continue;
for (Course course : cr.getCourses()) {
for (Config config : course.getOffering().getConfigs()) {
Integer nrChoicesThisCfg = iCache.get(config);
if (nrChoicesThisCfg == null) {
nrChoicesThisCfg = Integer.valueOf(nrChoices(config, 0, new HashSet<Section>()));
iCache.put(config, nrChoicesThisCfg);
}
nrChoices += nrChoicesThisCfg.intValue();
}
}
nrRequests++;
}
}
return (nrRequests == 0 ? 0.0 : ((double) nrChoices) / nrRequests);
}
use of org.cpsolver.studentsct.model.CourseRequest in project cpsolver by UniTime.
the class StudentConflict method computeConflicts.
/**
* A given enrollment is conflicting when the student is enrolled into
* another course / free time request that has an assignment that is
* overlapping with one or more assignments of the given section. See
* {@link Enrollment#isOverlapping(Enrollment)} for more details. All such
* overlapping enrollments are added into the provided set of conflicts.
*
* @param enrollment
* {@link Enrollment} that is being considered
* @param conflicts
* resultant list of conflicting enrollments
*/
@Override
public void computeConflicts(Assignment<Request, Enrollment> assignment, Enrollment enrollment, Set<Enrollment> conflicts) {
// enrollment -> conflict
for (Request request : variables()) {
if (request.equals(enrollment.getRequest()))
continue;
Enrollment e = assignment.getValue(request);
if (e == null)
continue;
if (enrollment.isOverlapping(e))
conflicts.add(e);
}
// schedule) -> unassignd a lowest priority request
while (!enrollment.getAssignments().isEmpty() && !canAssign(assignment, enrollment, conflicts)) {
Enrollment lowestPriorityEnrollment = null;
int lowestPriority = -1;
for (Request request : variables()) {
if (request.equals(enrollment.getRequest()))
continue;
if (!(request instanceof CourseRequest) || ((CourseRequest) request).isWaitlist())
continue;
Enrollment e = assignment.getValue(request);
if (e == null || conflicts.contains(e))
continue;
if (lowestPriority < request.getPriority()) {
lowestPriority = request.getPriority();
lowestPriorityEnrollment = e;
}
}
if (lowestPriorityEnrollment != null) {
conflicts.add(lowestPriorityEnrollment);
} else {
// there are only alternatives or wait-listed courses
conflicts.add(enrollment);
break;
}
}
}
use of org.cpsolver.studentsct.model.CourseRequest in project cpsolver by UniTime.
the class StudentConflict method canAssign.
/**
* True if the given enrollment can be assigned to the student. A new enrollment
* cannot be assigned to a student when the student already has the desired
* number of requests assigned (i.e., number of non-alternative course
* requests).
* @param assignment current assignment
* @param enrollment given enrollment
* @return true if the given request can be assigned
*/
public static boolean canAssign(Assignment<Request, Enrollment> assignment, Enrollment enrollment, Set<Enrollment> conflicts) {
int alt = 0;
float credit = 0;
boolean found = false;
for (Request r : enrollment.getStudent().getRequests()) {
Enrollment e = (r.equals(enrollment.getRequest()) ? enrollment : r.getAssignment(assignment));
if (r.equals(enrollment.getRequest())) {
found = true;
} else if (e != null && conflicts != null && conflicts.contains(e)) {
e = null;
}
boolean assigned = (e != null || r.equals(enrollment.getRequest()));
boolean course = (r instanceof CourseRequest);
boolean waitlist = (course && ((CourseRequest) r).isWaitlist());
if (r.isAlternative()) {
if (assigned || (!found && waitlist))
alt--;
} else {
if (course && !waitlist && !assigned)
alt++;
}
if (e != null)
credit += e.getCredit();
}
return (alt >= 0 && credit <= enrollment.getStudent().getMaxCredit());
}
Aggregations