Search in sources :

Example 6 with Reservation

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

the class CourseRequest method getReservations.

/**
     * Get reservations for this course requests
     * @param course given course
     * @return reservations for this course requests and the given course
     */
public synchronized List<Reservation> getReservations(Course course) {
    if (iReservations == null)
        iReservations = new HashMap<Course, List<Reservation>>();
    List<Reservation> reservations = iReservations.get(course);
    if (reservations == null) {
        reservations = new ArrayList<Reservation>();
        boolean mustBeUsed = false;
        for (Reservation r : course.getOffering().getReservations()) {
            if (!r.isApplicable(getStudent()))
                continue;
            if (!mustBeUsed && r.mustBeUsed()) {
                reservations.clear();
                mustBeUsed = true;
            }
            if (mustBeUsed && !r.mustBeUsed())
                continue;
            reservations.add(r);
        }
        iReservations.put(course, reservations);
    }
    return reservations;
}
Also used : Reservation(org.cpsolver.studentsct.reservation.Reservation) HashMap(java.util.HashMap)

Example 7 with Reservation

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

the class CourseRequest method computeEnrollments.

/**
     * Recursive computation of enrollments
     * 
     * @param enrollments
     *            list of enrollments to be returned
     * @param priority
     *            zero for the course, one for the first alternative, two for the second alternative
     * @param penalty
     *            penalty of the selected sections
     * @param course
     *            selected course
     * @param config
     *            selected configuration
     * @param sections
     *            sections selected so far
     * @param idx
     *            index of the subparts (a section of 0..idx-1 subparts has been
     *            already selected)
     * @param availableOnly
     *            only use available sections
     * @param skipSameTime
     *            for each possible times, pick only one section
     * @param selectedOnly
     *            select only sections that are selected (
     *            {@link CourseRequest#isSelected(Section)} is true)
     * @param random
     *            pick sections in a random order (useful when limit is used)
     * @param limit
     *            when above zero, limit the number of selected enrollments to
     *            this limit
     * @param reservations
     *            list of applicable reservations
     */
private void computeEnrollments(Assignment<Request, Enrollment> assignment, Collection<Enrollment> enrollments, int priority, double penalty, Course course, Config config, HashSet<Section> sections, int idx, boolean availableOnly, boolean skipSameTime, boolean selectedOnly, boolean random, int limit) {
    if (limit > 0 && enrollments.size() >= limit)
        return;
    if (idx == 0) {
        // run only once for each configuration
        boolean canOverLimit = false;
        if (availableOnly) {
            for (Reservation r : getReservations(course)) {
                if (!r.canBatchAssignOverLimit())
                    continue;
                if (!r.getConfigs().isEmpty() && !r.getConfigs().contains(config))
                    continue;
                if (r.getReservedAvailableSpace(assignment, this) < getWeight())
                    continue;
                canOverLimit = true;
                break;
            }
        }
        if (!canOverLimit) {
            if (availableOnly && config.getLimit() >= 0 && ConfigLimit.getEnrollmentWeight(assignment, config, this) > config.getLimit())
                return;
            if (availableOnly && course.getLimit() >= 0 && CourseLimit.getEnrollmentWeight(assignment, course, this) > course.getLimit())
                return;
            if (config.getOffering().hasReservations()) {
                boolean hasReservation = false, hasConfigReservation = false, reservationMustBeUsed = false;
                for (Reservation r : getReservations(course)) {
                    if (r.mustBeUsed())
                        reservationMustBeUsed = true;
                    if (availableOnly && r.getReservedAvailableSpace(assignment, this) < getWeight())
                        continue;
                    if (r.getConfigs().isEmpty()) {
                        hasReservation = true;
                    } else if (r.getConfigs().contains(config)) {
                        hasReservation = true;
                        hasConfigReservation = true;
                    }
                }
                if (!hasConfigReservation && config.getTotalUnreservedSpace() < getWeight())
                    return;
                if (!hasReservation && config.getOffering().getTotalUnreservedSpace() < getWeight())
                    return;
                if (availableOnly && !hasReservation && config.getOffering().getUnreservedSpace(assignment, this) < getWeight())
                    return;
                if (availableOnly && !hasConfigReservation && config.getUnreservedSpace(assignment, this) < getWeight())
                    return;
                if (!hasReservation && reservationMustBeUsed)
                    return;
            }
        }
    }
    if (config.getSubparts().size() == idx) {
        if (skipSameTime && sSameTimePrecise) {
            boolean waitListedOrSelected = false;
            if (!getSelectedChoices().isEmpty() || !getWaitlistedChoices().isEmpty()) {
                for (Section section : sections) {
                    if (isWaitlisted(section) || isSelected(section)) {
                        waitListedOrSelected = true;
                        break;
                    }
                }
            }
            if (!waitListedOrSelected) {
                for (Enrollment enrollment : enrollments) {
                    if (sameTimes(enrollment.getSections(), sections))
                        return;
                }
            }
        }
        if (!config.getOffering().hasReservations()) {
            enrollments.add(new Enrollment(this, priority, null, config, new HashSet<SctAssignment>(sections), null));
        } else {
            Enrollment e = new Enrollment(this, priority, null, config, new HashSet<SctAssignment>(sections), null);
            boolean mustHaveReservation = config.getOffering().getTotalUnreservedSpace() < getWeight();
            boolean mustHaveConfigReservation = config.getTotalUnreservedSpace() < getWeight();
            boolean mustHaveSectionReservation = false;
            for (Section s : sections) {
                if (s.getTotalUnreservedSpace() < getWeight()) {
                    mustHaveSectionReservation = true;
                    break;
                }
            }
            boolean canOverLimit = false;
            if (availableOnly) {
                for (Reservation r : getReservations(course)) {
                    if (!r.canBatchAssignOverLimit() || !r.isIncluded(e))
                        continue;
                    if (r.getReservedAvailableSpace(assignment, this) < getWeight())
                        continue;
                    enrollments.add(new Enrollment(this, priority, null, config, new HashSet<SctAssignment>(sections), r));
                    canOverLimit = true;
                }
            }
            if (!canOverLimit) {
                boolean reservationMustBeUsed = false;
                reservations: for (Reservation r : (availableOnly ? getSortedReservations(assignment, course) : getReservations(course))) {
                    if (r.mustBeUsed())
                        reservationMustBeUsed = true;
                    if (!r.isIncluded(e))
                        continue;
                    if (availableOnly && r.getReservedAvailableSpace(assignment, this) < getWeight())
                        continue;
                    if (mustHaveConfigReservation && r.getConfigs().isEmpty())
                        continue;
                    if (mustHaveSectionReservation)
                        for (Section s : sections) if (r.getSections(s.getSubpart()) == null && s.getTotalUnreservedSpace() < getWeight())
                            continue reservations;
                    enrollments.add(new Enrollment(this, priority, null, config, new HashSet<SctAssignment>(sections), r));
                    // only one available reservation suffice (the best matching one)
                    if (availableOnly)
                        return;
                }
                // a case w/o reservation
                if (!(mustHaveReservation || mustHaveConfigReservation || mustHaveSectionReservation) && !(availableOnly && config.getOffering().getUnreservedSpace(assignment, this) < getWeight()) && !reservationMustBeUsed) {
                    enrollments.add(new Enrollment(this, (getReservations(course).isEmpty() ? 0 : 1) + priority, null, config, new HashSet<SctAssignment>(sections), null));
                }
            }
        }
    } else {
        Subpart subpart = config.getSubparts().get(idx);
        HashSet<TimeLocation> times = (skipSameTime ? new HashSet<TimeLocation>() : null);
        List<Section> sectionsThisSubpart = subpart.getSections();
        if (skipSameTime) {
            sectionsThisSubpart = new ArrayList<Section>(subpart.getSections());
            Collections.sort(sectionsThisSubpart, new AssignmentComparator<Section, Request, Enrollment>(assignment));
        }
        List<Section> matchingSectionsThisSubpart = new ArrayList<Section>(subpart.getSections().size());
        boolean hasChildren = !subpart.getChildren().isEmpty();
        for (Section section : sectionsThisSubpart) {
            if (section.isCancelled())
                continue;
            if (getInitialAssignment() != null && (getModel() != null && ((StudentSectioningModel) getModel()).getKeepInitialAssignments()) && !getInitialAssignment().getAssignments().contains(section))
                continue;
            if (section.getParent() != null && !sections.contains(section.getParent()))
                continue;
            if (section.isOverlapping(sections))
                continue;
            if (selectedOnly && !isSelected(section))
                continue;
            if (!getStudent().isAvailable(section)) {
                boolean canOverlap = false;
                for (Reservation r : getReservations(course)) {
                    if (!r.isAllowOverlap())
                        continue;
                    if (r.getSections(subpart) != null && !r.getSections(subpart).contains(section))
                        continue;
                    if (r.getReservedAvailableSpace(assignment, this) < getWeight())
                        continue;
                    canOverlap = true;
                    break;
                }
                if (!canOverlap)
                    continue;
            }
            boolean canOverLimit = false;
            if (availableOnly) {
                for (Reservation r : getReservations(course)) {
                    if (!r.canBatchAssignOverLimit())
                        continue;
                    if (r.getSections(subpart) != null && !r.getSections(subpart).contains(section))
                        continue;
                    if (r.getReservedAvailableSpace(assignment, this) < getWeight())
                        continue;
                    canOverLimit = true;
                    break;
                }
            }
            if (!canOverLimit) {
                if (availableOnly && section.getLimit() >= 0 && SectionLimit.getEnrollmentWeight(assignment, section, this) > section.getLimit())
                    continue;
                if (config.getOffering().hasReservations()) {
                    boolean hasReservation = false, hasSectionReservation = false, reservationMustBeUsed = false;
                    for (Reservation r : getReservations(course)) {
                        if (r.mustBeUsed())
                            reservationMustBeUsed = true;
                        if (availableOnly && r.getReservedAvailableSpace(assignment, this) < getWeight())
                            continue;
                        if (r.getSections(subpart) == null) {
                            hasReservation = true;
                        } else if (r.getSections(subpart).contains(section)) {
                            hasReservation = true;
                            hasSectionReservation = true;
                        }
                    }
                    if (!hasSectionReservation && section.getTotalUnreservedSpace() < getWeight())
                        continue;
                    if (availableOnly && !hasSectionReservation && section.getUnreservedSpace(assignment, this) < getWeight())
                        continue;
                    if (!hasReservation && reservationMustBeUsed)
                        continue;
                }
            }
            if (skipSameTime && section.getTime() != null && !hasChildren && !times.add(section.getTime()) && !isSelected(section) && !isWaitlisted(section) && (section.getIgnoreConflictWithSectionIds() == null || section.getIgnoreConflictWithSectionIds().isEmpty()))
                continue;
            matchingSectionsThisSubpart.add(section);
        }
        if (random || limit > 0) {
            sectionsThisSubpart = new ArrayList<Section>(sectionsThisSubpart);
            Collections.shuffle(sectionsThisSubpart);
        }
        int i = 0;
        for (Section section : matchingSectionsThisSubpart) {
            sections.add(section);
            computeEnrollments(assignment, enrollments, priority, penalty + section.getPenalty(), course, config, sections, idx + 1, availableOnly, skipSameTime, selectedOnly, random, limit < 0 ? limit : Math.max(1, limit * (1 + i) / matchingSectionsThisSubpart.size()));
            sections.remove(section);
            i++;
        }
    }
}
Also used : TimeLocation(org.cpsolver.coursett.model.TimeLocation) ArrayList(java.util.ArrayList) Reservation(org.cpsolver.studentsct.reservation.Reservation) StudentSectioningModel(org.cpsolver.studentsct.StudentSectioningModel) HashSet(java.util.HashSet)

Example 8 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 9 with Reservation

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

the class Enrollment method guessReservation.

/**
     * Guess the reservation based on the enrollment
     * @param assignment current assignment
     * @param onlyAvailable use only reservation that have some space left in them
     */
public void guessReservation(Assignment<Request, Enrollment> assignment, boolean onlyAvailable) {
    if (iCourse != null) {
        Reservation best = null;
        for (Reservation reservation : ((CourseRequest) iRequest).getReservations(iCourse)) {
            if (reservation.isIncluded(this)) {
                if (onlyAvailable && reservation.getContext(assignment).getReservedAvailableSpace(assignment, iRequest) < iRequest.getWeight() && !reservation.canBatchAssignOverLimit())
                    continue;
                if (best == null || best.getPriority() > reservation.getPriority()) {
                    best = reservation;
                } else if (best.getPriority() == reservation.getPriority() && best.getContext(assignment).getReservedAvailableSpace(assignment, iRequest) < reservation.getContext(assignment).getReservedAvailableSpace(assignment, iRequest)) {
                    best = reservation;
                }
            }
        }
        iReservation = best;
    }
}
Also used : Reservation(org.cpsolver.studentsct.reservation.Reservation)

Example 10 with Reservation

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

the class Offering method getUnreservedSpace.

/**
     * Available space in the offering that is not reserved by any reservation 
     * @param assignment current request
     * @param excludeRequest excluding given request (if not null)
     * @return remaining unreserved space in the offering
     **/
public double getUnreservedSpace(Assignment<Request, Enrollment> assignment, Request excludeRequest) {
    // compute available space
    double available = 0.0;
    for (Config config : getConfigs()) {
        available += config.getLimit() - config.getContext(assignment).getEnrollmentWeight(assignment, excludeRequest);
        // (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 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 += Math.max(0.0, r.getContext(assignment).getReservedAvailableSpace(assignment, excludeRequest));
    }
    return available - reserved;
}
Also used : Reservation(org.cpsolver.studentsct.reservation.Reservation)

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