Search in sources :

Example 1 with Reservation

use of org.cpsolver.studentsct.reservation.Reservation in project cpsolver by UniTime.

the class StudentSectioningXMLLoader method loadReservation.

/**
     * Load reservation
     * @param reservationEl reservation element
     * @param offering parent offering
     * @param configTable config table (of the offering)
     * @param sectionTable section table (of the offering)
     * @return loaded reservation
     */
protected Reservation loadReservation(Element reservationEl, Offering offering, HashMap<Long, Config> configTable, HashMap<Long, Section> sectionTable) {
    Reservation r = null;
    if ("individual".equals(reservationEl.attributeValue("type"))) {
        Set<Long> studentIds = new HashSet<Long>();
        for (Iterator<?> k = reservationEl.elementIterator("student"); k.hasNext(); ) {
            Element studentEl = (Element) k.next();
            studentIds.add(Long.parseLong(studentEl.attributeValue("id")));
        }
        r = new IndividualReservation(Long.valueOf(reservationEl.attributeValue("id")), offering, studentIds);
    } else if ("group".equals(reservationEl.attributeValue("type"))) {
        Set<Long> studentIds = new HashSet<Long>();
        for (Iterator<?> k = reservationEl.elementIterator("student"); k.hasNext(); ) {
            Element studentEl = (Element) k.next();
            studentIds.add(Long.parseLong(studentEl.attributeValue("id")));
        }
        r = new GroupReservation(Long.valueOf(reservationEl.attributeValue("id")), Double.parseDouble(reservationEl.attributeValue("limit", "-1")), offering, studentIds);
    } else if ("curriculum".equals(reservationEl.attributeValue("type"))) {
        List<String> classifications = new ArrayList<String>();
        for (Iterator<?> k = reservationEl.elementIterator("classification"); k.hasNext(); ) {
            Element clasfEl = (Element) k.next();
            classifications.add(clasfEl.attributeValue("code"));
        }
        List<String> majors = new ArrayList<String>();
        for (Iterator<?> k = reservationEl.elementIterator("major"); k.hasNext(); ) {
            Element majorEl = (Element) k.next();
            majors.add(majorEl.attributeValue("code"));
        }
        r = new CurriculumReservation(Long.valueOf(reservationEl.attributeValue("id")), Double.parseDouble(reservationEl.attributeValue("limit", "-1")), offering, reservationEl.attributeValue("area"), classifications, majors);
    } else if ("course".equals(reservationEl.attributeValue("type"))) {
        long courseId = Long.parseLong(reservationEl.attributeValue("course"));
        for (Course course : offering.getCourses()) {
            if (course.getId() == courseId)
                r = new CourseReservation(Long.valueOf(reservationEl.attributeValue("id")), course);
        }
    } else if ("dummy".equals(reservationEl.attributeValue("type"))) {
        r = new DummyReservation(offering);
    } else if ("override".equals(reservationEl.attributeValue("type"))) {
        Set<Long> studentIds = new HashSet<Long>();
        for (Iterator<?> k = reservationEl.elementIterator("student"); k.hasNext(); ) {
            Element studentEl = (Element) k.next();
            studentIds.add(Long.parseLong(studentEl.attributeValue("id")));
        }
        r = new ReservationOverride(Long.valueOf(reservationEl.attributeValue("id")), offering, studentIds);
    }
    if (r == null) {
        sLogger.error("Unknown reservation type " + reservationEl.attributeValue("type"));
        return null;
    }
    r.setExpired("true".equals(reservationEl.attributeValue("expired", "false")));
    for (Iterator<?> k = reservationEl.elementIterator("config"); k.hasNext(); ) {
        Element configEl = (Element) k.next();
        r.addConfig(configTable.get(Long.parseLong(configEl.attributeValue("id"))));
    }
    for (Iterator<?> k = reservationEl.elementIterator("section"); k.hasNext(); ) {
        Element sectionEl = (Element) k.next();
        r.addSection(sectionTable.get(Long.parseLong(sectionEl.attributeValue("id"))));
    }
    r.setPriority(Integer.parseInt(reservationEl.attributeValue("priority", String.valueOf(r.getPriority()))));
    r.setMustBeUsed("true".equals(reservationEl.attributeValue("mustBeUsed", r.mustBeUsed() ? "true" : "false")));
    r.setAllowOverlap("true".equals(reservationEl.attributeValue("allowOverlap", r.isAllowOverlap() ? "true" : "false")));
    r.setCanAssignOverLimit("true".equals(reservationEl.attributeValue("canAssignOverLimit", r.canAssignOverLimit() ? "true" : "false")));
    return r;
}
Also used : GroupReservation(org.cpsolver.studentsct.reservation.GroupReservation) CourseReservation(org.cpsolver.studentsct.reservation.CourseReservation) HashSet(java.util.HashSet) Set(java.util.Set) BitSet(java.util.BitSet) IndividualReservation(org.cpsolver.studentsct.reservation.IndividualReservation) Element(org.dom4j.Element) ArrayList(java.util.ArrayList) DummyReservation(org.cpsolver.studentsct.reservation.DummyReservation) IndividualReservation(org.cpsolver.studentsct.reservation.IndividualReservation) GroupReservation(org.cpsolver.studentsct.reservation.GroupReservation) CourseReservation(org.cpsolver.studentsct.reservation.CourseReservation) Reservation(org.cpsolver.studentsct.reservation.Reservation) DummyReservation(org.cpsolver.studentsct.reservation.DummyReservation) CurriculumReservation(org.cpsolver.studentsct.reservation.CurriculumReservation) CurriculumReservation(org.cpsolver.studentsct.reservation.CurriculumReservation) ReservationOverride(org.cpsolver.studentsct.reservation.ReservationOverride) Iterator(java.util.Iterator) Course(org.cpsolver.studentsct.model.Course) HashSet(java.util.HashSet)

Example 2 with Reservation

use of org.cpsolver.studentsct.reservation.Reservation in project cpsolver by UniTime.

the class SectionLimit method hasSectionReservation.

/**
     * True if the enrollment has reservation for this section.
     * Everything else is checked in the {@link ReservationLimit} constraint.
     **/
private boolean hasSectionReservation(Enrollment enrollment, Section section) {
    Reservation reservation = enrollment.getReservation();
    if (reservation == null)
        return false;
    Set<Section> sections = reservation.getSections(section.getSubpart());
    return sections != null && sections.contains(section);
}
Also used : Reservation(org.cpsolver.studentsct.reservation.Reservation) Section(org.cpsolver.studentsct.model.Section)

Example 3 with Reservation

use of org.cpsolver.studentsct.reservation.Reservation in project cpsolver by UniTime.

the class Offering method getTotalUnreservedSpaceNoCache.

private double getTotalUnreservedSpaceNoCache() {
    // compute overall available space
    double available = 0.0;
    for (Config config : getConfigs()) {
        available += config.getLimit();
        // (in which case there is no unreserved space)
        if (config.getLimit() < 0) {
            for (Reservation r : getReservations()) {
                // ignore expired reservations
                if (r.isExpired())
                    continue;
                // there is an unlimited reservation -> no unreserved space
                if (r.getLimit() < 0)
                    return 0.0;
            }
            return Double.MAX_VALUE;
        }
    }
    // compute maximal reserved space (out of the available space)
    double reserved = 0;
    for (Reservation r : getReservations()) {
        // ignore expired reservations
        if (r.isExpired())
            continue;
        // unlimited reservation -> no unreserved space
        if (r.getLimit() < 0)
            return 0.0;
        reserved += r.getLimit();
    }
    return Math.max(0.0, available - reserved);
}
Also used : Reservation(org.cpsolver.studentsct.reservation.Reservation)

Example 4 with Reservation

use of org.cpsolver.studentsct.reservation.Reservation in project cpsolver by UniTime.

the class Section method getUnreservedSpace.

/**
     * Available space in the section that is not reserved by any section reservation
     * @param assignment current assignment
     * @param excludeRequest excluding given request (if not null)
     * @return unreserved space in this class
     **/
public double getUnreservedSpace(Assignment<Request, Enrollment> assignment, Request excludeRequest) {
    // (in which case there is no unreserved space)
    if (getLimit() < 0) {
        // exclude reservations that are not directly set on this section
        for (Reservation r : getSectionReservations()) {
            // ignore expired reservations
            if (r.isExpired())
                continue;
            // there is an unlimited reservation -> no unreserved space
            if (r.getLimit() < 0)
                return 0.0;
        }
        return Double.MAX_VALUE;
    }
    double available = getLimit() - getContext(assignment).getEnrollmentWeight(assignment, excludeRequest);
    // exclude reservations that are not directly set on this section
    for (Reservation r : getSectionReservations()) {
        // ignore expired reservations
        if (r.isExpired())
            continue;
        // unlimited reservation -> all the space is reserved
        if (r.getLimit() < 0.0)
            return 0.0;
        // compute space that can be potentially taken by this reservation
        double reserved = r.getContext(assignment).getReservedAvailableSpace(assignment, excludeRequest);
        // deduct the space from available space
        available -= Math.max(0.0, reserved);
    }
    return available;
}
Also used : Reservation(org.cpsolver.studentsct.reservation.Reservation)

Example 5 with Reservation

use of org.cpsolver.studentsct.reservation.Reservation 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)

Aggregations

Reservation (org.cpsolver.studentsct.reservation.Reservation)17 HashSet (java.util.HashSet)7 Config (org.cpsolver.studentsct.model.Config)5 ArrayList (java.util.ArrayList)4 Course (org.cpsolver.studentsct.model.Course)4 Section (org.cpsolver.studentsct.model.Section)4 CourseReservation (org.cpsolver.studentsct.reservation.CourseReservation)4 HashMap (java.util.HashMap)3 Set (java.util.Set)3 Enrollment (org.cpsolver.studentsct.model.Enrollment)3 Hashtable (java.util.Hashtable)2 TreeSet (java.util.TreeSet)2 AssignmentMap (org.cpsolver.ifs.assignment.AssignmentMap)2 CourseRequest (org.cpsolver.studentsct.model.CourseRequest)2 FreeTimeRequest (org.cpsolver.studentsct.model.FreeTimeRequest)2 Offering (org.cpsolver.studentsct.model.Offering)2 Subpart (org.cpsolver.studentsct.model.Subpart)2 CurriculumReservation (org.cpsolver.studentsct.reservation.CurriculumReservation)2 DummyReservation (org.cpsolver.studentsct.reservation.DummyReservation)2 GroupReservation (org.cpsolver.studentsct.reservation.GroupReservation)2