Search in sources :

Example 31 with Subpart

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

the class StudentSectioningXMLLoader method loadConfig.

/**
 * Load config
 * @param configEl config element
 * @param offering parent offering
 * @param subpartTable subpart table (of the offering)
 * @param sectionTable section table (of the offering)
 * @param timetable provided timetable
 * @return loaded config
 */
protected Config loadConfig(Element configEl, Offering offering, Map<Long, Subpart> subpartTable, Map<Long, Section> sectionTable, Map<Long, Placement> timetable) {
    Config config = new Config(Long.parseLong(configEl.attributeValue("id")), Integer.parseInt(configEl.attributeValue("limit", "-1")), configEl.attributeValue("name", "G" + configEl.attributeValue("id")), offering);
    Element imEl = configEl.element("instructional-method");
    if (imEl != null) {
        config.setInstructionalMethodId(Long.parseLong(imEl.attributeValue("id")));
        config.setInstructionalMethodName(imEl.attributeValue("name", "M" + imEl.attributeValue("id")));
        config.setInstructionalMethodReference(imEl.attributeValue("reference", config.getInstructionalMethodName()));
    }
    for (Iterator<?> k = configEl.elementIterator("subpart"); k.hasNext(); ) {
        Element subpartEl = (Element) k.next();
        Subpart subpart = loadSubpart(subpartEl, config, subpartTable, sectionTable, timetable);
        subpartTable.put(Long.valueOf(subpart.getId()), subpart);
    }
    return config;
}
Also used : Config(org.cpsolver.studentsct.model.Config) Subpart(org.cpsolver.studentsct.model.Subpart) Element(org.dom4j.Element)

Example 32 with Subpart

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

the class StudentSectioningXMLSaver method saveRestriction.

/**
 * Save restriction
 * @param restrictionEl restriction element to be populated
 * @param restriction restriction to be saved
 */
protected void saveRestriction(Element restrictionEl, Restriction restriction) {
    restrictionEl.addAttribute("id", getId("restriction", restriction.getId()));
    if (restriction instanceof IndividualRestriction) {
        restrictionEl.addAttribute("type", "individual");
        for (Long studentId : ((IndividualRestriction) restriction).getStudentIds()) restrictionEl.addElement("student").addAttribute("id", getId("student", studentId));
    } else if (restriction instanceof CurriculumRestriction) {
        restrictionEl.addAttribute("type", "curriculum");
        CurriculumRestriction cr = (CurriculumRestriction) restriction;
        if (cr.getAcademicAreas().size() == 1)
            restrictionEl.addAttribute("area", cr.getAcademicAreas().iterator().next());
        else {
            for (String area : cr.getAcademicAreas()) restrictionEl.addElement("area").addAttribute("code", area);
        }
        for (String clasf : cr.getClassifications()) restrictionEl.addElement("classification").addAttribute("code", clasf);
        for (String major : cr.getMajors()) {
            Element majorEl = restrictionEl.addElement("major").addAttribute("code", major);
            Set<String> concentrations = cr.getConcentrations(major);
            if (concentrations != null)
                for (String conc : concentrations) majorEl.addElement("concentration").addAttribute("code", conc);
        }
        for (String minor : cr.getMinors()) restrictionEl.addElement("minor").addAttribute("code", minor);
    } else if (restriction instanceof CourseRestriction) {
        restrictionEl.addAttribute("type", "course");
        CourseRestriction cr = (CourseRestriction) restriction;
        restrictionEl.addAttribute("course", getId("course", cr.getCourse().getId()));
    }
    for (Config config : restriction.getConfigs()) restrictionEl.addElement("config").addAttribute("id", getId("config", config.getId()));
    for (Map.Entry<Subpart, Set<Section>> entry : restriction.getSections().entrySet()) {
        for (Section section : entry.getValue()) {
            restrictionEl.addElement("section").addAttribute("id", getId("section", section.getId()));
        }
    }
}
Also used : IndividualRestriction(org.cpsolver.studentsct.reservation.IndividualRestriction) Set(java.util.Set) TreeSet(java.util.TreeSet) BitSet(java.util.BitSet) Config(org.cpsolver.studentsct.model.Config) Subpart(org.cpsolver.studentsct.model.Subpart) CurriculumRestriction(org.cpsolver.studentsct.reservation.CurriculumRestriction) Element(org.dom4j.Element) Map(java.util.Map) Section(org.cpsolver.studentsct.model.Section) CourseRestriction(org.cpsolver.studentsct.reservation.CourseRestriction)

Example 33 with Subpart

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

the class CourseLimitCheck method check.

/**
 * Check for courses where the limit is below the number of students that
 * request the course
 *
 * @return false, if there is such a case
 */
public boolean check() {
    sLog.info("Checking for course limits...");
    boolean ret = true;
    for (Offering offering : getModel().getOfferings()) {
        boolean hasUnlimitedSection = false;
        if (iFixUnlimited)
            for (Config config : offering.getConfigs()) {
                for (Subpart subpart : config.getSubparts()) {
                    for (Section section : subpart.getSections()) {
                        if (section.getLimit() < 0)
                            hasUnlimitedSection = true;
                    }
                }
            }
        int offeringLimit = 0;
        int nrStudents = 0;
        for (Course course : offering.getCourses()) {
            if (course.getLimit() < 0) {
                offeringLimit = -1;
                continue;
            }
            if (iFixUnlimited && hasUnlimitedSection) {
                sLog.info("Course " + course + " made unlimited.");
                course.setLimit(-1);
                offeringLimit = -1;
                continue;
            }
            double total = 0;
            double lastLike = 0, real = 0;
            for (Request request : getModel().variables()) {
                if (request instanceof CourseRequest && ((CourseRequest) request).getCourses().contains(course)) {
                    total += request.getWeight();
                    if (request.getStudent().isDummy())
                        lastLike += request.getWeight();
                    else
                        real += request.getWeight();
                }
            }
            nrStudents += Math.round(total);
            offeringLimit += course.getLimit();
            if (Math.round(total) > course.getLimit()) {
                sLog.error("Course " + course + " is requested by " + sDF.format(total) + " students, but its limit is only " + course.getLimit());
                ret = false;
                iCSVFile.addLine(new CSVFile.CSVField[] { new CSVFile.CSVField(course.getName()), new CSVFile.CSVField(course.getLimit()), new CSVFile.CSVField(total), new CSVFile.CSVField(real), new CSVFile.CSVField(lastLike) });
                if (iUpZeroLimits && course.getLimit() == 0) {
                    int oldLimit = course.getLimit();
                    course.setLimit((int) Math.round(total));
                    sLog.info("  -- limit of course " + course + " increased to " + course.getLimit() + " (was " + oldLimit + ")");
                } else if (iUpNonZeroLimits && course.getLimit() > 0) {
                    int oldLimit = course.getLimit();
                    course.setLimit((int) Math.round(total));
                    sLog.info("  -- limit of course " + course + " increased to " + course.getLimit() + " (was " + oldLimit + ")");
                }
            }
        }
        if (iUpZeroLimits && offeringLimit == 0 && nrStudents > 0) {
            for (Config config : offering.getConfigs()) {
                for (Subpart subpart : config.getSubparts()) {
                    for (Section section : subpart.getSections()) {
                        int oldLimit = section.getLimit();
                        section.setLimit(Math.max(section.getLimit(), (int) Math.ceil(nrStudents / subpart.getSections().size())));
                        sLog.info("    -- limit of section " + section + " increased to " + section.getLimit() + " (was " + oldLimit + ")");
                    }
                }
            }
        } else if (iUpNonZeroLimits && offeringLimit >= 0 && nrStudents > offeringLimit) {
            double fact = ((double) nrStudents) / offeringLimit;
            for (Config config : offering.getConfigs()) {
                for (Subpart subpart : config.getSubparts()) {
                    for (Section section : subpart.getSections()) {
                        int oldLimit = section.getLimit();
                        section.setLimit((int) Math.ceil(fact * section.getLimit()));
                        sLog.info("    -- limit of section " + section + " increased to " + section.getLimit() + " (was " + oldLimit + ")");
                    }
                }
            }
        }
        if (offeringLimit >= 0) {
            int totalSectionLimit = 0;
            for (Config config : offering.getConfigs()) {
                int configLimit = -1;
                for (Subpart subpart : config.getSubparts()) {
                    int subpartLimit = 0;
                    for (Section section : subpart.getSections()) {
                        subpartLimit += section.getLimit();
                    }
                    if (configLimit < 0)
                        configLimit = subpartLimit;
                    else
                        configLimit = Math.min(configLimit, subpartLimit);
                }
                totalSectionLimit += configLimit;
            }
            if (totalSectionLimit < offeringLimit) {
                sLog.error("Offering limit of " + offering + " is " + offeringLimit + ", but total section limit is only " + totalSectionLimit);
                if (iUpZeroLimits && totalSectionLimit == 0) {
                    for (Config config : offering.getConfigs()) {
                        for (Subpart subpart : config.getSubparts()) {
                            for (Section section : subpart.getSections()) {
                                int oldLimit = section.getLimit();
                                section.setLimit(Math.max(section.getLimit(), (int) Math.ceil(((double) offeringLimit) / subpart.getSections().size())));
                                sLog.info("    -- limit of section " + section + " increased to " + section.getLimit() + " (was " + oldLimit + ")");
                            }
                        }
                    }
                } else if (iUpNonZeroLimits && totalSectionLimit > 0) {
                    double fact = ((double) offeringLimit) / totalSectionLimit;
                    for (Config config : offering.getConfigs()) {
                        for (Subpart subpart : config.getSubparts()) {
                            for (Section section : subpart.getSections()) {
                                int oldLimit = section.getLimit();
                                section.setLimit((int) Math.ceil(fact * section.getLimit()));
                                sLog.info("    -- limit of section " + section + " increased to " + section.getLimit() + " (was " + oldLimit + ")");
                            }
                        }
                    }
                }
            }
        }
    }
    return ret;
}
Also used : CourseRequest(org.cpsolver.studentsct.model.CourseRequest) CSVFile(org.cpsolver.ifs.util.CSVFile) Config(org.cpsolver.studentsct.model.Config) Subpart(org.cpsolver.studentsct.model.Subpart) CourseRequest(org.cpsolver.studentsct.model.CourseRequest) Request(org.cpsolver.studentsct.model.Request) Course(org.cpsolver.studentsct.model.Course) Offering(org.cpsolver.studentsct.model.Offering) Section(org.cpsolver.studentsct.model.Section)

Example 34 with Subpart

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

the class StudentPreferencePenalties method setPenalties.

/**
 * Set the computed penalties to all sections of all requests of the given
 * student
 * @param student given student
 * @param distributionType penalty distribution type
 */
public static void setPenalties(Student student, int distributionType) {
    if (sDebug)
        sLog.debug("Setting penalties for " + student);
    StudentPreferencePenalties penalties = new StudentPreferencePenalties(distributionType);
    for (Request request : student.getRequests()) {
        if (!(request instanceof CourseRequest))
            continue;
        CourseRequest courseRequest = (CourseRequest) request;
        if (sDebug)
            sLog.debug("-- " + courseRequest);
        for (Course course : courseRequest.getCourses()) {
            if (sDebug)
                sLog.debug("  -- " + course.getName());
            for (Config config : course.getOffering().getConfigs()) {
                if (sDebug)
                    sLog.debug("    -- " + config.getName());
                for (Subpart subpart : config.getSubparts()) {
                    if (sDebug)
                        sLog.debug("      -- " + subpart.getName());
                    for (Section section : subpart.getSections()) {
                        section.setPenalty(penalties.getPenalty(section));
                        if (sDebug)
                            sLog.debug("        -- " + section);
                    }
                }
            }
        }
        courseRequest.clearCache();
    }
}
Also used : CourseRequest(org.cpsolver.studentsct.model.CourseRequest) Config(org.cpsolver.studentsct.model.Config) Subpart(org.cpsolver.studentsct.model.Subpart) CourseRequest(org.cpsolver.studentsct.model.CourseRequest) FreeTimeRequest(org.cpsolver.studentsct.model.FreeTimeRequest) Request(org.cpsolver.studentsct.model.Request) Course(org.cpsolver.studentsct.model.Course) Section(org.cpsolver.studentsct.model.Section)

Example 35 with Subpart

use of org.cpsolver.studentsct.model.Subpart 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.setInstructionalMethodReference(config.getInstructionalMethodReference());
        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());
                clonedSection.setEnabled(section.isEnabled());
                clonedSection.setOnline(section.isOnline());
                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)

Aggregations

Subpart (org.cpsolver.studentsct.model.Subpart)44 Section (org.cpsolver.studentsct.model.Section)40 Config (org.cpsolver.studentsct.model.Config)23 CourseRequest (org.cpsolver.studentsct.model.CourseRequest)22 Offering (org.cpsolver.studentsct.model.Offering)16 Course (org.cpsolver.studentsct.model.Course)13 Request (org.cpsolver.studentsct.model.Request)13 HashSet (java.util.HashSet)12 Set (java.util.Set)12 TreeSet (java.util.TreeSet)10 Enrollment (org.cpsolver.studentsct.model.Enrollment)10 Map (java.util.Map)8 Element (org.dom4j.Element)7 HashMap (java.util.HashMap)6 FreeTimeRequest (org.cpsolver.studentsct.model.FreeTimeRequest)6 Student (org.cpsolver.studentsct.model.Student)6 BitSet (java.util.BitSet)5 DistanceConflict (org.cpsolver.studentsct.extension.DistanceConflict)5 StudentQuality (org.cpsolver.studentsct.extension.StudentQuality)5 TimeOverlapsCounter (org.cpsolver.studentsct.extension.TimeOverlapsCounter)5