Search in sources :

Example 46 with Request

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

the class BestPenaltyCriterion method canImprove.

@Override
public boolean canImprove(Assignment<Request, Enrollment> assignment, int maxIdx, Enrollment[] current, Enrollment[] best) {
    // 0. best priority & alternativity ignoring free time requests
    int alt = 0;
    for (int idx = 0; idx < current.length; idx++) {
        if (isFreeTime(idx))
            continue;
        Request request = getRequest(idx);
        if (idx < maxIdx) {
            if (best[idx] != null) {
                if (current[idx] == null)
                    // higher priority request assigned
                    return false;
                if (best[idx].getPriority() < current[idx].getPriority())
                    // less alternative request assigned
                    return false;
                if (request.isAlternative())
                    alt--;
            } else {
                if (current[idx] != null)
                    // higher priority request assigned
                    return true;
                if (!request.isAlternative())
                    alt++;
            }
        } else {
            if (best[idx] != null) {
                if (best[idx].getPriority() > 0)
                    // alternativity can be improved
                    return true;
            } else {
                if (!request.isAlternative() || alt > 0)
                    // priority can be improved
                    return true;
            }
        }
    }
    // 1. maximize number of penalties
    int bestPenalties = 0, currentPenalties = 0;
    for (int idx = 0; idx < current.length; idx++) {
        if (best[idx] != null) {
            for (Section section : best[idx].getSections()) bestPenalties += iModel.getOverExpected(assignment, section, best[idx].getRequest());
        }
        if (current[idx] != null && idx < maxIdx) {
            for (Section section : current[idx].getSections()) currentPenalties += iModel.getOverExpected(assignment, section, current[idx].getRequest());
        }
    }
    if (currentPenalties < bestPenalties)
        return true;
    if (bestPenalties < currentPenalties)
        return false;
    return false;
}
Also used : FreeTimeRequest(org.cpsolver.studentsct.model.FreeTimeRequest) Request(org.cpsolver.studentsct.model.Request) Section(org.cpsolver.studentsct.model.Section)

Example 47 with Request

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

the class Test method loadCrsReqFiles.

/**
     * Load course request from the given files (in the format being used by the
     * old MSF system)
     * 
     * @param model
     *            student sectioning model (with offerings loaded)
     * @param files
     *            semi-colon separated list of files to be loaded
     */
public static void loadCrsReqFiles(StudentSectioningModel model, String files) {
    try {
        boolean lastLike = model.getProperties().getPropertyBoolean("Test.CrsReqIsLastLike", true);
        boolean shuffleIds = model.getProperties().getPropertyBoolean("Test.CrsReqShuffleStudentIds", true);
        boolean tryWithoutSuffix = model.getProperties().getPropertyBoolean("Test.CrsReqTryWithoutSuffix", false);
        HashMap<Long, Student> students = new HashMap<Long, Student>();
        long reqId = 0;
        for (StringTokenizer stk = new StringTokenizer(files, ";"); stk.hasMoreTokens(); ) {
            String file = stk.nextToken();
            sLog.debug("Loading " + file + " ...");
            BufferedReader in = new BufferedReader(new FileReader(file));
            String line;
            int lineIndex = 0;
            while ((line = in.readLine()) != null) {
                lineIndex++;
                if (line.length() <= 150)
                    continue;
                char code = line.charAt(13);
                if (code == 'H' || code == 'T')
                    // skip header and tail
                    continue;
                long studentId = Long.parseLong(line.substring(14, 23));
                Student student = students.get(new Long(studentId));
                if (student == null) {
                    student = new Student(studentId);
                    if (lastLike)
                        student.setDummy(true);
                    students.put(new Long(studentId), student);
                    sLog.debug("  -- loading student " + studentId + " ...");
                } else
                    sLog.debug("  -- updating student " + studentId + " ...");
                line = line.substring(150);
                while (line.length() >= 20) {
                    String subjectArea = line.substring(0, 4).trim();
                    String courseNbr = line.substring(4, 8).trim();
                    if (subjectArea.length() == 0 || courseNbr.length() == 0) {
                        line = line.substring(20);
                        continue;
                    }
                    /*
                         * // UNUSED String instrSel = line.substring(8,10);
                         * //ZZ - Remove previous instructor selection char
                         * reqPDiv = line.charAt(10); //P - Personal preference;
                         * C - Conflict resolution; //0 - (Zero) used by program
                         * only, for change requests to reschedule division //
                         * (used to reschedule canceled division) String reqDiv
                         * = line.substring(11,13); //00 - Reschedule division
                         * String reqSect = line.substring(13,15); //Contains
                         * designator for designator-required courses String
                         * credit = line.substring(15,19); char nameRaise =
                         * line.charAt(19); //N - Name raise
                         */
                    // A - Add; D - Drop; C -
                    char action = line.charAt(19);
                    // Change
                    sLog.debug("    -- requesting " + subjectArea + " " + courseNbr + " (action:" + action + ") ...");
                    Course course = null;
                    offerings: for (Offering offering : model.getOfferings()) {
                        for (Course c : offering.getCourses()) {
                            if (c.getSubjectArea().equals(subjectArea) && c.getCourseNumber().equals(courseNbr)) {
                                course = c;
                                break offerings;
                            }
                        }
                    }
                    if (course == null && tryWithoutSuffix && courseNbr.charAt(courseNbr.length() - 1) >= 'A' && courseNbr.charAt(courseNbr.length() - 1) <= 'Z') {
                        String courseNbrNoSfx = courseNbr.substring(0, courseNbr.length() - 1);
                        offerings: for (Offering offering : model.getOfferings()) {
                            for (Course c : offering.getCourses()) {
                                if (c.getSubjectArea().equals(subjectArea) && c.getCourseNumber().equals(courseNbrNoSfx)) {
                                    course = c;
                                    break offerings;
                                }
                            }
                        }
                    }
                    if (course == null) {
                        if (courseNbr.charAt(courseNbr.length() - 1) >= 'A' && courseNbr.charAt(courseNbr.length() - 1) <= 'Z') {
                        } else {
                            sLog.warn("      -- course " + subjectArea + " " + courseNbr + " not found (file " + file + ", line " + lineIndex + ")");
                        }
                    } else {
                        CourseRequest courseRequest = null;
                        for (Request request : student.getRequests()) {
                            if (request instanceof CourseRequest && ((CourseRequest) request).getCourses().contains(course)) {
                                courseRequest = (CourseRequest) request;
                                break;
                            }
                        }
                        if (action == 'A') {
                            if (courseRequest == null) {
                                List<Course> courses = new ArrayList<Course>(1);
                                courses.add(course);
                                courseRequest = new CourseRequest(reqId++, student.getRequests().size(), false, student, courses, false, null);
                            } else {
                                sLog.warn("      -- request for course " + course + " is already present");
                            }
                        } else if (action == 'D') {
                            if (courseRequest == null) {
                                sLog.warn("      -- request for course " + course + " is not present -- cannot be dropped");
                            } else {
                                student.getRequests().remove(courseRequest);
                            }
                        } else if (action == 'C') {
                            if (courseRequest == null) {
                                sLog.warn("      -- request for course " + course + " is not present -- cannot be changed");
                            } else {
                            // ?
                            }
                        } else {
                            sLog.warn("      -- unknown action " + action);
                        }
                    }
                    line = line.substring(20);
                }
            }
            in.close();
        }
        HashMap<Course, List<Request>> requests = new HashMap<Course, List<Request>>();
        Set<Long> studentIds = new HashSet<Long>();
        for (Student student : students.values()) {
            if (!student.getRequests().isEmpty())
                model.addStudent(student);
            if (shuffleIds) {
                long newId = -1;
                while (true) {
                    newId = 1 + (long) (999999999L * Math.random());
                    if (studentIds.add(new Long(newId)))
                        break;
                }
                student.setId(newId);
            }
            if (student.isDummy()) {
                for (Request request : student.getRequests()) {
                    if (request instanceof CourseRequest) {
                        Course course = ((CourseRequest) request).getCourses().get(0);
                        List<Request> requestsThisCourse = requests.get(course);
                        if (requestsThisCourse == null) {
                            requestsThisCourse = new ArrayList<Request>();
                            requests.put(course, requestsThisCourse);
                        }
                        requestsThisCourse.add(request);
                    }
                }
            }
        }
        Collections.sort(model.getStudents(), new Comparator<Student>() {

            @Override
            public int compare(Student o1, Student o2) {
                return Double.compare(o1.getId(), o2.getId());
            }
        });
        for (Map.Entry<Course, List<Request>> entry : requests.entrySet()) {
            Course course = entry.getKey();
            List<Request> requestsThisCourse = entry.getValue();
            double weight = getLastLikeStudentWeight(course, 0, requestsThisCourse.size());
            for (Request request : requestsThisCourse) {
                request.setWeight(weight);
            }
        }
        if (model.getProperties().getProperty("Test.EtrChk") != null) {
            for (StringTokenizer stk = new StringTokenizer(model.getProperties().getProperty("Test.EtrChk"), ";"); stk.hasMoreTokens(); ) {
                String file = stk.nextToken();
                sLog.debug("Loading " + file + " ...");
                BufferedReader in = new BufferedReader(new FileReader(file));
                try {
                    String line;
                    while ((line = in.readLine()) != null) {
                        if (line.length() < 55)
                            continue;
                        char code = line.charAt(12);
                        if (code == 'H' || code == 'T')
                            // skip header and tail
                            continue;
                        if (code == 'D' || code == 'K')
                            // skip delete nad cancel
                            continue;
                        long studentId = Long.parseLong(line.substring(2, 11));
                        Student student = students.get(new Long(studentId));
                        if (student == null) {
                            sLog.info("  -- student " + studentId + " not found");
                            continue;
                        }
                        sLog.info("  -- reading student " + studentId);
                        String area = line.substring(15, 18).trim();
                        if (area.length() == 0)
                            continue;
                        String clasf = line.substring(18, 20).trim();
                        String major = line.substring(21, 24).trim();
                        String minor = line.substring(24, 27).trim();
                        student.getAcademicAreaClasiffications().clear();
                        student.getMajors().clear();
                        student.getMinors().clear();
                        student.getAcademicAreaClasiffications().add(new AcademicAreaCode(area, clasf));
                        if (major.length() > 0)
                            student.getMajors().add(new AcademicAreaCode(area, major));
                        if (minor.length() > 0)
                            student.getMinors().add(new AcademicAreaCode(area, minor));
                    }
                } finally {
                    in.close();
                }
            }
        }
        int without = 0;
        for (Student student : students.values()) {
            if (student.getAcademicAreaClasiffications().isEmpty())
                without++;
        }
        fixPriorities(model);
        sLog.info("Students without academic area: " + without);
    } catch (Exception e) {
        sLog.error(e.getMessage(), e);
    }
}
Also used : HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) AcademicAreaCode(org.cpsolver.studentsct.model.AcademicAreaCode) FileReader(java.io.FileReader) List(java.util.List) ArrayList(java.util.ArrayList) Course(org.cpsolver.studentsct.model.Course) HashSet(java.util.HashSet) Request(org.cpsolver.studentsct.model.Request) CourseRequest(org.cpsolver.studentsct.model.CourseRequest) Student(org.cpsolver.studentsct.model.Student) Offering(org.cpsolver.studentsct.model.Offering) IOException(java.io.IOException) StringTokenizer(java.util.StringTokenizer) CourseRequest(org.cpsolver.studentsct.model.CourseRequest) BufferedReader(java.io.BufferedReader) Map(java.util.Map) HashMap(java.util.HashMap)

Example 48 with Request

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

the class Test method fixPriorities.

public static void fixPriorities(StudentSectioningModel model) {
    for (Student student : model.getStudents()) {
        Collections.sort(student.getRequests(), new Comparator<Request>() {

            @Override
            public int compare(Request r1, Request r2) {
                int cmp = Double.compare(r1.getPriority(), r2.getPriority());
                if (cmp != 0)
                    return cmp;
                return Double.compare(r1.getId(), r2.getId());
            }
        });
        int priority = 0;
        for (Request request : student.getRequests()) {
            if (priority != request.getPriority()) {
                sLog.debug("Change priority of " + request + " to " + priority);
                request.setPriority(priority);
            }
        }
    }
}
Also used : Request(org.cpsolver.studentsct.model.Request) CourseRequest(org.cpsolver.studentsct.model.CourseRequest) Student(org.cpsolver.studentsct.model.Student)

Example 49 with Request

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

the class Test method onlineSectioning.

/** Online sectioning test 
     * @param cfg solver configuration
     * @return resultant solution
     * @throws Exception thrown when the sectioning fails
     **/
public static Solution<Request, Enrollment> onlineSectioning(DataProperties cfg) throws Exception {
    Solution<Request, Enrollment> solution = load(cfg);
    if (solution == null)
        return null;
    StudentSectioningModel model = (StudentSectioningModel) solution.getModel();
    Assignment<Request, Enrollment> assignment = solution.getAssignment();
    solution.addSolutionListener(new TestSolutionListener());
    double startTime = JProf.currentTimeSec();
    Solver<Request, Enrollment> solver = new Solver<Request, Enrollment>(cfg);
    solver.setInitalSolution(solution);
    solver.initSolver();
    OnlineSelection onlineSelection = new OnlineSelection(cfg);
    onlineSelection.init(solver);
    double totalPenalty = 0, minPenalty = 0, maxPenalty = 0;
    double minAvEnrlPenalty = 0, maxAvEnrlPenalty = 0;
    double totalPrefPenalty = 0, minPrefPenalty = 0, maxPrefPenalty = 0;
    double minAvEnrlPrefPenalty = 0, maxAvEnrlPrefPenalty = 0;
    int nrChoices = 0, nrEnrollments = 0, nrCourseRequests = 0;
    int chChoices = 0, chCourseRequests = 0, chStudents = 0;
    int choiceLimit = model.getProperties().getPropertyInt("Test.ChoicesLimit", -1);
    File outDir = new File(model.getProperties().getProperty("General.Output", "."));
    outDir.mkdirs();
    PrintWriter pw = new PrintWriter(new FileWriter(new File(outDir, "choices.csv")));
    List<Student> students = model.getStudents();
    try {
        @SuppressWarnings("rawtypes") Class studentOrdClass = Class.forName(model.getProperties().getProperty("Test.StudentOrder", StudentRandomOrder.class.getName()));
        @SuppressWarnings("unchecked") StudentOrder studentOrd = (StudentOrder) studentOrdClass.getConstructor(new Class[] { DataProperties.class }).newInstance(new Object[] { model.getProperties() });
        students = studentOrd.order(model.getStudents());
    } catch (Exception e) {
        sLog.error("Unable to reorder students, reason: " + e.getMessage(), e);
    }
    ShutdownHook hook = new ShutdownHook(solver);
    Runtime.getRuntime().addShutdownHook(hook);
    for (Student student : students) {
        if (student.nrAssignedRequests(assignment) > 0)
            // skip students with assigned courses (i.e., students
            continue;
        // already assigned by a batch sectioning process)
        sLog.info("Sectioning student: " + student);
        BranchBoundSelection.Selection selection = onlineSelection.getSelection(assignment, student);
        BranchBoundNeighbour neighbour = selection.select();
        if (neighbour != null) {
            StudentPreferencePenalties penalties = null;
            if (selection instanceof OnlineSelection.EpsilonSelection) {
                OnlineSelection.EpsilonSelection epsSelection = (OnlineSelection.EpsilonSelection) selection;
                penalties = epsSelection.getPenalties();
                for (int i = 0; i < neighbour.getAssignment().length; i++) {
                    Request r = student.getRequests().get(i);
                    if (r instanceof CourseRequest) {
                        nrCourseRequests++;
                        chCourseRequests++;
                        int chChoicesThisRq = 0;
                        CourseRequest request = (CourseRequest) r;
                        for (Enrollment x : request.getAvaiableEnrollments(assignment)) {
                            nrEnrollments++;
                            if (epsSelection.isAllowed(i, x)) {
                                nrChoices++;
                                if (choiceLimit <= 0 || chChoicesThisRq < choiceLimit) {
                                    chChoices++;
                                    chChoicesThisRq++;
                                }
                            }
                        }
                    }
                }
                chStudents++;
                if (chStudents == 100) {
                    pw.println(sDF.format(((double) chChoices) / chCourseRequests));
                    pw.flush();
                    chStudents = 0;
                    chChoices = 0;
                    chCourseRequests = 0;
                }
            }
            for (int i = 0; i < neighbour.getAssignment().length; i++) {
                if (neighbour.getAssignment()[i] == null)
                    continue;
                Enrollment enrollment = neighbour.getAssignment()[i];
                if (enrollment.getRequest() instanceof CourseRequest) {
                    CourseRequest request = (CourseRequest) enrollment.getRequest();
                    double[] avEnrlMinMax = getMinMaxAvailableEnrollmentPenalty(assignment, request);
                    minAvEnrlPenalty += avEnrlMinMax[0];
                    maxAvEnrlPenalty += avEnrlMinMax[1];
                    totalPenalty += enrollment.getPenalty();
                    minPenalty += request.getMinPenalty();
                    maxPenalty += request.getMaxPenalty();
                    if (penalties != null) {
                        double[] avEnrlPrefMinMax = penalties.getMinMaxAvailableEnrollmentPenalty(assignment, enrollment.getRequest());
                        minAvEnrlPrefPenalty += avEnrlPrefMinMax[0];
                        maxAvEnrlPrefPenalty += avEnrlPrefMinMax[1];
                        totalPrefPenalty += penalties.getPenalty(enrollment);
                        minPrefPenalty += penalties.getMinPenalty(enrollment.getRequest());
                        maxPrefPenalty += penalties.getMaxPenalty(enrollment.getRequest());
                    }
                }
            }
            neighbour.assign(assignment, solution.getIteration());
            sLog.info("Student " + student + " enrolls into " + neighbour);
            onlineSelection.updateSpace(assignment, student);
        } else {
            sLog.warn("No solution found.");
        }
        solution.update(JProf.currentTimeSec() - startTime);
    }
    if (chCourseRequests > 0)
        pw.println(sDF.format(((double) chChoices) / chCourseRequests));
    pw.flush();
    pw.close();
    HashMap<String, String> extra = new HashMap<String, String>();
    sLog.info("Overall penalty is " + getPerc(totalPenalty, minPenalty, maxPenalty) + "% (" + sDF.format(totalPenalty) + "/" + sDF.format(minPenalty) + ".." + sDF.format(maxPenalty) + ")");
    extra.put("Overall penalty", getPerc(totalPenalty, minPenalty, maxPenalty) + "% (" + sDF.format(totalPenalty) + "/" + sDF.format(minPenalty) + ".." + sDF.format(maxPenalty) + ")");
    extra.put("Overall available enrollment penalty", getPerc(totalPenalty, minAvEnrlPenalty, maxAvEnrlPenalty) + "% (" + sDF.format(totalPenalty) + "/" + sDF.format(minAvEnrlPenalty) + ".." + sDF.format(maxAvEnrlPenalty) + ")");
    if (onlineSelection.isUseStudentPrefPenalties()) {
        sLog.info("Overall preference penalty is " + getPerc(totalPrefPenalty, minPrefPenalty, maxPrefPenalty) + "% (" + sDF.format(totalPrefPenalty) + "/" + sDF.format(minPrefPenalty) + ".." + sDF.format(maxPrefPenalty) + ")");
        extra.put("Overall preference penalty", getPerc(totalPrefPenalty, minPrefPenalty, maxPrefPenalty) + "% (" + sDF.format(totalPrefPenalty) + "/" + sDF.format(minPrefPenalty) + ".." + sDF.format(maxPrefPenalty) + ")");
        extra.put("Overall preference available enrollment penalty", getPerc(totalPrefPenalty, minAvEnrlPrefPenalty, maxAvEnrlPrefPenalty) + "% (" + sDF.format(totalPrefPenalty) + "/" + sDF.format(minAvEnrlPrefPenalty) + ".." + sDF.format(maxAvEnrlPrefPenalty) + ")");
        extra.put("Average number of choices", sDF.format(((double) nrChoices) / nrCourseRequests) + " (" + nrChoices + "/" + nrCourseRequests + ")");
        extra.put("Average number of enrollments", sDF.format(((double) nrEnrollments) / nrCourseRequests) + " (" + nrEnrollments + "/" + nrCourseRequests + ")");
    }
    hook.setExtra(extra);
    return solution;
}
Also used : Solver(org.cpsolver.ifs.solver.Solver) ParallelSolver(org.cpsolver.ifs.solver.ParallelSolver) HashMap(java.util.HashMap) FileWriter(java.io.FileWriter) OnlineSelection(org.cpsolver.studentsct.heuristics.selection.OnlineSelection) Enrollment(org.cpsolver.studentsct.model.Enrollment) PrintWriter(java.io.PrintWriter) BranchBoundSelection(org.cpsolver.studentsct.heuristics.selection.BranchBoundSelection) Request(org.cpsolver.studentsct.model.Request) CourseRequest(org.cpsolver.studentsct.model.CourseRequest) Student(org.cpsolver.studentsct.model.Student) IOException(java.io.IOException) CourseRequest(org.cpsolver.studentsct.model.CourseRequest) BranchBoundNeighbour(org.cpsolver.studentsct.heuristics.selection.BranchBoundSelection.BranchBoundNeighbour) StudentOrder(org.cpsolver.studentsct.heuristics.studentord.StudentOrder) File(java.io.File)

Example 50 with Request

use of org.cpsolver.studentsct.model.Request 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)

Aggregations

Request (org.cpsolver.studentsct.model.Request)65 CourseRequest (org.cpsolver.studentsct.model.CourseRequest)51 Enrollment (org.cpsolver.studentsct.model.Enrollment)47 FreeTimeRequest (org.cpsolver.studentsct.model.FreeTimeRequest)23 Section (org.cpsolver.studentsct.model.Section)22 ArrayList (java.util.ArrayList)21 Student (org.cpsolver.studentsct.model.Student)21 Course (org.cpsolver.studentsct.model.Course)20 HashSet (java.util.HashSet)18 HashMap (java.util.HashMap)14 Subpart (org.cpsolver.studentsct.model.Subpart)10 Map (java.util.Map)9 DataProperties (org.cpsolver.ifs.util.DataProperties)9 Config (org.cpsolver.studentsct.model.Config)8 Offering (org.cpsolver.studentsct.model.Offering)8 Set (java.util.Set)7 DefaultSingleAssignment (org.cpsolver.ifs.assignment.DefaultSingleAssignment)7 File (java.io.File)6 IOException (java.io.IOException)6 TreeSet (java.util.TreeSet)6