Search in sources :

Example 6 with Subpart

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

the class StudentSectioningXMLSaver method saveLinkedSections.

/**
 * Save linked sections
 * @param root document root
 */
protected void saveLinkedSections(Element root) {
    Element constrainstEl = root.addElement("constraints");
    for (LinkedSections linkedSections : getModel().getLinkedSections()) {
        Element linkEl = constrainstEl.addElement("linked-sections");
        linkEl.addAttribute("mustBeUsed", linkedSections.isMustBeUsed() ? "true" : "false");
        for (Offering offering : linkedSections.getOfferings()) for (Subpart subpart : linkedSections.getSubparts(offering)) for (Section section : linkedSections.getSections(subpart)) linkEl.addElement("section").addAttribute("offering", getId("offering", offering.getId())).addAttribute("id", getId("section", section.getId()));
    }
}
Also used : LinkedSections(org.cpsolver.studentsct.constraint.LinkedSections) Subpart(org.cpsolver.studentsct.model.Subpart) Element(org.dom4j.Element) Offering(org.cpsolver.studentsct.model.Offering) Section(org.cpsolver.studentsct.model.Section)

Example 7 with Subpart

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

the class StudentSectioningXMLSaver method saveConfig.

/**
 * Save given config
 * @param configEl config element to be populated
 * @param config config to be saved
 */
protected void saveConfig(Element configEl, Config config) {
    configEl.addAttribute("id", getId("config", config.getId()));
    if (config.getLimit() >= 0)
        configEl.addAttribute("limit", String.valueOf(config.getLimit()));
    if (iShowNames)
        configEl.addAttribute("name", config.getName());
    for (Subpart subpart : config.getSubparts()) {
        Element subpartEl = configEl.addElement("subpart");
        saveSubpart(subpartEl, subpart);
    }
    if (config.getInstructionalMethodId() != null) {
        Element imEl = configEl.addElement("instructional-method");
        imEl.addAttribute("id", getId("instructional-method", config.getInstructionalMethodId()));
        if (iShowNames && config.getInstructionalMethodName() != null)
            imEl.addAttribute("name", config.getInstructionalMethodName());
        if (iShowNames && config.getInstructionalMethodReference() != null)
            imEl.addAttribute("reference", config.getInstructionalMethodReference());
    }
}
Also used : Subpart(org.cpsolver.studentsct.model.Subpart) Element(org.dom4j.Element)

Example 8 with Subpart

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

the class Test method section.

public boolean section(Student original) {
    OnlineSectioningModel model = new TestModel(iModel.getProperties());
    model.setOverExpectedCriterion(iModel.getOverExpectedCriterion());
    Student student = new Student(original.getId());
    Hashtable<CourseRequest, Set<Section>> preferredSectionsForCourse = new Hashtable<CourseRequest, Set<Section>>();
    Map<Long, Section> classTable = new HashMap<Long, Section>();
    synchronized (iModel) {
        for (Request request : original.getRequests()) {
            Request clonnedRequest = addRequest(student, original, request, classTable, model);
            Enrollment enrollment = assignment().getValue(request);
            if (enrollment != null && enrollment.isCourseRequest()) {
                Set<Section> sections = new HashSet<Section>();
                for (Section section : enrollment.getSections()) sections.add(classTable.get(section.getId()));
                preferredSectionsForCourse.put((CourseRequest) clonnedRequest, sections);
            }
        }
    }
    model.addStudent(student);
    model.setDistanceConflict(new DistanceConflict(iModel.getDistanceConflict().getDistanceMetric(), model.getProperties()));
    model.setTimeOverlaps(new TimeOverlapsCounter(null, model.getProperties()));
    for (LinkedSections link : iModel.getLinkedSections()) {
        List<Section> sections = new ArrayList<Section>();
        for (Offering offering : link.getOfferings()) for (Subpart subpart : link.getSubparts(offering)) for (Section section : link.getSections(subpart)) {
            Section x = classTable.get(section.getId());
            if (x != null)
                sections.add(x);
        }
        if (sections.size() >= 2)
            model.addLinkedSections(link.isMustBeUsed(), sections);
    }
    OnlineSectioningSelection selection = null;
    if (model.getProperties().getPropertyBoolean("StudentWeights.MultiCriteria", true)) {
        selection = new MultiCriteriaBranchAndBoundSelection(iModel.getProperties());
    } else {
        selection = new SuggestionSelection(model.getProperties());
    }
    selection.setModel(model);
    selection.setPreferredSections(preferredSectionsForCourse);
    selection.setRequiredSections(new Hashtable<CourseRequest, Set<Section>>());
    selection.setRequiredFreeTimes(new HashSet<FreeTimeRequest>());
    long t0 = JProf.currentTimeMillis();
    Assignment<Request, Enrollment> newAssignment = new AssignmentMap<Request, Enrollment>();
    BranchBoundNeighbour neighbour = selection.select(newAssignment, student);
    long time = JProf.currentTimeMillis() - t0;
    inc("[C] CPU Time", time);
    if (neighbour == null) {
        inc("[F] Failure");
    } else {
        if (iSuggestions) {
            StudentPreferencePenalties penalties = new StudentPreferencePenalties(StudentPreferencePenalties.sDistTypePreference);
            double maxOverExpected = 0;
            int assigned = 0;
            double penalty = 0.0;
            Hashtable<CourseRequest, Set<Section>> enrollments = new Hashtable<CourseRequest, Set<Section>>();
            List<RequestSectionPair> pairs = new ArrayList<RequestSectionPair>();
            for (int i = 0; i < neighbour.getAssignment().length; i++) {
                Enrollment enrl = neighbour.getAssignment()[i];
                if (enrl != null && enrl.isCourseRequest() && enrl.getAssignments() != null) {
                    assigned++;
                    for (Section section : enrl.getSections()) {
                        maxOverExpected += model.getOverExpected(newAssignment, section, enrl.getRequest());
                        pairs.add(new RequestSectionPair(enrl.variable(), section));
                    }
                    enrollments.put((CourseRequest) enrl.variable(), enrl.getSections());
                    penalty += penalties.getPenalty(enrl);
                }
            }
            penalty /= assigned;
            inc("[S] Initial Penalty", penalty);
            double nrSuggestions = 0.0, nrAccepted = 0.0, totalSuggestions = 0.0, nrTries = 0.0;
            for (int i = 0; i < pairs.size(); i++) {
                RequestSectionPair pair = pairs.get(i);
                SuggestionsBranchAndBound suggestionBaB = null;
                if (model.getProperties().getPropertyBoolean("StudentWeights.MultiCriteria", true)) {
                    suggestionBaB = new MultiCriteriaBranchAndBoundSuggestions(model.getProperties(), student, newAssignment, new Hashtable<CourseRequest, Set<Section>>(), new HashSet<FreeTimeRequest>(), enrollments, pair.getRequest(), pair.getSection(), null, maxOverExpected, iModel.getProperties().getPropertyBoolean("StudentWeights.PriorityWeighting", true));
                } else {
                    suggestionBaB = new SuggestionsBranchAndBound(model.getProperties(), student, newAssignment, new Hashtable<CourseRequest, Set<Section>>(), new HashSet<FreeTimeRequest>(), enrollments, pair.getRequest(), pair.getSection(), null, maxOverExpected);
                }
                long x0 = JProf.currentTimeMillis();
                TreeSet<SuggestionsBranchAndBound.Suggestion> suggestions = suggestionBaB.computeSuggestions();
                inc("[S] Suggestion CPU Time", JProf.currentTimeMillis() - x0);
                totalSuggestions += suggestions.size();
                if (!suggestions.isEmpty())
                    nrSuggestions += 1.0;
                nrTries += 1.0;
                SuggestionsBranchAndBound.Suggestion best = null;
                for (SuggestionsBranchAndBound.Suggestion suggestion : suggestions) {
                    int a = 0;
                    double p = 0.0;
                    for (int j = 0; j < suggestion.getEnrollments().length; j++) {
                        Enrollment e = suggestion.getEnrollments()[j];
                        if (e != null && e.isCourseRequest() && e.getAssignments() != null) {
                            p += penalties.getPenalty(e);
                            a++;
                        }
                    }
                    p /= a;
                    if (a > assigned || (assigned == a && p < penalty)) {
                        best = suggestion;
                    }
                }
                if (best != null) {
                    nrAccepted += 1.0;
                    Enrollment[] e = best.getEnrollments();
                    for (int j = 0; j < e.length; j++) if (e[j] != null && e[j].getAssignments() == null)
                        e[j] = null;
                    neighbour = new BranchBoundNeighbour(student, best.getValue(), e);
                    assigned = 0;
                    penalty = 0.0;
                    enrollments.clear();
                    pairs.clear();
                    for (int j = 0; j < neighbour.getAssignment().length; j++) {
                        Enrollment enrl = neighbour.getAssignment()[j];
                        if (enrl != null && enrl.isCourseRequest() && enrl.getAssignments() != null) {
                            assigned++;
                            for (Section section : enrl.getSections()) pairs.add(new RequestSectionPair(enrl.variable(), section));
                            enrollments.put((CourseRequest) enrl.variable(), enrl.getSections());
                            penalty += penalties.getPenalty(enrl);
                        }
                    }
                    penalty /= assigned;
                    inc("[S] Improved Penalty", penalty);
                }
            }
            inc("[S] Final Penalty", penalty);
            if (nrSuggestions > 0) {
                inc("[S] Classes with suggestion", nrSuggestions);
                inc("[S] Avg. # of suggestions", totalSuggestions / nrSuggestions);
                inc("[S] Suggestion acceptance rate [%]", nrAccepted / nrSuggestions);
            } else {
                inc("[S] Student with no suggestions available", 1.0);
            }
            if (!pairs.isEmpty())
                inc("[S] Probability that a class has suggestions [%]", nrSuggestions / nrTries);
        }
        List<Enrollment> enrollments = new ArrayList<Enrollment>();
        i: for (int i = 0; i < neighbour.getAssignment().length; i++) {
            Request request = original.getRequests().get(i);
            Enrollment clonnedEnrollment = neighbour.getAssignment()[i];
            if (clonnedEnrollment != null && clonnedEnrollment.getAssignments() != null) {
                if (request instanceof FreeTimeRequest) {
                    enrollments.add(((FreeTimeRequest) request).createEnrollment());
                } else {
                    for (Course course : ((CourseRequest) request).getCourses()) if (course.getId() == clonnedEnrollment.getCourse().getId())
                        for (Config config : course.getOffering().getConfigs()) if (config.getId() == clonnedEnrollment.getConfig().getId()) {
                            Set<Section> assignments = new HashSet<Section>();
                            for (Subpart subpart : config.getSubparts()) for (Section section : subpart.getSections()) {
                                if (clonnedEnrollment.getSections().contains(section)) {
                                    assignments.add(section);
                                }
                            }
                            Reservation reservation = null;
                            if (clonnedEnrollment.getReservation() != null) {
                                for (Reservation r : course.getOffering().getReservations()) if (r.getId() == clonnedEnrollment.getReservation().getId()) {
                                    reservation = r;
                                    break;
                                }
                            }
                            enrollments.add(new Enrollment(request, clonnedEnrollment.getPriority(), course, config, assignments, reservation));
                            continue i;
                        }
                }
            }
        }
        synchronized (iModel) {
            for (Request r : original.getRequests()) {
                Enrollment e = assignment().getValue(r);
                r.setInitialAssignment(e);
                if (e != null)
                    updateSpace(assignment(), e, true);
            }
            for (Request r : original.getRequests()) if (assignment().getValue(r) != null)
                assignment().unassign(0, r);
            boolean fail = false;
            for (Enrollment enrl : enrollments) {
                if (iModel.conflictValues(assignment(), enrl).isEmpty()) {
                    assignment().assign(0, enrl);
                } else {
                    fail = true;
                    break;
                }
            }
            if (fail) {
                for (Request r : original.getRequests()) if (assignment().getValue(r) != null)
                    assignment().unassign(0, r);
                for (Request r : original.getRequests()) if (r.getInitialAssignment() != null)
                    assignment().assign(0, r.getInitialAssignment());
                for (Request r : original.getRequests()) if (assignment().getValue(r) != null)
                    updateSpace(assignment(), assignment().getValue(r), false);
            } else {
                for (Enrollment enrl : enrollments) updateSpace(assignment(), enrl, false);
            }
            if (fail)
                return false;
        }
        neighbour.assign(newAssignment, 0);
        int a = 0, u = 0, np = 0, zp = 0, pp = 0, cp = 0;
        double over = 0;
        double p = 0.0;
        for (Request r : student.getRequests()) {
            if (r instanceof CourseRequest) {
                Enrollment e = newAssignment.getValue(r);
                if (e != null) {
                    for (Section s : e.getSections()) {
                        if (s.getPenalty() < 0.0)
                            np++;
                        if (s.getPenalty() == 0.0)
                            zp++;
                        if (s.getPenalty() > 0.0)
                            pp++;
                        if (s.getLimit() > 0) {
                            p += s.getPenalty();
                            cp++;
                        }
                        over += model.getOverExpected(newAssignment, s, r);
                    }
                    a++;
                } else {
                    u++;
                }
            }
        }
        inc("[A] Student");
        if (over > 0.0)
            inc("[O] Over", over);
        if (a > 0)
            inc("[A] Assigned", a);
        if (u > 0)
            inc("[A] Not Assigned", u);
        inc("[V] Value", neighbour.value(newAssignment));
        if (zp > 0)
            inc("[P] Zero penalty", zp);
        if (np > 0)
            inc("[P] Negative penalty", np);
        if (pp > 0)
            inc("[P] Positive penalty", pp);
        if (cp > 0)
            inc("[P] Average penalty", p / cp);
    }
    inc("[T0] Time <10ms", time < 10 ? 1 : 0);
    inc("[T1] Time <100ms", time < 100 ? 1 : 0);
    inc("[T2] Time <250ms", time < 250 ? 1 : 0);
    inc("[T3] Time <500ms", time < 500 ? 1 : 0);
    inc("[T4] Time <1s", time < 1000 ? 1 : 0);
    inc("[T5] Time >=1s", time >= 1000 ? 1 : 0);
    return true;
}
Also used : StudentPreferencePenalties(org.cpsolver.studentsct.StudentPreferencePenalties) Set(java.util.Set) TreeSet(java.util.TreeSet) HashSet(java.util.HashSet) HashMap(java.util.HashMap) Config(org.cpsolver.studentsct.model.Config) DistanceConflict(org.cpsolver.studentsct.extension.DistanceConflict) ArrayList(java.util.ArrayList) SuggestionSelection(org.cpsolver.studentsct.online.selection.SuggestionSelection) CourseReservation(org.cpsolver.studentsct.reservation.CourseReservation) Reservation(org.cpsolver.studentsct.reservation.Reservation) LinkedSections(org.cpsolver.studentsct.constraint.LinkedSections) Enrollment(org.cpsolver.studentsct.model.Enrollment) SuggestionsBranchAndBound(org.cpsolver.studentsct.online.selection.SuggestionsBranchAndBound) Course(org.cpsolver.studentsct.model.Course) HashSet(java.util.HashSet) MultiCriteriaBranchAndBoundSelection(org.cpsolver.studentsct.online.selection.MultiCriteriaBranchAndBoundSelection) FreeTimeRequest(org.cpsolver.studentsct.model.FreeTimeRequest) Hashtable(java.util.Hashtable) Request(org.cpsolver.studentsct.model.Request) CourseRequest(org.cpsolver.studentsct.model.CourseRequest) FreeTimeRequest(org.cpsolver.studentsct.model.FreeTimeRequest) Student(org.cpsolver.studentsct.model.Student) OnlineSectioningSelection(org.cpsolver.studentsct.online.selection.OnlineSectioningSelection) Section(org.cpsolver.studentsct.model.Section) Offering(org.cpsolver.studentsct.model.Offering) TimeOverlapsCounter(org.cpsolver.studentsct.extension.TimeOverlapsCounter) CourseRequest(org.cpsolver.studentsct.model.CourseRequest) AssignmentMap(org.cpsolver.ifs.assignment.AssignmentMap) BranchBoundNeighbour(org.cpsolver.studentsct.heuristics.selection.BranchBoundSelection.BranchBoundNeighbour) Subpart(org.cpsolver.studentsct.model.Subpart) MultiCriteriaBranchAndBoundSuggestions(org.cpsolver.studentsct.online.selection.MultiCriteriaBranchAndBoundSuggestions)

Example 9 with Subpart

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

the class Test method getPercDisbalancedSections.

public double getPercDisbalancedSections(Assignment<Request, Enrollment> assignment, double perc) {
    boolean balanceUnlimited = model().getProperties().getPropertyBoolean("General.BalanceUnlimited", false);
    double disb10Sections = 0, nrSections = 0;
    for (Offering offering : model().getOfferings()) {
        for (Config config : offering.getConfigs()) {
            double enrl = config.getEnrollmentTotalWeight(assignment, null);
            for (Subpart subpart : config.getSubparts()) {
                if (subpart.getSections().size() <= 1)
                    continue;
                nrSections += subpart.getSections().size();
                if (subpart.getLimit() > 0) {
                    // sections have limits -> desired size is section limit
                    // x (total enrollment / total limit)
                    double ratio = enrl / subpart.getLimit();
                    for (Section section : subpart.getSections()) {
                        double desired = ratio * section.getLimit();
                        if (Math.abs(desired - section.getEnrollmentTotalWeight(assignment, null)) >= Math.max(1.0, perc * section.getLimit()))
                            disb10Sections++;
                    }
                } else if (balanceUnlimited) {
                    // enrollment / number of sections
                    for (Section section : subpart.getSections()) {
                        double desired = enrl / subpart.getSections().size();
                        if (Math.abs(desired - section.getEnrollmentTotalWeight(assignment, null)) >= Math.max(1.0, perc * desired))
                            disb10Sections++;
                    }
                }
            }
        }
    }
    return 100.0 * disb10Sections / nrSections;
}
Also used : Config(org.cpsolver.studentsct.model.Config) Subpart(org.cpsolver.studentsct.model.Subpart) Offering(org.cpsolver.studentsct.model.Offering) Section(org.cpsolver.studentsct.model.Section)

Example 10 with Subpart

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

the class StudentChoiceOrder method nrChoices.

private int nrChoices(Config config, int idx, HashSet<Section> sections) {
    if (iFast) {
        int nrChoices = 1;
        for (Subpart subpart : config.getSubparts()) {
            if (subpart.getChildren().isEmpty())
                nrChoices *= subpart.getSections().size();
        }
        return nrChoices;
    }
    if (config.getSubparts().size() == idx) {
        return 1;
    } else {
        Subpart subpart = config.getSubparts().get(idx);
        int choicesThisSubpart = 0;
        for (Section section : subpart.getSections()) {
            if (section.getParent() != null && !sections.contains(section.getParent()))
                continue;
            if (section.isOverlapping(sections))
                continue;
            sections.add(section);
            choicesThisSubpart += nrChoices(config, idx + 1, sections);
            sections.remove(section);
        }
        return choicesThisSubpart;
    }
}
Also used : Subpart(org.cpsolver.studentsct.model.Subpart) Section(org.cpsolver.studentsct.model.Section)

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