Search in sources :

Example 11 with CourseRequest

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;
}
Also used : StudentPreferencePenalties(org.cpsolver.studentsct.StudentPreferencePenalties) Set(java.util.Set) TreeSet(java.util.TreeSet) HashSet(java.util.HashSet) HashMap(java.util.HashMap) Config(org.cpsolver.studentsct.model.Config) DistanceConflict(org.cpsolver.studentsct.extension.DistanceConflict) ArrayList(java.util.ArrayList) SuggestionSelection(org.cpsolver.studentsct.online.selection.SuggestionSelection) CourseReservation(org.cpsolver.studentsct.reservation.CourseReservation) Reservation(org.cpsolver.studentsct.reservation.Reservation) LinkedSections(org.cpsolver.studentsct.constraint.LinkedSections) Enrollment(org.cpsolver.studentsct.model.Enrollment) SuggestionsBranchAndBound(org.cpsolver.studentsct.online.selection.SuggestionsBranchAndBound) Course(org.cpsolver.studentsct.model.Course) HashSet(java.util.HashSet) MultiCriteriaBranchAndBoundSelection(org.cpsolver.studentsct.online.selection.MultiCriteriaBranchAndBoundSelection) FreeTimeRequest(org.cpsolver.studentsct.model.FreeTimeRequest) Hashtable(java.util.Hashtable) Request(org.cpsolver.studentsct.model.Request) CourseRequest(org.cpsolver.studentsct.model.CourseRequest) FreeTimeRequest(org.cpsolver.studentsct.model.FreeTimeRequest) Student(org.cpsolver.studentsct.model.Student) OnlineSectioningSelection(org.cpsolver.studentsct.online.selection.OnlineSectioningSelection) Section(org.cpsolver.studentsct.model.Section) Offering(org.cpsolver.studentsct.model.Offering) TimeOverlapsCounter(org.cpsolver.studentsct.extension.TimeOverlapsCounter) CourseRequest(org.cpsolver.studentsct.model.CourseRequest) AssignmentMap(org.cpsolver.ifs.assignment.AssignmentMap) BranchBoundNeighbour(org.cpsolver.studentsct.heuristics.selection.BranchBoundSelection.BranchBoundNeighbour) Subpart(org.cpsolver.studentsct.model.Subpart) MultiCriteriaBranchAndBoundSuggestions(org.cpsolver.studentsct.online.selection.MultiCriteriaBranchAndBoundSuggestions)

Example 12 with CourseRequest

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;
}
Also used : CourseRequest(org.cpsolver.studentsct.model.CourseRequest) CourseRequest(org.cpsolver.studentsct.model.CourseRequest) Request(org.cpsolver.studentsct.model.Request)

Example 13 with CourseRequest

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);
}
Also used : CourseRequest(org.cpsolver.studentsct.model.CourseRequest) Config(org.cpsolver.studentsct.model.Config) CourseRequest(org.cpsolver.studentsct.model.CourseRequest) Request(org.cpsolver.studentsct.model.Request) Course(org.cpsolver.studentsct.model.Course) Section(org.cpsolver.studentsct.model.Section)

Example 14 with CourseRequest

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;
        }
    }
}
Also used : CourseRequest(org.cpsolver.studentsct.model.CourseRequest) CourseRequest(org.cpsolver.studentsct.model.CourseRequest) Request(org.cpsolver.studentsct.model.Request) Enrollment(org.cpsolver.studentsct.model.Enrollment) Constraint(org.cpsolver.ifs.model.Constraint)

Example 15 with CourseRequest

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());
}
Also used : CourseRequest(org.cpsolver.studentsct.model.CourseRequest) CourseRequest(org.cpsolver.studentsct.model.CourseRequest) Request(org.cpsolver.studentsct.model.Request) Enrollment(org.cpsolver.studentsct.model.Enrollment) Constraint(org.cpsolver.ifs.model.Constraint)

Aggregations

CourseRequest (org.cpsolver.studentsct.model.CourseRequest)67 Request (org.cpsolver.studentsct.model.Request)51 Enrollment (org.cpsolver.studentsct.model.Enrollment)37 Section (org.cpsolver.studentsct.model.Section)36 Course (org.cpsolver.studentsct.model.Course)26 FreeTimeRequest (org.cpsolver.studentsct.model.FreeTimeRequest)21 Subpart (org.cpsolver.studentsct.model.Subpart)21 ArrayList (java.util.ArrayList)20 HashSet (java.util.HashSet)18 Student (org.cpsolver.studentsct.model.Student)17 HashMap (java.util.HashMap)15 Config (org.cpsolver.studentsct.model.Config)13 Map (java.util.Map)11 Offering (org.cpsolver.studentsct.model.Offering)10 CSVFile (org.cpsolver.ifs.util.CSVFile)9 Set (java.util.Set)8 DistanceConflict (org.cpsolver.studentsct.extension.DistanceConflict)7 TreeSet (java.util.TreeSet)6 Constraint (org.cpsolver.ifs.model.Constraint)6 StudentQuality (org.cpsolver.studentsct.extension.StudentQuality)6