Search in sources :

Example 36 with CourseRequest

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

the class OriginalStudentWeights method main.

/**
 * Test case -- run to see the weights for a few courses
 * @param args program arguments
 */
public static void main(String[] args) {
    OriginalStudentWeights pw = new OriginalStudentWeights(new DataProperties());
    DecimalFormat df = new DecimalFormat("0.000");
    Student s = new Student(0l);
    new CourseRequest(1l, 0, false, s, ToolBox.toList(new Course(1, "A", "1", new Offering(0, "A")), new Course(1, "A", "2", new Offering(0, "A")), new Course(1, "A", "3", new Offering(0, "A"))), false, null);
    new CourseRequest(2l, 1, false, s, ToolBox.toList(new Course(1, "B", "1", new Offering(0, "B")), new Course(1, "B", "2", new Offering(0, "B")), new Course(1, "B", "3", new Offering(0, "B"))), false, null);
    new CourseRequest(3l, 2, false, s, ToolBox.toList(new Course(1, "C", "1", new Offering(0, "C")), new Course(1, "C", "2", new Offering(0, "C")), new Course(1, "C", "3", new Offering(0, "C"))), false, null);
    new CourseRequest(4l, 3, false, s, ToolBox.toList(new Course(1, "D", "1", new Offering(0, "D")), new Course(1, "D", "2", new Offering(0, "D")), new Course(1, "D", "3", new Offering(0, "D"))), false, null);
    new CourseRequest(5l, 4, false, s, ToolBox.toList(new Course(1, "E", "1", new Offering(0, "E")), new Course(1, "E", "2", new Offering(0, "E")), new Course(1, "E", "3", new Offering(0, "E"))), false, null);
    new CourseRequest(6l, 5, true, s, ToolBox.toList(new Course(1, "F", "1", new Offering(0, "F")), new Course(1, "F", "2", new Offering(0, "F")), new Course(1, "F", "3", new Offering(0, "F"))), false, null);
    new CourseRequest(7l, 6, true, s, ToolBox.toList(new Course(1, "G", "1", new Offering(0, "G")), new Course(1, "G", "2", new Offering(0, "G")), new Course(1, "G", "3", new Offering(0, "G"))), false, null);
    Assignment<Request, Enrollment> assignment = new DefaultSingleAssignment<Request, Enrollment>();
    Placement p = new Placement(null, new TimeLocation(1, 90, 12, 0, 0, null, null, new BitSet(), 10), new ArrayList<RoomLocation>());
    for (Request r : s.getRequests()) {
        CourseRequest cr = (CourseRequest) r;
        double[] w = new double[] { 0.0, 0.0, 0.0 };
        for (int i = 0; i < cr.getCourses().size(); i++) {
            Config cfg = new Config(0l, -1, "", cr.getCourses().get(i).getOffering());
            Set<SctAssignment> sections = new HashSet<SctAssignment>();
            sections.add(new Section(0, 1, "x", new Subpart(0, "Lec", "Lec", cfg, null), p, null));
            Enrollment e = new Enrollment(cr, i, cfg, sections, assignment);
            w[i] = pw.getWeight(assignment, e, null, null);
        }
        System.out.println(cr + ": " + df.format(w[0]) + "  " + df.format(w[1]) + "  " + df.format(w[2]));
    }
    System.out.println("With one distance conflict:");
    for (Request r : s.getRequests()) {
        CourseRequest cr = (CourseRequest) r;
        double[] w = new double[] { 0.0, 0.0, 0.0 };
        for (int i = 0; i < cr.getCourses().size(); i++) {
            Config cfg = new Config(0l, -1, "", cr.getCourses().get(i).getOffering());
            Set<SctAssignment> sections = new HashSet<SctAssignment>();
            sections.add(new Section(0, 1, "x", new Subpart(0, "Lec", "Lec", cfg, null), p, null));
            Enrollment e = new Enrollment(cr, i, cfg, sections, assignment);
            Set<DistanceConflict.Conflict> dc = new HashSet<DistanceConflict.Conflict>();
            dc.add(new DistanceConflict.Conflict(s, e, (Section) sections.iterator().next(), e, (Section) sections.iterator().next()));
            w[i] = pw.getWeight(assignment, e, dc, null);
        }
        System.out.println(cr + ": " + df.format(w[0]) + "  " + df.format(w[1]) + "  " + df.format(w[2]));
    }
    System.out.println("With two distance conflicts:");
    for (Request r : s.getRequests()) {
        CourseRequest cr = (CourseRequest) r;
        double[] w = new double[] { 0.0, 0.0, 0.0 };
        for (int i = 0; i < cr.getCourses().size(); i++) {
            Config cfg = new Config(0l, -1, "", cr.getCourses().get(i).getOffering());
            Set<SctAssignment> sections = new HashSet<SctAssignment>();
            sections.add(new Section(0, 1, "x", new Subpart(0, "Lec", "Lec", cfg, null), p, null));
            Enrollment e = new Enrollment(cr, i, cfg, sections, assignment);
            Set<DistanceConflict.Conflict> dc = new HashSet<DistanceConflict.Conflict>();
            dc.add(new DistanceConflict.Conflict(s, e, (Section) sections.iterator().next(), e, (Section) sections.iterator().next()));
            dc.add(new DistanceConflict.Conflict(s, e, (Section) sections.iterator().next(), e, new Section(1, 1, "x", new Subpart(0, "Lec", "Lec", cfg, null), p, null)));
            w[i] = pw.getWeight(assignment, e, dc, null);
        }
        System.out.println(cr + ": " + df.format(w[0]) + "  " + df.format(w[1]) + "  " + df.format(w[2]));
    }
    System.out.println("With 25% time overlapping conflicts:");
    for (Request r : s.getRequests()) {
        CourseRequest cr = (CourseRequest) r;
        double[] w = new double[] { 0.0, 0.0, 0.0 };
        for (int i = 0; i < cr.getCourses().size(); i++) {
            Config cfg = new Config(0l, -1, "", cr.getCourses().get(i).getOffering());
            Set<SctAssignment> sections = new HashSet<SctAssignment>();
            sections.add(new Section(0, 1, "x", new Subpart(0, "Lec", "Lec", cfg, null), p, null));
            Enrollment e = new Enrollment(cr, i, cfg, sections, assignment);
            Set<TimeOverlapsCounter.Conflict> toc = new HashSet<TimeOverlapsCounter.Conflict>();
            toc.add(new TimeOverlapsCounter.Conflict(s, 3, e, sections.iterator().next(), e, sections.iterator().next()));
            w[i] = pw.getWeight(assignment, e, null, toc);
        }
        System.out.println(cr + ": " + df.format(w[0]) + "  " + df.format(w[1]) + "  " + df.format(w[2]));
    }
}
Also used : TimeLocation(org.cpsolver.coursett.model.TimeLocation) Config(org.cpsolver.studentsct.model.Config) DecimalFormat(java.text.DecimalFormat) DistanceConflict(org.cpsolver.studentsct.extension.DistanceConflict) DataProperties(org.cpsolver.ifs.util.DataProperties) Placement(org.cpsolver.coursett.model.Placement) Enrollment(org.cpsolver.studentsct.model.Enrollment) Course(org.cpsolver.studentsct.model.Course) HashSet(java.util.HashSet) RoomLocation(org.cpsolver.coursett.model.RoomLocation) Request(org.cpsolver.studentsct.model.Request) CourseRequest(org.cpsolver.studentsct.model.CourseRequest) BitSet(java.util.BitSet) Student(org.cpsolver.studentsct.model.Student) Offering(org.cpsolver.studentsct.model.Offering) Section(org.cpsolver.studentsct.model.Section) TimeOverlapsCounter(org.cpsolver.studentsct.extension.TimeOverlapsCounter) CourseRequest(org.cpsolver.studentsct.model.CourseRequest) DistanceConflict(org.cpsolver.studentsct.extension.DistanceConflict) Subpart(org.cpsolver.studentsct.model.Subpart) DefaultSingleAssignment(org.cpsolver.ifs.assignment.DefaultSingleAssignment) SctAssignment(org.cpsolver.studentsct.model.SctAssignment)

Example 37 with CourseRequest

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

the class OriginalStudentWeights method getBound.

@Override
public double getBound(Request request) {
    double w = getWeight(request) * Math.pow(iInitialWeight, (request.getInitialAssignment() == null ? 0 : 1));
    if (request instanceof CourseRequest) {
        CourseRequest cr = (CourseRequest) request;
        w *= Math.pow(iSelectedWeight, cr.getSelectedChoices().isEmpty() ? 0 : 1);
        w *= Math.pow(iWaitlistedWeight, cr.getWaitlistedChoices().isEmpty() ? 0 : 1);
        w *= normalizePenalty(cr.getMinPenalty());
    }
    return w;
}
Also used : CourseRequest(org.cpsolver.studentsct.model.CourseRequest)

Example 38 with CourseRequest

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

the class ResectioningWeights method getWeight.

@Override
public double getWeight(Assignment<Request, Enrollment> assignment, Enrollment enrollment) {
    double weight = super.getWeight(assignment, enrollment);
    if (enrollment.isCourseRequest() && enrollment.getAssignments() != null && iLastSectionProvider != null) {
        int sameChoice = 0;
        int sameTime = 0;
        int sameRooms = 0;
        int sameName = 0;
        for (Section section : enrollment.getSections()) {
            if (iLastSectionProvider.sameLastChoice(section))
                sameChoice++;
            if (iLastSectionProvider.sameLastTime(section))
                sameTime++;
            if (iLastSectionProvider.sameLastRoom(section))
                sameRooms++;
            if (iLastSectionProvider.sameLastName(section, enrollment.getCourse()))
                sameName++;
        }
        CourseRequest cr = (CourseRequest) enrollment.getRequest();
        if (sameChoice == 0 && !cr.getSelectedChoices().isEmpty()) {
            for (Section section : enrollment.getSections()) {
                if (cr.isSelected(section)) {
                    sameChoice++;
                    continue;
                }
            }
        }
        double size = enrollment.getAssignments().size();
        double sameChoiceFraction = (size - sameChoice) / size;
        double sameTimeFraction = (size - sameTime) / size;
        double sameRoomsFraction = (size - sameRooms) / size;
        double sameNameFraction = (size - sameName) / size;
        double base = getBaseWeight(assignment, enrollment);
        weight -= sameChoiceFraction * base * iSameChoiceFactor;
        weight -= sameTimeFraction * base * iSameTimeFactor;
        weight -= sameRoomsFraction * base * iSameRoomsFactor;
        weight -= sameNameFraction * base * iSameNameFactor;
    }
    return weight;
}
Also used : CourseRequest(org.cpsolver.studentsct.model.CourseRequest) Section(org.cpsolver.studentsct.model.Section)

Example 39 with CourseRequest

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

the class EqualWeightCriterion method canImprove.

@Override
public boolean canImprove(Assignment<Request, Enrollment> assignment, int maxIdx, Enrollment[] current, Enrollment[] best) {
    // 0. best number of assigned course requests (including alternativity &
    // priority)
    int currentAssignedCourseReq = 0, bestAssignedCourseReq = 0;
    int currentAssignedRequests = 0, bestAssignedRequests = 0;
    int currentAssignedPriority = 0, bestAssignedPriority = 0;
    int currentAssignedAlternativity = 0, bestAssignedAlternativity = 0;
    int currentNotFollowedReservations = 0, bestNotFollowedReservations = 0;
    int alt = 0;
    for (int idx = 0; idx < current.length; idx++) {
        if (idx < maxIdx) {
            if (current[idx] != null && current[idx].getAssignments() != null) {
                currentAssignedRequests++;
                if (current[idx].isCourseRequest())
                    currentAssignedCourseReq++;
                currentAssignedPriority += current[idx].getTruePriority() * current[idx].getTruePriority();
                currentAssignedAlternativity += (current[idx].getRequest().isAlternative() ? 1 : 0);
                if (current[idx].getTruePriority() < current[idx].getPriority())
                    currentNotFollowedReservations++;
            } else if (!isFreeTime(idx) && !getRequest(idx).isAlternative()) {
                alt++;
            }
        } else {
            if (!getRequest(idx).isAlternative()) {
                currentAssignedRequests++;
                if (!isFreeTime(idx))
                    currentAssignedCourseReq++;
            } else if (alt > 0) {
                currentAssignedRequests++;
                currentAssignedCourseReq++;
                alt--;
                currentAssignedAlternativity++;
            }
        }
        if (best[idx] != null && best[idx].getAssignments() != null) {
            bestAssignedRequests++;
            if (best[idx].isCourseRequest())
                bestAssignedCourseReq++;
            bestAssignedPriority += best[idx].getTruePriority() * best[idx].getTruePriority();
            bestAssignedAlternativity += (best[idx].getRequest().isAlternative() ? 1 : 0);
            if (best[idx].getTruePriority() < best[idx].getPriority())
                bestNotFollowedReservations++;
        }
    }
    if (currentAssignedCourseReq > bestAssignedCourseReq)
        return true;
    if (bestAssignedCourseReq > currentAssignedCourseReq)
        return false;
    if (currentAssignedPriority < bestAssignedPriority)
        return true;
    if (bestAssignedPriority < currentAssignedPriority)
        return false;
    if (currentAssignedAlternativity < bestAssignedAlternativity)
        return true;
    if (bestAssignedAlternativity < currentAssignedAlternativity)
        return false;
    // 0.1. allowed, but not available sections
    int notAvailable = 0;
    for (int idx = 0; idx < current.length; idx++) {
        if (best[idx] != null && best[idx].getAssignments() != null && best[idx].getRequest() instanceof CourseRequest && best[idx].getReservation() != null && best[idx].getReservation().canAssignOverLimit()) {
            for (Section section : best[idx].getSections()) {
                if (section.getLimit() == 0)
                    notAvailable++;
            }
        }
        if (idx < maxIdx && current[idx] != null && current[idx].getAssignments() != null && current[idx].getRequest() instanceof CourseRequest && current[idx].getReservation() != null && current[idx].getReservation().canAssignOverLimit()) {
            for (Section section : current[idx].getSections()) {
                if (section.getLimit() == 0)
                    notAvailable--;
            }
        }
    }
    if (notAvailable > 0) {
        return true;
    }
    // 0.5. avoid course time overlaps & unavailabilities
    if (getModel().getStudentQuality() != null) {
        int bestTimeOverlaps = 0, currentTimeOverlaps = 0;
        for (int idx = 0; idx < current.length; idx++) {
            if (best[idx] != null && best[idx].getRequest() instanceof CourseRequest) {
                for (int x = 0; x < idx; x++) {
                    if (best[x] != null && best[x].getRequest() instanceof CourseRequest)
                        bestTimeOverlaps += getModel().getStudentQuality().penalty(StudentQuality.Type.CourseTimeOverlap, best[x], best[idx]);
                }
            }
            if (current[idx] != null && idx < maxIdx && current[idx].getRequest() instanceof CourseRequest) {
                for (int x = 0; x < idx; x++) {
                    if (current[x] != null && current[x].getRequest() instanceof CourseRequest)
                        currentTimeOverlaps += getModel().getStudentQuality().penalty(StudentQuality.Type.CourseTimeOverlap, current[x], current[idx]);
                }
            }
        }
        for (int idx = 0; idx < current.length; idx++) {
            if (best[idx] != null && best[idx].getAssignments() != null && best[idx].isCourseRequest()) {
                bestTimeOverlaps += getModel().getStudentQuality().penalty(StudentQuality.Type.Unavailability, best[idx]);
            }
            if (current[idx] != null && idx < maxIdx && current[idx].getAssignments() != null && current[idx].isCourseRequest()) {
                currentTimeOverlaps += getModel().getStudentQuality().penalty(StudentQuality.Type.Unavailability, current[idx]);
            }
        }
        if (currentTimeOverlaps < bestTimeOverlaps)
            return true;
        if (bestTimeOverlaps < currentTimeOverlaps)
            return false;
    } else if (getModel().getTimeOverlaps() != null) {
        int bestTimeOverlaps = 0, currentTimeOverlaps = 0;
        for (int idx = 0; idx < current.length; idx++) {
            if (best[idx] != null && best[idx].getRequest() instanceof CourseRequest) {
                for (int x = 0; x < idx; x++) {
                    if (best[x] != null && best[x].getRequest() instanceof CourseRequest)
                        bestTimeOverlaps += getModel().getTimeOverlaps().nrConflicts(best[x], best[idx]);
                }
            }
            if (current[idx] != null && idx < maxIdx && current[idx].getRequest() instanceof CourseRequest) {
                for (int x = 0; x < idx; x++) {
                    if (current[x] != null && current[x].getRequest() instanceof CourseRequest)
                        currentTimeOverlaps += getModel().getTimeOverlaps().nrConflicts(current[x], current[idx]);
                }
            }
        }
        for (int idx = 0; idx < current.length; idx++) {
            if (best[idx] != null && best[idx].getAssignments() != null && best[idx].isCourseRequest()) {
                bestTimeOverlaps += getModel().getTimeOverlaps().nrNotAvailableTimeConflicts(best[idx]);
            }
            if (current[idx] != null && idx < maxIdx && current[idx].getAssignments() != null && current[idx].isCourseRequest()) {
                currentTimeOverlaps += getModel().getTimeOverlaps().nrNotAvailableTimeConflicts(current[idx]);
            }
        }
        if (currentTimeOverlaps < bestTimeOverlaps)
            return true;
        if (bestTimeOverlaps < currentTimeOverlaps)
            return false;
    }
    // 1. maximize number of penalties
    double bestPenalties = 0, currentPenalties = 0;
    for (int idx = 0; idx < current.length; idx++) {
        if (best[idx] != null) {
            for (Section section : best[idx].getSections()) bestPenalties += getModel().getOverExpected(assignment, best, idx, section, best[idx].getRequest());
        }
        if (current[idx] != null && idx < maxIdx) {
            for (Section section : current[idx].getSections()) currentPenalties += getModel().getOverExpected(assignment, current, idx, section, current[idx].getRequest());
        }
    }
    if (currentPenalties < bestPenalties)
        return true;
    if (bestPenalties < currentPenalties)
        return false;
    // 2. best number of assigned requests (including free time requests)
    if (currentAssignedRequests > bestAssignedRequests)
        return true;
    if (bestAssignedRequests > currentAssignedRequests)
        return false;
    // 3. maximize selection
    int bestSelected = 0, currentSelected = 0;
    for (int idx = 0; idx < current.length; idx++) {
        if (best[idx] != null && best[idx].isCourseRequest()) {
            Set<Section> preferred = getPreferredSections(best[idx].getRequest());
            if (preferred != null && !preferred.isEmpty()) {
                for (Section section : best[idx].getSections()) if (preferred.contains(section)) {
                    if (idx < maxIdx)
                        bestSelected++;
                } else if (idx >= maxIdx)
                    bestSelected--;
            }
        }
        if (current[idx] != null && idx < maxIdx && current[idx].isCourseRequest()) {
            Set<Section> preferred = getPreferredSections(current[idx].getRequest());
            if (preferred != null && !preferred.isEmpty()) {
                for (Section section : current[idx].getSections()) if (preferred.contains(section))
                    currentSelected++;
            }
        }
    }
    if (currentSelected > bestSelected)
        return true;
    if (bestSelected > currentSelected)
        return false;
    // 3.5 maximize preferences
    double bestSelectedConfigs = 0, currentSelectedConfigs = 0;
    double bestSelectedSections = 0, currentSelectedSections = 0;
    for (int idx = 0; idx < current.length; idx++) {
        if (best[idx] != null && best[idx].getAssignments() != null && best[idx].isCourseRequest()) {
            bestSelectedSections += best[idx].percentSelectedSameSection();
            bestSelectedConfigs += best[idx].percentSelectedSameConfig();
            if (idx >= maxIdx) {
                bestSelectedSections -= 1.0;
                bestSelectedConfigs -= 1.0;
            }
        }
        if (current[idx] != null && idx < maxIdx && current[idx].getAssignments() != null && current[idx].isCourseRequest()) {
            currentSelectedSections += current[idx].percentSelectedSameSection();
            currentSelectedConfigs += current[idx].percentSelectedSameConfig();
        }
    }
    if (0.3 * currentSelectedConfigs + 0.7 * currentSelectedSections > 0.3 * bestSelectedConfigs + 0.7 * bestSelectedSections)
        return true;
    if (0.3 * bestSelectedConfigs + 0.7 * bestSelectedSections > 0.3 * currentSelectedConfigs + 0.7 * currentSelectedSections)
        return false;
    // 3.9 minimize enrollments where the reservation is not followed
    if (currentNotFollowedReservations < bestNotFollowedReservations)
        return true;
    if (bestNotFollowedReservations < currentNotFollowedReservations)
        return false;
    // 3.95 avoid past sections
    int bestPast = 0, currentPast = 0;
    for (int idx = 0; idx < current.length; idx++) {
        if (best[idx] != null && best[idx].getAssignments() != null) {
            for (Section section : best[idx].getSections()) {
                if (section.isPast())
                    bestPast++;
            }
        }
        if (current[idx] != null && idx < maxIdx && current[idx].getAssignments() != null) {
            for (Section section : current[idx].getSections()) {
                if (section.isPast())
                    currentPast++;
            }
        }
    }
    if (currentPast < bestPast)
        return true;
    if (bestPast < currentPast)
        return false;
    // 4-5. solution quality
    if (getModel().getStudentQuality() != null) {
        double bestQuality = 0, currentQuality = 0;
        for (StudentQuality.Type type : StudentQuality.Type.values()) {
            for (int idx = 0; idx < current.length; idx++) {
                if (best[idx] != null) {
                    bestQuality += iQalityWeights[type.ordinal()] * getModel().getStudentQuality().penalty(type, best[idx]);
                    for (int x = 0; x < idx; x++) {
                        if (best[x] != null)
                            bestQuality += iQalityWeights[type.ordinal()] * getModel().getStudentQuality().penalty(type, best[x], best[idx]);
                    }
                }
                if (current[idx] != null && idx < maxIdx) {
                    currentQuality += iQalityWeights[type.ordinal()] * getModel().getStudentQuality().penalty(type, current[idx]);
                    for (int x = 0; x < idx; x++) {
                        if (current[x] != null)
                            currentQuality += iQalityWeights[type.ordinal()] * getModel().getStudentQuality().penalty(type, current[x], current[idx]);
                    }
                }
            }
        }
        if (currentQuality < bestQuality)
            return true;
        if (bestQuality < currentQuality)
            return false;
    } else {
        // 4. avoid time overlaps
        if (getModel().getTimeOverlaps() != null) {
            int bestTimeOverlaps = 0, currentTimeOverlaps = 0;
            for (int idx = 0; idx < current.length; idx++) {
                if (best[idx] != null) {
                    for (int x = 0; x < idx; x++) {
                        if (best[x] != null)
                            bestTimeOverlaps += getModel().getTimeOverlaps().nrConflicts(best[x], best[idx]);
                        else if (getStudent().getRequests().get(x) instanceof FreeTimeRequest)
                            bestTimeOverlaps += getModel().getTimeOverlaps().nrConflicts(((FreeTimeRequest) getStudent().getRequests().get(x)).createEnrollment(), best[idx]);
                    }
                }
                if (current[idx] != null && idx < maxIdx) {
                    for (int x = 0; x < idx; x++) {
                        if (current[x] != null)
                            currentTimeOverlaps += getModel().getTimeOverlaps().nrConflicts(current[x], current[idx]);
                        else if (getStudent().getRequests().get(x) instanceof FreeTimeRequest)
                            currentTimeOverlaps += getModel().getTimeOverlaps().nrConflicts(((FreeTimeRequest) getStudent().getRequests().get(x)).createEnrollment(), current[idx]);
                    }
                }
            }
            for (int idx = 0; idx < current.length; idx++) {
                if (best[idx] != null && best[idx].getAssignments() != null && best[idx].isCourseRequest()) {
                    bestTimeOverlaps += getModel().getTimeOverlaps().nrNotAvailableTimeConflicts(best[idx]);
                }
                if (current[idx] != null && idx < maxIdx && current[idx].getAssignments() != null && current[idx].isCourseRequest()) {
                    currentTimeOverlaps += getModel().getTimeOverlaps().nrNotAvailableTimeConflicts(current[idx]);
                }
            }
            if (currentTimeOverlaps < bestTimeOverlaps)
                return true;
            if (bestTimeOverlaps < currentTimeOverlaps)
                return false;
        }
        // 5. avoid distance conflicts
        if (getModel().getDistanceConflict() != null) {
            int bestDistanceConf = 0, currentDistanceConf = 0;
            for (int idx = 0; idx < current.length; idx++) {
                if (best[idx] != null) {
                    bestDistanceConf += getModel().getDistanceConflict().nrConflicts(best[idx]);
                    for (int x = 0; x < idx; x++) {
                        if (best[x] != null)
                            bestDistanceConf += getModel().getDistanceConflict().nrConflicts(best[x], best[idx]);
                    }
                }
                if (current[idx] != null && idx < maxIdx) {
                    currentDistanceConf += getModel().getDistanceConflict().nrConflicts(current[idx]);
                    for (int x = 0; x < idx; x++) {
                        if (current[x] != null)
                            currentDistanceConf += getModel().getDistanceConflict().nrConflicts(current[x], current[idx]);
                    }
                }
            }
            if (currentDistanceConf < bestDistanceConf)
                return true;
            if (bestDistanceConf < currentDistanceConf)
                return false;
        }
    }
    // 6. avoid no-time and online sections (no-time first, online second)
    int bestNoTime = 0, currentNoTime = 0;
    int bestOnline = 0, currentOnline = 0;
    for (int idx = 0; idx < current.length; idx++) {
        if (best[idx] != null) {
            for (Section section : best[idx].getSections()) {
                if (!section.hasTime())
                    bestNoTime++;
                if (section.isOnline())
                    bestOnline++;
            }
        }
        if (current[idx] != null && idx < maxIdx) {
            for (Section section : current[idx].getSections()) {
                if (!section.hasTime())
                    currentNoTime++;
                if (section.isOnline())
                    currentOnline++;
            }
        }
    }
    if (currentNoTime < bestNoTime)
        return true;
    if (bestNoTime < currentNoTime)
        return false;
    if (currentOnline < bestOnline)
        return true;
    if (bestOnline < currentOnline)
        return false;
    // 7. balance sections
    double bestUnavailableSize = 0.0, currentUnavailableSize = 0.0;
    int bestAltSectionsWithLimit = 0, currentAltSectionsWithLimit = 0;
    for (int idx = 0; idx < current.length; idx++) {
        if (best[idx] != null) {
            for (Section section : best[idx].getSections()) {
                Subpart subpart = section.getSubpart();
                // skip unlimited and single section subparts
                if (subpart.getSections().size() <= 1 || subpart.getLimit() <= 0)
                    continue;
                // average size
                double averageSize = ((double) subpart.getLimit()) / subpart.getSections().size();
                // section is below average
                if (section.getLimit() < averageSize)
                    bestUnavailableSize += (averageSize - section.getLimit()) / averageSize;
                bestAltSectionsWithLimit++;
            }
        }
        if (current[idx] != null && idx < maxIdx) {
            for (Section section : current[idx].getSections()) {
                Subpart subpart = section.getSubpart();
                // skip unlimited and single section subparts
                if (subpart.getSections().size() <= 1 || subpart.getLimit() <= 0)
                    continue;
                // average size
                double averageSize = ((double) subpart.getLimit()) / subpart.getSections().size();
                // section is below average
                if (section.getLimit() < averageSize)
                    currentUnavailableSize += (averageSize - section.getLimit()) / averageSize;
                currentAltSectionsWithLimit++;
            }
        }
    }
    double bestUnavailableSizeFraction = (bestUnavailableSize > 0 ? bestUnavailableSize / bestAltSectionsWithLimit : 0.0);
    double currentUnavailableSizeFraction = (currentUnavailableSize > 0 ? currentUnavailableSize / currentAltSectionsWithLimit : 0.0);
    if (currentUnavailableSizeFraction < bestUnavailableSizeFraction)
        return true;
    if (bestUnavailableSizeFraction < currentUnavailableSizeFraction)
        return false;
    // 8. average penalty sections
    double bestPenalty = 0.0, currentPenalty = 0.0;
    for (int idx = 0; idx < current.length; idx++) {
        if (best[idx] != null) {
            for (Section section : best[idx].getSections()) bestPenalty += section.getPenalty() / best[idx].getSections().size();
            if (idx >= maxIdx && best[idx].isCourseRequest())
                bestPenalty -= ((CourseRequest) best[idx].getRequest()).getMinPenalty();
        }
        if (current[idx] != null && idx < maxIdx) {
            for (Section section : current[idx].getSections()) currentPenalty += section.getPenalty() / current[idx].getSections().size();
        }
    }
    if (currentPenalty < bestPenalty)
        return true;
    if (bestPenalty < currentPenalty)
        return false;
    return true;
}
Also used : FreeTimeRequest(org.cpsolver.studentsct.model.FreeTimeRequest) CourseRequest(org.cpsolver.studentsct.model.CourseRequest) StudentQuality(org.cpsolver.studentsct.extension.StudentQuality) Subpart(org.cpsolver.studentsct.model.Subpart) Section(org.cpsolver.studentsct.model.Section)

Example 40 with CourseRequest

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

the class TableauReport method create.

@Override
public CSVFile create(Assignment<Request, Enrollment> assignment, DataProperties properties) {
    CSVFile csv = new CSVFile();
    boolean simple = properties.getPropertyBoolean("simple", false);
    if (simple) {
        csv.setHeader(new CSVFile.CSVField[] { new CSVFile.CSVField("__Student"), new CSVFile.CSVField("Student"), new CSVFile.CSVField("Course"), new CSVFile.CSVField("Course Limit"), new CSVFile.CSVField("Primary"), new CSVFile.CSVField("Priority"), new CSVFile.CSVField("Alternativity"), new CSVFile.CSVField("Enrolled"), new CSVFile.CSVField("Request Type") });
    } else {
        csv.setHeader(new CSVFile.CSVField[] { new CSVFile.CSVField("__Student"), new CSVFile.CSVField("Student"), new CSVFile.CSVField("Course"), new CSVFile.CSVField("Course Limit"), new CSVFile.CSVField("Controlling Course"), new CSVFile.CSVField("Primary"), new CSVFile.CSVField("Priority"), new CSVFile.CSVField("Alternativity"), new CSVFile.CSVField("Enrolled"), new CSVFile.CSVField("Credits"), new CSVFile.CSVField("Sections"), new CSVFile.CSVField("Preferred Sections"), new CSVFile.CSVField("Required Sections"), new CSVFile.CSVField("Instructional Method"), new CSVFile.CSVField("Preferred Instructional Methods"), new CSVFile.CSVField("Required Instructional Methods"), new CSVFile.CSVField("Request Type") });
    }
    for (Student student : getModel().getStudents()) {
        if (student.isDummy())
            continue;
        int regPriority = 1, altPriority = 1;
        for (Request r : student.getRequests()) {
            if (r instanceof CourseRequest) {
                CourseRequest cr = (CourseRequest) r;
                Enrollment e = cr.getAssignment(assignment);
                int primary = (cr.isAlternative() ? 0 : 1);
                int priority = 0;
                if (cr.isAlternative())
                    priority = altPriority++;
                else
                    priority = regPriority++;
                int alternativity = 0;
                for (Course course : cr.getCourses()) {
                    int enrolled = (e != null && e.getCourse().equals(course) ? 1 : 0);
                    String sect = null;
                    if (e != null && e.getCourse().equals(course)) {
                        sect = "";
                        Set<String> added = new HashSet<String>();
                        for (Section s : e.getSections()) {
                            String x = s.getName(e.getCourse().getId());
                            if (x.indexOf('-') > 0)
                                x = x.substring(0, x.indexOf('-'));
                            if (added.add(x))
                                sect += (sect.isEmpty() ? "" : ",") + x;
                        }
                    }
                    String imR = "", sctR = "";
                    Set<String> addedR = new HashSet<String>();
                    for (Choice ch : cr.getRequiredChoices()) {
                        if (course.getOffering().equals(ch.getOffering())) {
                            if (ch.getConfigId() != null) {
                                for (Config cfg : ch.getOffering().getConfigs()) {
                                    if (ch.getConfigId().equals(cfg.getId())) {
                                        String im = cfg.getInstructionalMethodReference();
                                        if (im != null && addedR.add(im))
                                            imR += (imR.isEmpty() ? "" : ",") + im;
                                    }
                                }
                            }
                            if (ch.getSectionId() != null) {
                                String x = ch.getOffering().getSection(ch.getSectionId()).getName(course.getId());
                                if (x.indexOf('-') > 0)
                                    x = x.substring(0, x.indexOf('-'));
                                if (addedR.add(x))
                                    sctR += (sctR.isEmpty() ? "" : ",") + x;
                            }
                        }
                    }
                    for (Reservation rs : cr.getReservations(course)) {
                        if (rs.mustBeUsed()) {
                            for (Map.Entry<Subpart, Set<Section>> ent : rs.getSections().entrySet()) {
                                for (Section s : ent.getValue()) {
                                    String x = s.getName(course.getId());
                                    if (x.indexOf('-') > 0)
                                        x = x.substring(0, x.indexOf('-'));
                                    if (addedR.add(x))
                                        sctR += (sctR.isEmpty() ? "" : ",") + x;
                                }
                            }
                            if (rs.getSections().isEmpty()) {
                                for (Config cfg : rs.getConfigs()) {
                                    String im = cfg.getInstructionalMethodReference();
                                    if (im != null && addedR.add(im))
                                        imR += (imR.isEmpty() ? "" : ",") + im;
                                }
                            }
                        }
                    }
                    String imP = "", sctP = "";
                    for (Choice ch : cr.getSelectedChoices()) {
                        Set<String> added = new HashSet<String>();
                        if (course.getOffering().equals(ch.getOffering())) {
                            if (ch.getConfigId() != null) {
                                for (Config cfg : ch.getOffering().getConfigs()) {
                                    if (ch.getConfigId().equals(cfg.getId())) {
                                        String im = cfg.getInstructionalMethodReference();
                                        if (im != null && added.add(im))
                                            imP += (imP.isEmpty() ? "" : ",") + im;
                                    }
                                }
                            }
                            if (ch.getSectionId() != null) {
                                String x = ch.getOffering().getSection(ch.getSectionId()).getName(course.getId());
                                if (x.indexOf('-') > 0)
                                    x = x.substring(0, x.indexOf('-'));
                                if (added.add(x))
                                    sctP += (sctP.isEmpty() ? "" : ",") + x;
                            }
                        }
                    }
                    if (simple)
                        csv.addLine(new CSVFile.CSVField[] { new CSVFile.CSVField(student.getId()), new CSVFile.CSVField(student.getExternalId()), new CSVFile.CSVField(course.getName()), new CSVFile.CSVField(course.getLimit() < 0 ? null : course.getLimit()), new CSVFile.CSVField(primary == 1 ? "Yes" : "No"), new CSVFile.CSVField(priority), new CSVFile.CSVField(alternativity), new CSVFile.CSVField(enrolled == 1 ? "Yes" : "No"), new CSVFile.CSVField(cr.getRequestPriority() == null ? "" : cr.getRequestPriority().name()) });
                    else
                        csv.addLine(new CSVFile.CSVField[] { new CSVFile.CSVField(student.getId()), new CSVFile.CSVField(student.getExternalId()), new CSVFile.CSVField(course.getName()), new CSVFile.CSVField(course.getLimit() < 0 ? null : course.getLimit()), new CSVFile.CSVField(course.getOffering().getCourses().size() <= 1 ? null : course.getOffering().getName()), new CSVFile.CSVField(primary == 1 ? "Yes" : "No"), new CSVFile.CSVField(priority), new CSVFile.CSVField(alternativity), new CSVFile.CSVField(enrolled == 1 ? "Yes" : "No"), new CSVFile.CSVField(enrolled == 1 ? e.getCredit() : course.getCreditValue() == null ? 0f : course.getCreditValue()), new CSVFile.CSVField(sect), new CSVFile.CSVField(sctP), new CSVFile.CSVField(sctR), new CSVFile.CSVField(e != null ? e.getConfig().getInstructionalMethodReference() : null), new CSVFile.CSVField(imP), new CSVFile.CSVField(imR), new CSVFile.CSVField(cr.getRequestPriority() == null ? "" : cr.getRequestPriority().name()) });
                    alternativity++;
                }
            }
        }
    }
    return csv;
}
Also used : CSVFile(org.cpsolver.ifs.util.CSVFile) Choice(org.cpsolver.studentsct.model.Choice) Set(java.util.Set) HashSet(java.util.HashSet) Config(org.cpsolver.studentsct.model.Config) CourseRequest(org.cpsolver.studentsct.model.CourseRequest) Request(org.cpsolver.studentsct.model.Request) Student(org.cpsolver.studentsct.model.Student) Section(org.cpsolver.studentsct.model.Section) Reservation(org.cpsolver.studentsct.reservation.Reservation) CourseRequest(org.cpsolver.studentsct.model.CourseRequest) Subpart(org.cpsolver.studentsct.model.Subpart) Enrollment(org.cpsolver.studentsct.model.Enrollment) Course(org.cpsolver.studentsct.model.Course) Map(java.util.Map) HashSet(java.util.HashSet)

Aggregations

CourseRequest (org.cpsolver.studentsct.model.CourseRequest)67 Request (org.cpsolver.studentsct.model.Request)51 Enrollment (org.cpsolver.studentsct.model.Enrollment)37 Section (org.cpsolver.studentsct.model.Section)36 Course (org.cpsolver.studentsct.model.Course)26 FreeTimeRequest (org.cpsolver.studentsct.model.FreeTimeRequest)21 Subpart (org.cpsolver.studentsct.model.Subpart)21 ArrayList (java.util.ArrayList)20 HashSet (java.util.HashSet)18 Student (org.cpsolver.studentsct.model.Student)17 HashMap (java.util.HashMap)15 Config (org.cpsolver.studentsct.model.Config)13 Map (java.util.Map)11 Offering (org.cpsolver.studentsct.model.Offering)10 CSVFile (org.cpsolver.ifs.util.CSVFile)9 Set (java.util.Set)8 DistanceConflict (org.cpsolver.studentsct.extension.DistanceConflict)7 TreeSet (java.util.TreeSet)6 Constraint (org.cpsolver.ifs.model.Constraint)6 StudentQuality (org.cpsolver.studentsct.extension.StudentQuality)6