Search in sources :

Example 16 with Enrollment

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

the class AssignInitialSelection method selectNeighbour.

@Override
public Neighbour<Request, Enrollment> selectNeighbour(Solution<Request, Enrollment> solution) {
    Student student = null;
    while ((student = nextStudent()) != null) {
        Progress.getInstance(solution.getModel()).incProgress();
        if (student.nrAssignedRequests(solution.getAssignment()) > 0)
            continue;
        Neighbour<Request, Enrollment> neighbour = new InitialSelection(student, solution.getAssignment()).select();
        if (neighbour != null)
            return neighbour;
    }
    return null;
}
Also used : Request(org.cpsolver.studentsct.model.Request) Enrollment(org.cpsolver.studentsct.model.Enrollment) Student(org.cpsolver.studentsct.model.Student)

Example 17 with Enrollment

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

the class BacktrackSelection method selectNeighbour.

@Override
public Neighbour<Request, Enrollment> selectNeighbour(Solution<Request, Enrollment> solution) {
    Request request = null;
    while ((request = nextRequest()) != null) {
        Progress.getInstance(solution.getModel()).incProgress();
        Neighbour<Request, Enrollment> n = iRBtNSel.selectNeighbour(solution, request);
        if (n != null && n.value(solution.getAssignment()) <= 0.0)
            return n;
    }
    return null;
}
Also used : Request(org.cpsolver.studentsct.model.Request) Enrollment(org.cpsolver.studentsct.model.Enrollment)

Example 18 with Enrollment

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

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

the class CourseConflictTable method createTable.

/**
     * Create report
     * 
     * @param assignment current assignment
     * @param includeLastLikeStudents
     *            true, if last-like students should be included (i.e.,
     *            {@link Student#isDummy()} is true)
     * @param includeRealStudents
     *            true, if real students should be included (i.e.,
     *            {@link Student#isDummy()} is false)
     * @param useAmPm use 12-hour format
     * @return report as comma separated text file
     */
@SuppressWarnings("unchecked")
public CSVFile createTable(Assignment<Request, Enrollment> assignment, boolean includeLastLikeStudents, boolean includeRealStudents, boolean useAmPm) {
    CSVFile csv = new CSVFile();
    csv.setHeader(new CSVFile.CSVField[] { new CSVFile.CSVField("UnasgnCrs"), new CSVFile.CSVField("ConflCrs"), new CSVFile.CSVField("NrStud"), new CSVFile.CSVField("StudWeight"), new CSVFile.CSVField("NoAlt"), new CSVFile.CSVField("Reason") });
    HashMap<Course, HashMap<Course, Object[]>> unassignedCourseTable = new HashMap<Course, HashMap<Course, Object[]>>();
    for (Request request : new ArrayList<Request>(getModel().unassignedVariables(assignment))) {
        if (request.getStudent().isDummy() && !includeLastLikeStudents)
            continue;
        if (!request.getStudent().isDummy() && !includeRealStudents)
            continue;
        if (request instanceof CourseRequest) {
            CourseRequest courseRequest = (CourseRequest) request;
            if (courseRequest.getStudent().isComplete(assignment))
                continue;
            List<Enrollment> values = courseRequest.values(assignment);
            SectionLimit limitConstraint = null;
            for (GlobalConstraint<Request, Enrollment> c : getModel().globalConstraints()) {
                if (c instanceof SectionLimit) {
                    limitConstraint = (SectionLimit) c;
                    break;
                }
            }
            if (limitConstraint == null) {
                limitConstraint = new SectionLimit(new DataProperties());
                limitConstraint.setModel(getModel());
            }
            List<Enrollment> availableValues = new ArrayList<Enrollment>(values.size());
            for (Enrollment enrollment : values) {
                if (!limitConstraint.inConflict(assignment, enrollment))
                    availableValues.add(enrollment);
            }
            if (availableValues.isEmpty()) {
                Course course = courseRequest.getCourses().get(0);
                HashMap<Course, Object[]> conflictCourseTable = unassignedCourseTable.get(course);
                if (conflictCourseTable == null) {
                    conflictCourseTable = new HashMap<Course, Object[]>();
                    unassignedCourseTable.put(course, conflictCourseTable);
                }
                Object[] weight = conflictCourseTable.get(course);
                double nrStud = (weight == null ? 0.0 : ((Double) weight[0]).doubleValue()) + 1.0;
                double nrStudW = (weight == null ? 0.0 : ((Double) weight[1]).doubleValue()) + request.getWeight();
                boolean noAlt = (weight == null ? true : ((Boolean) weight[2]).booleanValue());
                HashSet<String> expl = (weight == null ? new HashSet<String>() : (HashSet<String>) weight[3]);
                expl.add(course.getName() + " n/a");
                conflictCourseTable.put(course, new Object[] { new Double(nrStud), new Double(nrStudW), new Boolean(noAlt), expl });
            }
            for (Enrollment enrollment : availableValues) {
                Set<Enrollment> conflicts = getModel().conflictValues(assignment, enrollment);
                if (conflicts.isEmpty()) {
                    sLog.warn("Request " + courseRequest + " of student " + courseRequest.getStudent() + " not assigned, however, no conflicts were returned.");
                    assignment.assign(0, enrollment);
                    break;
                }
                Course course = null;
                for (Course c : courseRequest.getCourses()) {
                    if (c.getOffering().equals(enrollment.getConfig().getOffering())) {
                        course = c;
                        break;
                    }
                }
                if (course == null) {
                    sLog.warn("Course not found for request " + courseRequest + " of student " + courseRequest.getStudent() + ".");
                    continue;
                }
                HashMap<Course, Object[]> conflictCourseTable = unassignedCourseTable.get(course);
                if (conflictCourseTable == null) {
                    conflictCourseTable = new HashMap<Course, Object[]>();
                    unassignedCourseTable.put(course, conflictCourseTable);
                }
                for (Enrollment conflict : conflicts) {
                    if (conflict.variable() instanceof CourseRequest) {
                        CourseRequest conflictCourseRequest = (CourseRequest) conflict.variable();
                        Course conflictCourse = null;
                        for (Course c : conflictCourseRequest.getCourses()) {
                            if (c.getOffering().equals(conflict.getConfig().getOffering())) {
                                conflictCourse = c;
                                break;
                            }
                        }
                        if (conflictCourse == null) {
                            sLog.warn("Course not found for request " + conflictCourseRequest + " of student " + conflictCourseRequest.getStudent() + ".");
                            continue;
                        }
                        double weightThisConflict = request.getWeight() / availableValues.size() / conflicts.size();
                        double partThisConflict = 1.0 / availableValues.size() / conflicts.size();
                        Object[] weight = conflictCourseTable.get(conflictCourse);
                        double nrStud = (weight == null ? 0.0 : ((Double) weight[0]).doubleValue()) + partThisConflict;
                        double nrStudW = (weight == null ? 0.0 : ((Double) weight[1]).doubleValue()) + weightThisConflict;
                        boolean noAlt = (weight == null ? areInHardConfict(assignment, request, conflict.getRequest()) : ((Boolean) weight[2]).booleanValue());
                        HashSet<String> expl = (weight == null ? new HashSet<String>() : (HashSet<String>) weight[3]);
                        expl.addAll(explanations(assignment, enrollment, conflict, useAmPm));
                        conflictCourseTable.put(conflictCourse, new Object[] { new Double(nrStud), new Double(nrStudW), new Boolean(noAlt), expl });
                    }
                }
            }
        }
    }
    for (Map.Entry<Course, HashMap<Course, Object[]>> entry : unassignedCourseTable.entrySet()) {
        Course unassignedCourse = entry.getKey();
        HashMap<Course, Object[]> conflictCourseTable = entry.getValue();
        for (Map.Entry<Course, Object[]> entry2 : conflictCourseTable.entrySet()) {
            Course conflictCourse = entry2.getKey();
            Object[] weight = entry2.getValue();
            HashSet<String> expl = (HashSet<String>) weight[3];
            String explStr = "";
            for (Iterator<String> k = new TreeSet<String>(expl).iterator(); k.hasNext(); ) explStr += k.next() + (k.hasNext() ? "\n" : "");
            csv.addLine(new CSVFile.CSVField[] { new CSVFile.CSVField(unassignedCourse.getName()), new CSVFile.CSVField(conflictCourse.getName()), new CSVFile.CSVField(sDF.format(weight[0])), new CSVFile.CSVField(sDF.format(weight[1])), new CSVFile.CSVField(((Boolean) weight[2]).booleanValue() ? "Y" : "N"), new CSVFile.CSVField(explStr) });
        }
    }
    if (csv.getLines() != null)
        Collections.sort(csv.getLines(), new Comparator<CSVFile.CSVLine>() {

            @Override
            public int compare(CSVFile.CSVLine l1, CSVFile.CSVLine l2) {
                // int cmp =
                // l2.getField(3).toString().compareTo(l1.getField(3).toString());
                // if (cmp!=0) return cmp;
                int cmp = Double.compare(l2.getField(2).toDouble(), l1.getField(2).toDouble());
                if (cmp != 0)
                    return cmp;
                cmp = l1.getField(0).toString().compareTo(l2.getField(0).toString());
                if (cmp != 0)
                    return cmp;
                return l1.getField(1).toString().compareTo(l2.getField(1).toString());
            }
        });
    return csv;
}
Also used : CSVFile(org.cpsolver.ifs.util.CSVFile) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) DataProperties(org.cpsolver.ifs.util.DataProperties) Comparator(java.util.Comparator) Enrollment(org.cpsolver.studentsct.model.Enrollment) Course(org.cpsolver.studentsct.model.Course) HashSet(java.util.HashSet) Request(org.cpsolver.studentsct.model.Request) CourseRequest(org.cpsolver.studentsct.model.CourseRequest) GlobalConstraint(org.cpsolver.ifs.model.GlobalConstraint) CourseRequest(org.cpsolver.studentsct.model.CourseRequest) SectionLimit(org.cpsolver.studentsct.constraint.SectionLimit) HashMap(java.util.HashMap) Map(java.util.Map)

Example 20 with Enrollment

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

the class DistanceConflictTable method createTable.

/**
     * Create report
     * 
     * @param assignment current assignment
     * @param includeLastLikeStudents
     *            true, if last-like students should be included (i.e.,
     *            {@link Student#isDummy()} is true)
     * @param includeRealStudents
     *            true, if real students should be included (i.e.,
     *            {@link Student#isDummy()} is false)
     * @param useAmPm use 12-hour format
     * @return report as comma separated text file
     */
public CSVFile createTable(Assignment<Request, Enrollment> assignment, boolean includeLastLikeStudents, boolean includeRealStudents, boolean useAmPm) {
    CSVFile csv = new CSVFile();
    csv.setHeader(new CSVFile.CSVField[] { new CSVFile.CSVField("Course"), new CSVFile.CSVField("Total\nConflicts"), new CSVFile.CSVField("Class"), new CSVFile.CSVField("Meeting Time"), new CSVFile.CSVField("Room"), new CSVFile.CSVField("Distance\nConflicts"), new CSVFile.CSVField("% of Total\nConflicts"), new CSVFile.CSVField("Conflicting\nClass"), new CSVFile.CSVField("Conflicting\nMeeting Time"), new CSVFile.CSVField("Conflicting\nRoom"), new CSVFile.CSVField("Distance [m]"), new CSVFile.CSVField("Distance [min]"), new CSVFile.CSVField("Joined\nConflicts"), new CSVFile.CSVField("% of Total\nConflicts") });
    Set<Conflict> confs = new HashSet<Conflict>();
    for (Request r1 : getModel().variables()) {
        Enrollment e1 = assignment.getValue(r1);
        if (e1 == null || !(r1 instanceof CourseRequest))
            continue;
        confs.addAll(iDC.conflicts(e1));
        for (Request r2 : r1.getStudent().getRequests()) {
            Enrollment e2 = assignment.getValue(r2);
            if (e2 == null || r1.getId() >= r2.getId() || !(r2 instanceof CourseRequest))
                continue;
            confs.addAll(iDC.conflicts(e1, e2));
        }
    }
    HashMap<Course, Set<Long>> totals = new HashMap<Course, Set<Long>>();
    HashMap<CourseSection, Map<CourseSection, Double>> conflictingPairs = new HashMap<CourseSection, Map<CourseSection, Double>>();
    HashMap<CourseSection, Set<Long>> sectionOverlaps = new HashMap<CourseSection, Set<Long>>();
    for (Conflict conflict : confs) {
        if (conflict.getStudent().isDummy() && !includeLastLikeStudents)
            continue;
        if (!conflict.getStudent().isDummy() && !includeRealStudents)
            continue;
        Section s1 = conflict.getS1(), s2 = conflict.getS2();
        Course c1 = null, c2 = null;
        Request r1 = null, r2 = null;
        for (Request request : conflict.getStudent().getRequests()) {
            Enrollment enrollment = assignment.getValue(request);
            if (enrollment == null || !enrollment.isCourseRequest())
                continue;
            if (c1 == null && enrollment.getAssignments().contains(s1)) {
                c1 = enrollment.getCourse();
                r1 = request;
                Set<Long> total = totals.get(enrollment.getCourse());
                if (total == null) {
                    total = new HashSet<Long>();
                    totals.put(enrollment.getCourse(), total);
                }
                total.add(enrollment.getStudent().getId());
            }
            if (c2 == null && enrollment.getAssignments().contains(s2)) {
                c2 = enrollment.getCourse();
                r2 = request;
                Set<Long> total = totals.get(enrollment.getCourse());
                if (total == null) {
                    total = new HashSet<Long>();
                    totals.put(enrollment.getCourse(), total);
                }
                total.add(enrollment.getStudent().getId());
            }
        }
        if (c1 == null) {
            sLog.error("Unable to find a course for " + s1);
            continue;
        }
        if (c2 == null) {
            sLog.error("Unable to find a course for " + s2);
            continue;
        }
        CourseSection a = new CourseSection(c1, s1);
        CourseSection b = new CourseSection(c2, s2);
        Set<Long> total = sectionOverlaps.get(a);
        if (total == null) {
            total = new HashSet<Long>();
            sectionOverlaps.put(a, total);
        }
        total.add(r1.getStudent().getId());
        Map<CourseSection, Double> pair = conflictingPairs.get(a);
        if (pair == null) {
            pair = new HashMap<CourseSection, Double>();
            conflictingPairs.put(a, pair);
        }
        Double prev = pair.get(b);
        pair.put(b, r2.getWeight() + (prev == null ? 0.0 : prev.doubleValue()));
        total = sectionOverlaps.get(b);
        if (total == null) {
            total = new HashSet<Long>();
            sectionOverlaps.put(b, total);
        }
        total.add(r2.getStudent().getId());
        pair = conflictingPairs.get(b);
        if (pair == null) {
            pair = new HashMap<CourseSection, Double>();
            conflictingPairs.put(b, pair);
        }
        prev = pair.get(a);
        pair.put(a, r1.getWeight() + (prev == null ? 0.0 : prev.doubleValue()));
    }
    Comparator<Course> courseComparator = new Comparator<Course>() {

        @Override
        public int compare(Course a, Course b) {
            int cmp = a.getName().compareTo(b.getName());
            if (cmp != 0)
                return cmp;
            return a.getId() < b.getId() ? -1 : a.getId() == b.getId() ? 0 : 1;
        }
    };
    Comparator<Section> sectionComparator = new Comparator<Section>() {

        @Override
        public int compare(Section a, Section b) {
            int cmp = a.getSubpart().getConfig().getOffering().getName().compareTo(b.getSubpart().getConfig().getOffering().getName());
            if (cmp != 0)
                return cmp;
            cmp = a.getSubpart().getInstructionalType().compareTo(b.getSubpart().getInstructionalType());
            // cmp = a.getName().compareTo(b.getName());
            if (cmp != 0)
                return cmp;
            return a.getId() < b.getId() ? -1 : a.getId() == b.getId() ? 0 : 1;
        }
    };
    TreeSet<Course> courses = new TreeSet<Course>(courseComparator);
    courses.addAll(totals.keySet());
    for (Course course : courses) {
        Set<Long> total = totals.get(course);
        TreeSet<Section> sections = new TreeSet<Section>(sectionComparator);
        for (Map.Entry<CourseSection, Set<Long>> entry : sectionOverlaps.entrySet()) if (course.equals(entry.getKey().getCourse()))
            sections.add(entry.getKey().getSection());
        boolean firstCourse = true;
        for (Section section : sections) {
            Set<Long> sectionOverlap = sectionOverlaps.get(new CourseSection(course, section));
            Map<CourseSection, Double> pair = conflictingPairs.get(new CourseSection(course, section));
            boolean firstClass = true;
            String rooms = "";
            if (section.getRooms() != null)
                for (RoomLocation r : section.getRooms()) {
                    if (!rooms.isEmpty())
                        rooms += "\n";
                    rooms += r.getName();
                }
            for (CourseSection other : new TreeSet<CourseSection>(pair.keySet())) {
                List<CSVFile.CSVField> line = new ArrayList<CSVFile.CSVField>();
                line.add(new CSVFile.CSVField(firstCourse && firstClass ? course.getName() : ""));
                line.add(new CSVFile.CSVField(firstCourse && firstClass ? total.size() : ""));
                line.add(new CSVFile.CSVField(firstClass ? section.getSubpart().getName() + " " + section.getName(course.getId()) : ""));
                line.add(new CSVFile.CSVField(firstClass ? section.getTime() == null ? "" : section.getTime().getDayHeader() + " " + section.getTime().getStartTimeHeader(useAmPm) + " - " + section.getTime().getEndTimeHeader(useAmPm) : ""));
                line.add(new CSVFile.CSVField(firstClass ? rooms : ""));
                line.add(new CSVFile.CSVField(firstClass && sectionOverlap != null ? String.valueOf(sectionOverlap.size()) : ""));
                line.add(new CSVFile.CSVField(firstClass && sectionOverlap != null ? sDF2.format(((double) sectionOverlap.size()) / total.size()) : ""));
                line.add(new CSVFile.CSVField(other.getCourse().getName() + " " + other.getSection().getSubpart().getName() + " " + other.getSection().getName(other.getCourse().getId())));
                line.add(new CSVFile.CSVField(other.getSection().getTime().getDayHeader() + " " + other.getSection().getTime().getStartTimeHeader(useAmPm) + " - " + other.getSection().getTime().getEndTimeHeader(useAmPm)));
                String or = "";
                if (other.getSection().getRooms() != null)
                    for (RoomLocation r : other.getSection().getRooms()) {
                        if (!or.isEmpty())
                            or += "\n";
                        or += r.getName();
                    }
                line.add(new CSVFile.CSVField(or));
                line.add(new CSVFile.CSVField(sDF2.format(Placement.getDistanceInMeters(iDM, section.getPlacement(), other.getSection().getPlacement()))));
                line.add(new CSVFile.CSVField(String.valueOf(Placement.getDistanceInMinutes(iDM, section.getPlacement(), other.getSection().getPlacement()))));
                line.add(new CSVFile.CSVField(sDF1.format(pair.get(other))));
                line.add(new CSVFile.CSVField(sDF2.format(pair.get(other) / total.size())));
                csv.addLine(line);
                firstClass = false;
            }
            firstCourse = false;
        }
        csv.addLine();
    }
    return csv;
}
Also used : CSVFile(org.cpsolver.ifs.util.CSVFile) Set(java.util.Set) TreeSet(java.util.TreeSet) HashSet(java.util.HashSet) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) Comparator(java.util.Comparator) TreeSet(java.util.TreeSet) Enrollment(org.cpsolver.studentsct.model.Enrollment) Course(org.cpsolver.studentsct.model.Course) HashSet(java.util.HashSet) RoomLocation(org.cpsolver.coursett.model.RoomLocation) CourseRequest(org.cpsolver.studentsct.model.CourseRequest) Request(org.cpsolver.studentsct.model.Request) Section(org.cpsolver.studentsct.model.Section) CourseRequest(org.cpsolver.studentsct.model.CourseRequest) Conflict(org.cpsolver.studentsct.extension.DistanceConflict.Conflict) DistanceConflict(org.cpsolver.studentsct.extension.DistanceConflict) HashMap(java.util.HashMap) Map(java.util.Map)

Aggregations

Enrollment (org.cpsolver.studentsct.model.Enrollment)59 Request (org.cpsolver.studentsct.model.Request)47 CourseRequest (org.cpsolver.studentsct.model.CourseRequest)36 ArrayList (java.util.ArrayList)19 Section (org.cpsolver.studentsct.model.Section)19 HashSet (java.util.HashSet)17 Student (org.cpsolver.studentsct.model.Student)16 FreeTimeRequest (org.cpsolver.studentsct.model.FreeTimeRequest)15 Course (org.cpsolver.studentsct.model.Course)14 HashMap (java.util.HashMap)11 DataProperties (org.cpsolver.ifs.util.DataProperties)9 Config (org.cpsolver.studentsct.model.Config)9 Set (java.util.Set)8 TreeSet (java.util.TreeSet)8 Subpart (org.cpsolver.studentsct.model.Subpart)8 Map (java.util.Map)7 DefaultSingleAssignment (org.cpsolver.ifs.assignment.DefaultSingleAssignment)7 DistanceConflict (org.cpsolver.studentsct.extension.DistanceConflict)7 Offering (org.cpsolver.studentsct.model.Offering)7 File (java.io.File)6