Search in sources :

Example 56 with Section

use of org.cpsolver.studentsct.model.Section in project cpsolver by UniTime.

the class Test method updateSpace.

public static void updateSpace(Assignment<Request, Enrollment> assignment, Enrollment enrollment, boolean increment) {
    if (enrollment == null || !enrollment.isCourseRequest())
        return;
    for (Section section : enrollment.getSections()) section.setSpaceHeld(section.getSpaceHeld() + (increment ? 1.0 : -1.0));
    List<Enrollment> feasibleEnrollments = new ArrayList<Enrollment>();
    int totalLimit = 0;
    for (Enrollment enrl : enrollment.getRequest().values(assignment)) {
        if (!enrl.getCourse().equals(enrollment.getCourse()))
            continue;
        boolean overlaps = false;
        for (Request otherRequest : enrollment.getRequest().getStudent().getRequests()) {
            if (otherRequest.equals(enrollment.getRequest()) || !(otherRequest instanceof CourseRequest))
                continue;
            Enrollment otherErollment = assignment.getValue(otherRequest);
            if (otherErollment == null)
                continue;
            if (enrl.isOverlapping(otherErollment)) {
                overlaps = true;
                break;
            }
        }
        if (!overlaps) {
            feasibleEnrollments.add(enrl);
            if (totalLimit >= 0) {
                int limit = enrl.getLimit();
                if (limit < 0)
                    totalLimit = -1;
                else
                    totalLimit += limit;
            }
        }
    }
    double change = enrollment.getRequest().getWeight() / (totalLimit > 0 ? totalLimit : feasibleEnrollments.size());
    for (Enrollment feasibleEnrollment : feasibleEnrollments) for (Section section : feasibleEnrollment.getSections()) {
        if (totalLimit > 0) {
            section.setSpaceExpected(section.getSpaceExpected() + (increment ? +change : -change) * feasibleEnrollment.getLimit());
        } else {
            section.setSpaceExpected(section.getSpaceExpected() + (increment ? +change : -change));
        }
    }
}
Also used : CourseRequest(org.cpsolver.studentsct.model.CourseRequest) ArrayList(java.util.ArrayList) Request(org.cpsolver.studentsct.model.Request) CourseRequest(org.cpsolver.studentsct.model.CourseRequest) FreeTimeRequest(org.cpsolver.studentsct.model.FreeTimeRequest) Enrollment(org.cpsolver.studentsct.model.Enrollment) Section(org.cpsolver.studentsct.model.Section)

Example 57 with Section

use of org.cpsolver.studentsct.model.Section 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 58 with Section

use of org.cpsolver.studentsct.model.Section in project cpsolver by UniTime.

the class SectionLimit method computeConflicts.

/**
     * A given enrollment is conflicting, if there is a section which limit
     * (computed by {@link SectionLimit#getEnrollmentWeight(Assignment, Section, Request)})
     * exceeds the section limit. <br>
     * For each of such sections, one or more existing enrollments are
     * (randomly) selected as conflicting until the overall weight is under the
     * limit.
     * 
     * @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) {
    // check reservation can assign over the limit
    if (enrollment.getReservation() != null && enrollment.getReservation().canBatchAssignOverLimit())
        return;
    // exclude free time requests
    if (!enrollment.isCourseRequest())
        return;
    // for each section
    for (Section section : enrollment.getSections()) {
        // no reservation -- check the space in the unreserved space in the section
        if (enrollment.getConfig().getOffering().hasReservations() && !hasSectionReservation(enrollment, section)) {
            // section is fully reserved by section reservations
            if (section.getTotalUnreservedSpace() < enrollment.getRequest().getWeight()) {
                conflicts.add(enrollment);
                return;
            }
            double unreserved = getUnreservedSpace(assignment, section, enrollment.getRequest());
            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>(section.getEnrollments(assignment).size());
                for (Enrollment e : section.getEnrollments(assignment)) {
                    if (e.getRequest().equals(enrollment.getRequest()))
                        continue;
                    if (e.getReservation() != null && e.getReservation().canBatchAssignOverLimit())
                        continue;
                    if (hasSectionReservation(e, section))
                        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);
                }
            }
        }
        // unlimited section
        if (section.getLimit() < 0)
            continue;
        // new enrollment weight
        double enrlWeight = getEnrollmentWeight(assignment, section, enrollment.getRequest());
        // below limit -> ok
        if (enrlWeight <= section.getLimit())
            continue;
        // above limit -> compute adepts (current assignments that are not
        // yet conflicting) exclude all conflicts as well
        List<Enrollment> adepts = new ArrayList<Enrollment>(section.getEnrollments(assignment).size());
        for (Enrollment e : section.getEnrollments(assignment)) {
            if (e.getRequest().equals(enrollment.getRequest()))
                continue;
            if (conflicts.contains(e))
                enrlWeight -= e.getRequest().getWeight();
            else
                adepts.add(e);
        }
        // while above limit -> pick an adept and make it conflicting
        while (enrlWeight > section.getLimit()) {
            if (adepts.isEmpty()) {
                // no adepts -> enrollment cannot be assigned
                conflicts.add(enrollment);
                return;
            }
            // pick adept (prefer dummy students & students w/o reservation), decrease enrollment
            // weight, make conflict
            List<Enrollment> best = new ArrayList<Enrollment>();
            boolean bestDummy = false;
            double bestValue = 0;
            boolean bestRes = true;
            for (Enrollment adept : adepts) {
                boolean dummy = adept.getStudent().isDummy();
                double value = adept.toDouble(assignment, false);
                boolean res = hasSectionReservation(adept, section);
                if (iPreferDummyStudents && dummy != bestDummy) {
                    if (dummy) {
                        best.clear();
                        best.add(adept);
                        bestDummy = dummy;
                        bestValue = value;
                        bestRes = res;
                    }
                    continue;
                }
                if (bestRes != res) {
                    if (!res) {
                        best.clear();
                        best.add(adept);
                        bestDummy = dummy;
                        bestValue = value;
                        bestRes = res;
                    }
                    continue;
                }
                if (best.isEmpty() || value > bestValue) {
                    if (best.isEmpty())
                        best.clear();
                    best.add(adept);
                    bestDummy = dummy;
                    bestValue = value;
                    bestRes = res;
                } else if (bestValue == value) {
                    best.add(adept);
                }
            }
            Enrollment conflict = ToolBox.random(best);
            adepts.remove(conflict);
            enrlWeight -= conflict.getRequest().getWeight();
            conflicts.add(conflict);
        }
    }
}
Also used : ArrayList(java.util.ArrayList) Enrollment(org.cpsolver.studentsct.model.Enrollment) Section(org.cpsolver.studentsct.model.Section)

Example 59 with Section

use of org.cpsolver.studentsct.model.Section in project cpsolver by UniTime.

the class OnlineSelection method updateSpace.

/** Update online sectioning info after the given student is sectioned 
     * @param assignment current assignment
     * @param student student in question
     **/
public void updateSpace(Assignment<Request, Enrollment> assignment, Student student) {
    for (Request request : student.getRequests()) {
        if (!(request instanceof CourseRequest))
            continue;
        CourseRequest courseRequest = (CourseRequest) request;
        Enrollment enrollment = assignment.getValue(courseRequest);
        if (enrollment == null)
            // not enrolled --> no update
            return;
        for (Section section : enrollment.getSections()) {
            section.setSpaceHeld(section.getSpaceHeld() - courseRequest.getWeight());
        // sLog.debug("  -- space held for "+section+" decreased by 1 (to "+section.getSpaceHeld()+")");
        }
        List<Enrollment> feasibleEnrollments = new ArrayList<Enrollment>();
        for (Enrollment enrl : courseRequest.values(assignment)) {
            boolean overlaps = false;
            for (Request otherRequest : courseRequest.getStudent().getRequests()) {
                if (otherRequest.equals(courseRequest) || !(otherRequest instanceof CourseRequest))
                    continue;
                Enrollment otherErollment = assignment.getValue(otherRequest);
                if (otherErollment == null)
                    continue;
                if (enrl.isOverlapping(otherErollment)) {
                    overlaps = true;
                    break;
                }
            }
            if (!overlaps)
                feasibleEnrollments.add(enrl);
        }
        double decrement = courseRequest.getWeight() / feasibleEnrollments.size();
        for (Enrollment feasibleEnrollment : feasibleEnrollments) {
            for (Section section : feasibleEnrollment.getSections()) {
                section.setSpaceExpected(section.getSpaceExpected() - decrement);
            // sLog.debug("  -- space expected for "+section+" decreased by "+decrement+" (to "+section.getSpaceExpected()+")");
            }
        }
    }
}
Also used : CourseRequest(org.cpsolver.studentsct.model.CourseRequest) CourseRequest(org.cpsolver.studentsct.model.CourseRequest) Request(org.cpsolver.studentsct.model.Request) ArrayList(java.util.ArrayList) Enrollment(org.cpsolver.studentsct.model.Enrollment) Section(org.cpsolver.studentsct.model.Section)

Aggregations

Section (org.cpsolver.studentsct.model.Section)59 Subpart (org.cpsolver.studentsct.model.Subpart)34 CourseRequest (org.cpsolver.studentsct.model.CourseRequest)32 Config (org.cpsolver.studentsct.model.Config)23 Request (org.cpsolver.studentsct.model.Request)22 Course (org.cpsolver.studentsct.model.Course)19 Enrollment (org.cpsolver.studentsct.model.Enrollment)19 Offering (org.cpsolver.studentsct.model.Offering)17 HashSet (java.util.HashSet)14 FreeTimeRequest (org.cpsolver.studentsct.model.FreeTimeRequest)14 ArrayList (java.util.ArrayList)13 Set (java.util.Set)11 TreeSet (java.util.TreeSet)10 HashMap (java.util.HashMap)9 Map (java.util.Map)9 Element (org.dom4j.Element)9 Student (org.cpsolver.studentsct.model.Student)7 CSVFile (org.cpsolver.ifs.util.CSVFile)6 DistanceConflict (org.cpsolver.studentsct.extension.DistanceConflict)6 RoomLocation (org.cpsolver.coursett.model.RoomLocation)5