Search in sources :

Example 11 with Reservation

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

the class Section method getTotalUnreservedSpaceNoCache.

private double getTotalUnreservedSpaceNoCache() {
    // (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;
    }
    // we need to check all reservations linked with this section
    double available = getLimit(), reserved = 0, exclusive = 0;
    Set<Section> sections = new HashSet<Section>();
    reservations: for (Reservation r : getSectionReservations()) {
        // ignore expired reservations
        if (r.isExpired())
            continue;
        // unlimited reservation -> no unreserved space
        if (r.getLimit() < 0)
            return 0.0;
        for (Section s : r.getSections(getSubpart())) {
            if (s.equals(this))
                continue;
            if (s.getLimit() < 0)
                continue reservations;
            if (sections.add(s))
                available += s.getLimit();
        }
        reserved += r.getLimit();
        if (r.getSections(getSubpart()).size() == 1)
            exclusive += r.getLimit();
    }
    return Math.min(available - reserved, getLimit() - exclusive);
}
Also used : Reservation(org.cpsolver.studentsct.reservation.Reservation) HashSet(java.util.HashSet)

Example 12 with Reservation

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

the class StudentSectioningXMLLoader method loadEnrollment.

/**
     * Load enrollment
     * @param enrollmentEl enrollment element (current, best, or initial)
     * @param request parent request
     * @return loaded enrollment
     */
protected Enrollment loadEnrollment(Element enrollmentEl, Request request) {
    if (request instanceof CourseRequest) {
        CourseRequest courseRequest = (CourseRequest) request;
        HashSet<Section> sections = new HashSet<Section>();
        for (Iterator<?> k = enrollmentEl.elementIterator("section"); k.hasNext(); ) {
            Element sectionEl = (Element) k.next();
            Section section = courseRequest.getSection(Long.parseLong(sectionEl.attributeValue("id")));
            sections.add(section);
        }
        Reservation reservation = null;
        if (enrollmentEl.attributeValue("reservation", null) != null) {
            long reservationId = Long.valueOf(enrollmentEl.attributeValue("reservation"));
            for (Course course : courseRequest.getCourses()) for (Reservation r : course.getOffering().getReservations()) if (r.getId() == reservationId) {
                reservation = r;
                break;
            }
        }
        if (!sections.isEmpty())
            return courseRequest.createEnrollment(sections, reservation);
    } else if (request instanceof FreeTimeRequest) {
        return ((FreeTimeRequest) request).createEnrollment();
    }
    return null;
}
Also used : FreeTimeRequest(org.cpsolver.studentsct.model.FreeTimeRequest) 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) CourseRequest(org.cpsolver.studentsct.model.CourseRequest) Element(org.dom4j.Element) Course(org.cpsolver.studentsct.model.Course) Section(org.cpsolver.studentsct.model.Section) HashSet(java.util.HashSet)

Example 13 with Reservation

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

the class RequiredReservation method inConflict.

/**
     * A given enrollment is conflicting, if there is a reservation that
     * the student must use, but the given enrollment does not use it.
     * 
     * @param enrollment {@link Enrollment} that is being considered
     * @return true, if the enrollment does not follow a reservation that must be used 
     */
@Override
public boolean inConflict(Assignment<Request, Enrollment> assignment, Enrollment enrollment) {
    // enrollment's config
    Config config = enrollment.getConfig();
    // exclude free time requests
    if (config == null)
        return false;
    // no reservations
    if (!config.getOffering().hasReservations())
        return false;
    // enrollment's reservation
    Reservation reservation = enrollment.getReservation();
    // already has a reservation that must be used
    if (reservation != null && reservation.mustBeUsed())
        return false;
    // if a reservation is required for the student, fail
    for (Reservation r : config.getOffering().getReservations()) if (r.mustBeUsed() && r.isApplicable(enrollment.getStudent()))
        return true;
    return false;
}
Also used : Reservation(org.cpsolver.studentsct.reservation.Reservation) Config(org.cpsolver.studentsct.model.Config)

Example 14 with Reservation

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

the class Test method clone.

protected Course clone(Course course, long studentId, Student originalStudent, Map<Long, Section> classTable, StudentSectioningModel model) {
    Offering clonedOffering = new Offering(course.getOffering().getId(), course.getOffering().getName());
    clonedOffering.setModel(model);
    int courseLimit = course.getLimit();
    if (courseLimit >= 0) {
        courseLimit -= course.getEnrollments(assignment()).size();
        if (courseLimit < 0)
            courseLimit = 0;
        for (Iterator<Enrollment> i = course.getEnrollments(assignment()).iterator(); i.hasNext(); ) {
            Enrollment enrollment = i.next();
            if (enrollment.getStudent().getId() == studentId) {
                courseLimit++;
                break;
            }
        }
    }
    Course clonedCourse = new Course(course.getId(), course.getSubjectArea(), course.getCourseNumber(), clonedOffering, courseLimit, course.getProjected());
    clonedCourse.setNote(course.getNote());
    Hashtable<Config, Config> configs = new Hashtable<Config, Config>();
    Hashtable<Subpart, Subpart> subparts = new Hashtable<Subpart, Subpart>();
    Hashtable<Section, Section> sections = new Hashtable<Section, Section>();
    for (Iterator<Config> e = course.getOffering().getConfigs().iterator(); e.hasNext(); ) {
        Config config = e.next();
        int configLimit = config.getLimit();
        int configEnrollment = config.getEnrollments(assignment()).size();
        if (configLimit >= 0) {
            configLimit -= config.getEnrollments(assignment()).size();
            if (configLimit < 0)
                configLimit = 0;
            for (Iterator<Enrollment> i = config.getEnrollments(assignment()).iterator(); i.hasNext(); ) {
                Enrollment enrollment = i.next();
                if (enrollment.getStudent().getId() == studentId) {
                    configLimit++;
                    configEnrollment--;
                    break;
                }
            }
        }
        OnlineConfig clonedConfig = new OnlineConfig(config.getId(), configLimit, config.getName(), clonedOffering);
        clonedConfig.setInstructionalMethodId(config.getInstructionalMethodId());
        clonedConfig.setInstructionalMethodName(config.getInstructionalMethodName());
        clonedConfig.setEnrollment(configEnrollment);
        configs.put(config, clonedConfig);
        for (Iterator<Subpart> f = config.getSubparts().iterator(); f.hasNext(); ) {
            Subpart subpart = f.next();
            Subpart clonedSubpart = new Subpart(subpart.getId(), subpart.getInstructionalType(), subpart.getName(), clonedConfig, (subpart.getParent() == null ? null : subparts.get(subpart.getParent())));
            clonedSubpart.setAllowOverlap(subpart.isAllowOverlap());
            clonedSubpart.setCredit(subpart.getCredit());
            subparts.put(subpart, clonedSubpart);
            for (Iterator<Section> g = subpart.getSections().iterator(); g.hasNext(); ) {
                Section section = g.next();
                int limit = section.getLimit();
                int enrl = section.getEnrollments(assignment()).size();
                if (limit >= 0) {
                    // limited section, deduct enrollments
                    limit -= section.getEnrollments(assignment()).size();
                    if (limit < 0)
                        // over-enrolled, but not unlimited
                        limit = 0;
                    if (studentId >= 0)
                        for (Enrollment enrollment : section.getEnrollments(assignment())) if (enrollment.getStudent().getId() == studentId) {
                            limit++;
                            enrl--;
                            break;
                        }
                }
                OnlineSection clonedSection = new OnlineSection(section.getId(), limit, section.getName(course.getId()), clonedSubpart, section.getPlacement(), section.getInstructors(), (section.getParent() == null ? null : sections.get(section.getParent())));
                clonedSection.setName(-1l, section.getName(-1l));
                clonedSection.setNote(section.getNote());
                clonedSection.setSpaceExpected(section.getSpaceExpected());
                clonedSection.setSpaceHeld(section.getSpaceHeld());
                clonedSection.setEnrollment(enrl);
                clonedSection.setCancelled(section.isCancelled());
                if (section.getIgnoreConflictWithSectionIds() != null)
                    for (Long id : section.getIgnoreConflictWithSectionIds()) clonedSection.addIgnoreConflictWith(id);
                if (limit > 0) {
                    double available = Math.round(section.getSpaceExpected() - limit);
                    clonedSection.setPenalty(available / section.getLimit());
                }
                sections.put(section, clonedSection);
                classTable.put(section.getId(), clonedSection);
            }
        }
    }
    if (course.getOffering().hasReservations()) {
        for (Reservation reservation : course.getOffering().getReservations()) {
            int reservationLimit = (int) Math.round(reservation.getLimit());
            if (reservationLimit >= 0) {
                reservationLimit -= reservation.getEnrollments(assignment()).size();
                if (reservationLimit < 0)
                    reservationLimit = 0;
                for (Iterator<Enrollment> i = reservation.getEnrollments(assignment()).iterator(); i.hasNext(); ) {
                    Enrollment enrollment = i.next();
                    if (enrollment.getStudent().getId() == studentId) {
                        reservationLimit++;
                        break;
                    }
                }
                if (reservationLimit <= 0 && !reservation.mustBeUsed())
                    continue;
            }
            boolean applicable = originalStudent != null && reservation.isApplicable(originalStudent);
            if (reservation instanceof CourseReservation)
                applicable = (course.getId() == ((CourseReservation) reservation).getCourse().getId());
            if (reservation instanceof org.cpsolver.studentsct.reservation.DummyReservation) {
                // the student is already enrolled in the course
                for (Enrollment enrollment : course.getEnrollments(assignment())) if (enrollment.getStudent().getId() == studentId) {
                    applicable = true;
                    break;
                }
            }
            Reservation clonedReservation = new OnlineReservation(0, reservation.getId(), clonedOffering, reservation.getPriority(), reservation.canAssignOverLimit(), reservationLimit, applicable, reservation.mustBeUsed(), reservation.isAllowOverlap(), reservation.isExpired());
            for (Config config : reservation.getConfigs()) clonedReservation.addConfig(configs.get(config));
            for (Map.Entry<Subpart, Set<Section>> entry : reservation.getSections().entrySet()) {
                Set<Section> clonedSections = new HashSet<Section>();
                for (Section section : entry.getValue()) clonedSections.add(sections.get(section));
                clonedReservation.getSections().put(subparts.get(entry.getKey()), clonedSections);
            }
        }
    }
    return clonedCourse;
}
Also used : Set(java.util.Set) TreeSet(java.util.TreeSet) HashSet(java.util.HashSet) Config(org.cpsolver.studentsct.model.Config) CourseReservation(org.cpsolver.studentsct.reservation.CourseReservation) Reservation(org.cpsolver.studentsct.reservation.Reservation) Enrollment(org.cpsolver.studentsct.model.Enrollment) Course(org.cpsolver.studentsct.model.Course) HashSet(java.util.HashSet) CourseReservation(org.cpsolver.studentsct.reservation.CourseReservation) Hashtable(java.util.Hashtable) Offering(org.cpsolver.studentsct.model.Offering) Section(org.cpsolver.studentsct.model.Section) Subpart(org.cpsolver.studentsct.model.Subpart) Map(java.util.Map) HashMap(java.util.HashMap) AssignmentMap(org.cpsolver.ifs.assignment.AssignmentMap)

Example 15 with Reservation

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

the class ReservationLimit method computeConflicts.

/**
     * A given enrollment is conflicting, if the reservation's remaining available space
     * (computed by {@link Reservation#getReservedAvailableSpace(Assignment, Request)})
     * is below the requests weight {@link Request#getWeight()}. <br>
     * If the limit is breached, one or more existing enrollments are
     * selected as conflicting until there is enough space in the reservation.
     * Similarly, if the enrollment does not have the reservation, it is checked
     * that there is enough unreserved space in the desired configuration.
     * 
     * @param enrollment
     *            {@link Enrollment} that is being considered
     * @param conflicts
     *            all computed conflicting requests are added into this set
     */
@Override
public void computeConflicts(Assignment<Request, Enrollment> assignment, Enrollment enrollment, Set<Enrollment> conflicts) {
    // enrollment's config
    Config config = enrollment.getConfig();
    // exclude free time requests
    if (config == null)
        return;
    // no reservations
    if (!config.getOffering().hasReservations())
        return;
    // enrollment's reservation
    Reservation reservation = enrollment.getReservation();
    // check space in the reservation reservation
    if (reservation != null) {
        // check reservation too
        double reserved = reservation.getReservedAvailableSpace(assignment, enrollment.getRequest());
        if (reservation.getLimit() >= 0 && reserved < enrollment.getRequest().getWeight()) {
            // reservation is not unlimited and there is not enough space in it
            // try to free some space in the reservation
            List<Enrollment> adepts = new ArrayList<Enrollment>(config.getEnrollments(assignment).size());
            for (Enrollment e : config.getEnrollments(assignment)) {
                if (e.getRequest().equals(enrollment.getRequest()))
                    continue;
                if (!reservation.equals(e.getReservation()))
                    continue;
                if (conflicts.contains(e))
                    reserved += e.getRequest().getWeight();
                else
                    adepts.add(e);
            }
            while (reserved < enrollment.getRequest().getWeight()) {
                if (adepts.isEmpty()) {
                    // no adepts -> enrollment cannot be assigned
                    conflicts.add(enrollment);
                    return;
                }
                // pick adept (prefer dummy students), decrease unreserved space,
                // make conflict
                List<Enrollment> best = new ArrayList<Enrollment>();
                boolean bestDummy = false;
                double bestValue = 0;
                for (Enrollment adept : adepts) {
                    boolean dummy = adept.getStudent().isDummy();
                    double value = adept.toDouble(assignment, false);
                    if (iPreferDummyStudents && dummy != bestDummy) {
                        if (dummy) {
                            best.clear();
                            best.add(adept);
                            bestDummy = dummy;
                            bestValue = value;
                        }
                        continue;
                    }
                    if (best.isEmpty() || value > bestValue) {
                        if (best.isEmpty())
                            best.clear();
                        best.add(adept);
                        bestDummy = dummy;
                        bestValue = value;
                    } else if (bestValue == value) {
                        best.add(adept);
                    }
                }
                Enrollment conflict = ToolBox.random(best);
                adepts.remove(conflict);
                reserved += conflict.getRequest().getWeight();
                conflicts.add(conflict);
            }
        }
        // if not configuration reservation -> check configuration unavailable space
        if (!hasConfigReservation(enrollment)) {
            // check reservation can assign over the limit
            if (reservation.canBatchAssignOverLimit())
                return;
            // the section for an enrollment w/o configuration reservation
            if (config.getTotalUnreservedSpace() < enrollment.getRequest().getWeight()) {
                conflicts.add(enrollment);
                return;
            }
            double unreserved = getUnreservedSpace(assignment, config, enrollment.getRequest(), true);
            if (unreserved < 0.0) {
                // no unreserved space available -> cannot be assigned
                // try to unassign some other enrollments that also do not have config reservation
                List<Enrollment> adepts = new ArrayList<Enrollment>(config.getEnrollments(assignment).size());
                for (Enrollment e : config.getEnrollments(assignment)) {
                    if (e.getRequest().equals(enrollment.getRequest()))
                        continue;
                    if (hasConfigReservation(e))
                        continue;
                    if (conflicts.contains(e))
                        unreserved += e.getRequest().getWeight();
                    else
                        adepts.add(e);
                }
                while (unreserved < 0.0) {
                    if (adepts.isEmpty()) {
                        // no adepts -> enrollment cannot be assigned
                        conflicts.add(enrollment);
                        return;
                    }
                    // pick adept (prefer dummy students), decrease unreserved space,
                    // make conflict
                    List<Enrollment> best = new ArrayList<Enrollment>();
                    boolean bestDummy = false;
                    double bestValue = 0;
                    for (Enrollment adept : adepts) {
                        boolean dummy = adept.getStudent().isDummy();
                        double value = adept.toDouble(assignment, false);
                        if (iPreferDummyStudents && dummy != bestDummy) {
                            if (dummy) {
                                best.clear();
                                best.add(adept);
                                bestDummy = dummy;
                                bestValue = value;
                            }
                            continue;
                        }
                        if (best.isEmpty() || value > bestValue) {
                            if (best.isEmpty())
                                best.clear();
                            best.add(adept);
                            bestDummy = dummy;
                            bestValue = value;
                        } else if (bestValue == value) {
                            best.add(adept);
                        }
                    }
                    Enrollment conflict = ToolBox.random(best);
                    adepts.remove(conflict);
                    unreserved += conflict.getRequest().getWeight();
                    conflicts.add(conflict);
                }
            }
        }
    } else {
        // the section for an enrollment w/o reservation
        if (config.getOffering().getTotalUnreservedSpace() < enrollment.getRequest().getWeight() || config.getTotalUnreservedSpace() < enrollment.getRequest().getWeight()) {
            conflicts.add(enrollment);
            return;
        }
        // check configuration unavailable space too
        double unreserved = getUnreservedSpace(assignment, config, enrollment.getRequest(), false);
        if (unreserved < 0.0) {
            // no unreserved space available -> cannot be assigned
            // try to unassign some other enrollments that also do not have reservation
            List<Enrollment> adepts = new ArrayList<Enrollment>(config.getEnrollments(assignment).size());
            for (Enrollment e : config.getEnrollments(assignment)) {
                if (e.getRequest().equals(enrollment.getRequest()))
                    continue;
                if (e.getReservation() != null)
                    continue;
                if (conflicts.contains(e))
                    unreserved += e.getRequest().getWeight();
                else
                    adepts.add(e);
            }
            while (unreserved < 0.0) {
                if (adepts.isEmpty()) {
                    // no adepts -> enrollment cannot be assigned
                    conflicts.add(enrollment);
                    return;
                }
                // pick adept (prefer dummy students), decrease unreserved space,
                // make conflict
                List<Enrollment> best = new ArrayList<Enrollment>();
                boolean bestDummy = false;
                double bestValue = 0;
                for (Enrollment adept : adepts) {
                    boolean dummy = adept.getStudent().isDummy();
                    double value = adept.toDouble(assignment, false);
                    if (iPreferDummyStudents && dummy != bestDummy) {
                        if (dummy) {
                            best.clear();
                            best.add(adept);
                            bestDummy = dummy;
                            bestValue = value;
                        }
                        continue;
                    }
                    if (best.isEmpty() || value > bestValue) {
                        if (best.isEmpty())
                            best.clear();
                        best.add(adept);
                        bestDummy = dummy;
                        bestValue = value;
                    } else if (bestValue == value) {
                        best.add(adept);
                    }
                }
                Enrollment conflict = ToolBox.random(best);
                adepts.remove(conflict);
                unreserved += conflict.getRequest().getWeight();
                conflicts.add(conflict);
            }
        }
    }
}
Also used : Reservation(org.cpsolver.studentsct.reservation.Reservation) Config(org.cpsolver.studentsct.model.Config) ArrayList(java.util.ArrayList) Enrollment(org.cpsolver.studentsct.model.Enrollment)

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