Search in sources :

Example 36 with Subpart

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

the class PriorityStudentWeights method main.

/**
 * Test case -- run to see the weights for a few courses
 * @param args program arguments
 */
public static void main(String[] args) {
    PriorityStudentWeights pw = new PriorityStudentWeights(new DataProperties());
    DecimalFormat df = new DecimalFormat("0.000000");
    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 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<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]));
    }
    System.out.println("Disbalanced sections (by 2 / 10 students):");
    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>();
            Subpart x = new Subpart(0, "Lec", "Lec", cfg, null);
            Section a = new Section(0, 10, "x", x, p, null);
            new Section(1, 10, "y", x, p, null);
            sections.add(a);
            a.assigned(assignment, new Enrollment(s.getRequests().get(0), i, cfg, sections, assignment));
            a.assigned(assignment, new Enrollment(s.getRequests().get(0), i, cfg, sections, assignment));
            cfg.getContext(assignment).assigned(assignment, new Enrollment(s.getRequests().get(0), i, cfg, sections, assignment));
            cfg.getContext(assignment).assigned(assignment, new Enrollment(s.getRequests().get(0), i, cfg, sections, assignment));
            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("Same choice sections:");
    pw.iMPP = true;
    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<SctAssignment> other = new HashSet<SctAssignment>();
            other.add(new Section(1, 1, "x", new Subpart(0, "Lec", "Lec", cfg, null), p, null));
            cr.setInitialAssignment(new Enrollment(cr, i, cfg, other, 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("Same time sections:");
    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<SctAssignment> other = new HashSet<SctAssignment>();
            other.add(new Section(1, 1, "x", new Subpart(0, "Lec", "Lec", cfg, null), p, null, new Instructor(1l, null, "Josef Novak", null)));
            cr.setInitialAssignment(new Enrollment(cr, i, cfg, other, 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("Different time sections:");
    Placement q = new Placement(null, new TimeLocation(1, 102, 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);
            Set<SctAssignment> other = new HashSet<SctAssignment>();
            other.add(new Section(1, 1, "x", new Subpart(0, "Lec", "Lec", cfg, null), q, null));
            cr.setInitialAssignment(new Enrollment(cr, i, cfg, other, 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("Two sections, one same choice, one same time:");
    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));
            sections.add(new Section(1, 1, "y", new Subpart(1, "Rec", "Rec", cfg, null), p, null));
            Enrollment e = new Enrollment(cr, i, cfg, sections, assignment);
            Set<SctAssignment> other = new HashSet<SctAssignment>();
            other.add(new Section(2, 1, "x", new Subpart(0, "Lec", "Lec", cfg, null), p, null));
            other.add(new Section(3, 1, "y", new Subpart(1, "Rec", "Rec", cfg, null), p, null, new Instructor(1l, null, "Josef Novak", null)));
            cr.setInitialAssignment(new Enrollment(cr, i, cfg, other, 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]));
    }
}
Also used : TimeLocation(org.cpsolver.coursett.model.TimeLocation) Config(org.cpsolver.studentsct.model.Config) DecimalFormat(java.text.DecimalFormat) DistanceConflict(org.cpsolver.studentsct.extension.DistanceConflict) Instructor(org.cpsolver.studentsct.model.Instructor) 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) Conflict(org.cpsolver.studentsct.extension.StudentQuality.Conflict) Subpart(org.cpsolver.studentsct.model.Subpart) DefaultSingleAssignment(org.cpsolver.ifs.assignment.DefaultSingleAssignment) SctAssignment(org.cpsolver.studentsct.model.SctAssignment)

Example 37 with Subpart

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

the class SuggestionSelection method setRequiredSections.

@Override
public void setRequiredSections(Hashtable<CourseRequest, Set<Section>> requiredSections) {
    iRequiredConfig = new Hashtable<CourseRequest, Config>();
    iRequiredSection = new Hashtable<CourseRequest, Hashtable<Subpart, Section>>();
    if (requiredSections != null) {
        for (Map.Entry<CourseRequest, Set<Section>> entry : requiredSections.entrySet()) {
            Hashtable<Subpart, Section> subSection = new Hashtable<Subpart, Section>();
            iRequiredSection.put(entry.getKey(), subSection);
            for (Section section : entry.getValue()) {
                if (subSection.isEmpty())
                    iRequiredConfig.put(entry.getKey(), section.getSubpart().getConfig());
                subSection.put(section.getSubpart(), section);
            }
        }
    }
}
Also used : CourseRequest(org.cpsolver.studentsct.model.CourseRequest) Set(java.util.Set) Config(org.cpsolver.studentsct.model.Config) Hashtable(java.util.Hashtable) Subpart(org.cpsolver.studentsct.model.Subpart) Map(java.util.Map) Section(org.cpsolver.studentsct.model.Section)

Example 38 with Subpart

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

the class FractionallyUnbalancedWhenNoExpectations method getOverExpected.

@Override
public double getOverExpected(Assignment<Request, Enrollment> assignment, Section section, Request request) {
    Subpart subpart = section.getSubpart();
    if (hasExpectations(subpart) && section.getLimit() > 0)
        return super.getOverExpected(assignment, section, request);
    if (getDisbalance() == null || getDisbalance() < 0.0)
        return 0.0;
    double enrlConfig = request.getWeight() + getEnrollment(assignment, subpart.getConfig(), request);
    int subparts = section.getSubpart().getConfig().getSubparts().size();
    int limit = getLimit(section);
    double enrl = request.getWeight() + getEnrollment(assignment, section, request);
    if (limit > 0) {
        // sections have limits -> desired size is section limit x (total
        // enrollment / total limit)
        double desired = (enrlConfig / getLimit(subpart)) * limit;
        if (enrl - desired >= Math.max(1.0, getDisbalance() * limit)) {
            double max = getMaximum(section, limit);
            return Math.min(max, enrl - desired) / (max * subparts);
        }
    } else if (isBalanceUnlimited()) {
        // unlimited sections -> desired size is total enrollment / number
        // of sections
        double desired = enrlConfig / subpart.getSections().size();
        if (enrl - desired >= Math.max(1.0, getDisbalance() * desired)) {
            double max = getMaximum(section, desired);
            return Math.min(max, enrl - desired) / (max * subparts);
        }
    }
    return 0.0;
}
Also used : Subpart(org.cpsolver.studentsct.model.Subpart)

Example 39 with Subpart

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

the class EqualWeightCriterion method compare.

@Override
public int compare(Assignment<Request, Enrollment> assignment, Enrollment[] current, Enrollment[] best) {
    if (best == null)
        return -1;
    // 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;
    for (int idx = 0; idx < current.length; idx++) {
        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++;
        }
        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 -1;
    if (bestAssignedCourseReq > currentAssignedCourseReq)
        return 1;
    if (currentAssignedPriority < bestAssignedPriority)
        return -1;
    if (bestAssignedPriority < currentAssignedPriority)
        return 1;
    if (currentAssignedAlternativity < bestAssignedAlternativity)
        return -1;
    if (bestAssignedAlternativity < currentAssignedAlternativity)
        return 1;
    // 0.1. allowed, but not available sections
    int bestNotAvailable = 0, currentNotAvailable = 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)
                    bestNotAvailable++;
            }
        }
        if (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)
                    currentNotAvailable++;
            }
        }
    }
    if (bestNotAvailable > currentNotAvailable)
        return -1;
    if (bestNotAvailable < currentNotAvailable)
        return 1;
    // 0.5. avoid course 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].getAssignments() != null && best[idx].getRequest() instanceof CourseRequest) {
                for (int x = 0; x < idx; x++) {
                    if (best[x] != null && best[x].getAssignments() != null && best[x].getRequest() instanceof CourseRequest)
                        bestTimeOverlaps += getModel().getStudentQuality().penalty(StudentQuality.Type.CourseTimeOverlap, best[x], best[idx]);
                }
            }
            if (current[idx] != null && current[idx].getAssignments() != null && current[idx].getRequest() instanceof CourseRequest) {
                for (int x = 0; x < idx; x++) {
                    if (current[x] != null && current[x].getAssignments() != 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 && current[idx].getAssignments() != null && current[idx].isCourseRequest()) {
                currentTimeOverlaps += getModel().getStudentQuality().penalty(StudentQuality.Type.Unavailability, current[idx]);
            }
        }
        if (currentTimeOverlaps < bestTimeOverlaps)
            return -1;
        if (bestTimeOverlaps < currentTimeOverlaps)
            return 1;
    } else if (getModel().getTimeOverlaps() != null) {
        int bestTimeOverlaps = 0, currentTimeOverlaps = 0;
        for (int idx = 0; idx < current.length; idx++) {
            if (best[idx] != null && best[idx].getAssignments() != null && best[idx].getRequest() instanceof CourseRequest) {
                for (int x = 0; x < idx; x++) {
                    if (best[x] != null && best[x].getAssignments() != null && best[x].getRequest() instanceof CourseRequest)
                        bestTimeOverlaps += getModel().getTimeOverlaps().nrConflicts(best[x], best[idx]);
                }
            }
            if (current[idx] != null && current[idx].getAssignments() != null && current[idx].getRequest() instanceof CourseRequest) {
                for (int x = 0; x < idx; x++) {
                    if (current[x] != null && current[x].getAssignments() != 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 && current[idx].getAssignments() != null && current[idx].isCourseRequest()) {
                currentTimeOverlaps += getModel().getTimeOverlaps().nrNotAvailableTimeConflicts(current[idx]);
            }
        }
        if (currentTimeOverlaps < bestTimeOverlaps)
            return -1;
        if (bestTimeOverlaps < currentTimeOverlaps)
            return 1;
    }
    // 1. minimize number of penalties
    double bestPenalties = 0, currentPenalties = 0;
    for (int idx = 0; idx < current.length; idx++) {
        if (best[idx] != null && best[idx].getAssignments() != null && best[idx].isCourseRequest()) {
            for (Section section : best[idx].getSections()) bestPenalties += getModel().getOverExpected(assignment, best, idx, section, best[idx].getRequest());
        }
        if (current[idx] != null && current[idx].getAssignments() != null && current[idx].isCourseRequest()) {
            for (Section section : current[idx].getSections()) currentPenalties += getModel().getOverExpected(assignment, current, idx, section, current[idx].getRequest());
        }
    }
    if (currentPenalties < bestPenalties)
        return -1;
    if (bestPenalties < currentPenalties)
        return 1;
    // 2. best number of assigned requests (including free time requests)
    if (currentAssignedRequests > bestAssignedRequests)
        return -1;
    if (bestAssignedRequests > currentAssignedRequests)
        return 1;
    // 3. maximize selection
    int bestSelected = 0, currentSelected = 0;
    for (int idx = 0; idx < current.length; idx++) {
        Set<Section> preferred = getPreferredSections(getRequest(idx));
        if (preferred != null && !preferred.isEmpty()) {
            if (best[idx] != null && best[idx].getAssignments() != null && best[idx].isCourseRequest()) {
                for (Section section : best[idx].getSections()) if (preferred.contains(section))
                    bestSelected++;
            }
            if (current[idx] != null && current[idx].getAssignments() != null && current[idx].isCourseRequest()) {
                for (Section section : current[idx].getSections()) if (preferred.contains(section))
                    currentSelected++;
            }
        }
    }
    if (currentSelected > bestSelected)
        return -1;
    if (bestSelected > currentSelected)
        return 1;
    // 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 (current[idx] != null && 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 -1;
    if (0.3 * bestSelectedConfigs + 0.7 * bestSelectedSections > 0.3 * currentSelectedConfigs + 0.7 * currentSelectedSections)
        return 1;
    // 3.9 minimize enrollments where the reservation is not followed
    if (currentNotFollowedReservations < bestNotFollowedReservations)
        return -1;
    if (bestNotFollowedReservations < currentNotFollowedReservations)
        return 1;
    // 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 && current[idx].getAssignments() != null) {
            for (Section section : current[idx].getSections()) {
                if (section.isPast())
                    currentPast++;
            }
        }
    }
    if (currentPast < bestPast)
        return -1;
    if (bestPast < currentPast)
        return 1;
    // 4-5. student 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 && best[idx].getAssignments() != null) {
                    bestQuality += iQalityWeights[type.ordinal()] * getModel().getStudentQuality().penalty(type, best[idx]);
                    for (int x = 0; x < idx; x++) {
                        if (best[x] != null && best[x].getAssignments() != null)
                            bestQuality += iQalityWeights[type.ordinal()] * getModel().getStudentQuality().penalty(type, best[x], best[idx]);
                    }
                }
                if (current[idx] != null && current[idx].getAssignments() != null) {
                    currentQuality += iQalityWeights[type.ordinal()] * getModel().getStudentQuality().penalty(type, current[idx]);
                    for (int x = 0; x < idx; x++) {
                        if (current[x] != null && current[x].getAssignments() != null)
                            currentQuality += iQalityWeights[type.ordinal()] * getModel().getStudentQuality().penalty(type, current[x], current[idx]);
                    }
                }
            }
        }
        if (currentQuality < bestQuality)
            return -1;
        if (bestQuality < currentQuality)
            return 1;
    } 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 && best[idx].getAssignments() != null) {
                    for (int x = 0; x < idx; x++) {
                        if (best[x] != null && best[x].getAssignments() != 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 && current[idx].getAssignments() != null) {
                    for (int x = 0; x < idx; x++) {
                        if (current[x] != null && current[x].getAssignments() != 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 && current[idx].getAssignments() != null && current[idx].isCourseRequest()) {
                    currentTimeOverlaps += getModel().getTimeOverlaps().nrNotAvailableTimeConflicts(current[idx]);
                }
            }
            if (currentTimeOverlaps < bestTimeOverlaps)
                return -1;
            if (bestTimeOverlaps < currentTimeOverlaps)
                return 1;
        }
        // 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 && best[idx].getAssignments() != null) {
                    bestDistanceConf += getModel().getDistanceConflict().nrConflicts(best[idx]);
                    for (int x = 0; x < idx; x++) {
                        if (best[x] != null && best[x].getAssignments() != null)
                            bestDistanceConf += getModel().getDistanceConflict().nrConflicts(best[x], best[idx]);
                    }
                }
                if (current[idx] != null && current[idx].getAssignments() != null) {
                    currentDistanceConf += getModel().getDistanceConflict().nrConflicts(current[idx]);
                    for (int x = 0; x < idx; x++) {
                        if (current[x] != null && current[x].getAssignments() != null)
                            currentDistanceConf += getModel().getDistanceConflict().nrConflicts(current[x], current[idx]);
                    }
                }
            }
            if (currentDistanceConf < bestDistanceConf)
                return -1;
            if (bestDistanceConf < currentDistanceConf)
                return 1;
        }
    }
    // 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 && best[idx].getAssignments() != null) {
            for (Section section : best[idx].getSections()) {
                if (!section.hasTime())
                    bestNoTime++;
                if (section.isOnline())
                    bestOnline++;
            }
        }
        if (current[idx] != null && current[idx].getAssignments() != null) {
            for (Section section : current[idx].getSections()) {
                if (!section.hasTime())
                    currentNoTime++;
                if (section.isOnline())
                    currentOnline++;
            }
        }
    }
    if (currentNoTime < bestNoTime)
        return -1;
    if (bestNoTime < currentNoTime)
        return 1;
    if (currentOnline < bestOnline)
        return -1;
    if (bestOnline < currentOnline)
        return 1;
    // 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 && best[idx].getAssignments() != 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 && current[idx].getAssignments() != null) {
            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 -1;
    if (bestUnavailableSizeFraction < currentUnavailableSizeFraction)
        return 1;
    // 8. average penalty sections
    double bestPenalty = 0.0, currentPenalty = 0.0;
    for (int idx = 0; idx < current.length; idx++) {
        if (best[idx] != null && best[idx].getAssignments() != null) {
            for (Section section : best[idx].getSections()) bestPenalty += section.getPenalty() / best[idx].getSections().size();
        }
        if (current[idx] != null && current[idx].getAssignments() != null) {
            for (Section section : current[idx].getSections()) currentPenalty += section.getPenalty() / current[idx].getSections().size();
        }
    }
    if (currentPenalty < bestPenalty)
        return -1;
    if (bestPenalty < currentPenalty)
        return 1;
    return 0;
}
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 Subpart

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

the class MultiCriteriaBranchAndBoundSelection method setRequiredSections.

@Override
public void setRequiredSections(Hashtable<CourseRequest, Set<Section>> requiredSections) {
    if (requiredSections != null) {
        for (Map.Entry<CourseRequest, Set<Section>> entry : requiredSections.entrySet()) {
            Hashtable<Subpart, Section> subSection = new Hashtable<Subpart, Section>();
            iRequiredSection.put(entry.getKey(), subSection);
            for (Section section : entry.getValue()) {
                if (subSection.isEmpty())
                    iRequiredConfig.put(entry.getKey(), section.getSubpart().getConfig());
                subSection.put(section.getSubpart(), section);
            }
        }
    }
}
Also used : CourseRequest(org.cpsolver.studentsct.model.CourseRequest) Set(java.util.Set) Subpart(org.cpsolver.studentsct.model.Subpart) Hashtable(java.util.Hashtable) HashMap(java.util.HashMap) Map(java.util.Map) 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