Search in sources :

Example 16 with TimeLocation

use of org.cpsolver.coursett.model.TimeLocation in project cpsolver by UniTime.

the class CourseRequest method computeEnrollments.

/**
     * Recursive computation of enrollments
     * 
     * @param enrollments
     *            list of enrollments to be returned
     * @param priority
     *            zero for the course, one for the first alternative, two for the second alternative
     * @param penalty
     *            penalty of the selected sections
     * @param course
     *            selected course
     * @param config
     *            selected configuration
     * @param sections
     *            sections selected so far
     * @param idx
     *            index of the subparts (a section of 0..idx-1 subparts has been
     *            already selected)
     * @param availableOnly
     *            only use available sections
     * @param skipSameTime
     *            for each possible times, pick only one section
     * @param selectedOnly
     *            select only sections that are selected (
     *            {@link CourseRequest#isSelected(Section)} is true)
     * @param random
     *            pick sections in a random order (useful when limit is used)
     * @param limit
     *            when above zero, limit the number of selected enrollments to
     *            this limit
     * @param reservations
     *            list of applicable reservations
     */
private void computeEnrollments(Assignment<Request, Enrollment> assignment, Collection<Enrollment> enrollments, int priority, double penalty, Course course, Config config, HashSet<Section> sections, int idx, boolean availableOnly, boolean skipSameTime, boolean selectedOnly, boolean random, int limit) {
    if (limit > 0 && enrollments.size() >= limit)
        return;
    if (idx == 0) {
        // run only once for each configuration
        boolean canOverLimit = false;
        if (availableOnly) {
            for (Reservation r : getReservations(course)) {
                if (!r.canBatchAssignOverLimit())
                    continue;
                if (!r.getConfigs().isEmpty() && !r.getConfigs().contains(config))
                    continue;
                if (r.getReservedAvailableSpace(assignment, this) < getWeight())
                    continue;
                canOverLimit = true;
                break;
            }
        }
        if (!canOverLimit) {
            if (availableOnly && config.getLimit() >= 0 && ConfigLimit.getEnrollmentWeight(assignment, config, this) > config.getLimit())
                return;
            if (availableOnly && course.getLimit() >= 0 && CourseLimit.getEnrollmentWeight(assignment, course, this) > course.getLimit())
                return;
            if (config.getOffering().hasReservations()) {
                boolean hasReservation = false, hasConfigReservation = false, reservationMustBeUsed = false;
                for (Reservation r : getReservations(course)) {
                    if (r.mustBeUsed())
                        reservationMustBeUsed = true;
                    if (availableOnly && r.getReservedAvailableSpace(assignment, this) < getWeight())
                        continue;
                    if (r.getConfigs().isEmpty()) {
                        hasReservation = true;
                    } else if (r.getConfigs().contains(config)) {
                        hasReservation = true;
                        hasConfigReservation = true;
                    }
                }
                if (!hasConfigReservation && config.getTotalUnreservedSpace() < getWeight())
                    return;
                if (!hasReservation && config.getOffering().getTotalUnreservedSpace() < getWeight())
                    return;
                if (availableOnly && !hasReservation && config.getOffering().getUnreservedSpace(assignment, this) < getWeight())
                    return;
                if (availableOnly && !hasConfigReservation && config.getUnreservedSpace(assignment, this) < getWeight())
                    return;
                if (!hasReservation && reservationMustBeUsed)
                    return;
            }
        }
    }
    if (config.getSubparts().size() == idx) {
        if (skipSameTime && sSameTimePrecise) {
            boolean waitListedOrSelected = false;
            if (!getSelectedChoices().isEmpty() || !getWaitlistedChoices().isEmpty()) {
                for (Section section : sections) {
                    if (isWaitlisted(section) || isSelected(section)) {
                        waitListedOrSelected = true;
                        break;
                    }
                }
            }
            if (!waitListedOrSelected) {
                for (Enrollment enrollment : enrollments) {
                    if (sameTimes(enrollment.getSections(), sections))
                        return;
                }
            }
        }
        if (!config.getOffering().hasReservations()) {
            enrollments.add(new Enrollment(this, priority, null, config, new HashSet<SctAssignment>(sections), null));
        } else {
            Enrollment e = new Enrollment(this, priority, null, config, new HashSet<SctAssignment>(sections), null);
            boolean mustHaveReservation = config.getOffering().getTotalUnreservedSpace() < getWeight();
            boolean mustHaveConfigReservation = config.getTotalUnreservedSpace() < getWeight();
            boolean mustHaveSectionReservation = false;
            for (Section s : sections) {
                if (s.getTotalUnreservedSpace() < getWeight()) {
                    mustHaveSectionReservation = true;
                    break;
                }
            }
            boolean canOverLimit = false;
            if (availableOnly) {
                for (Reservation r : getReservations(course)) {
                    if (!r.canBatchAssignOverLimit() || !r.isIncluded(e))
                        continue;
                    if (r.getReservedAvailableSpace(assignment, this) < getWeight())
                        continue;
                    enrollments.add(new Enrollment(this, priority, null, config, new HashSet<SctAssignment>(sections), r));
                    canOverLimit = true;
                }
            }
            if (!canOverLimit) {
                boolean reservationMustBeUsed = false;
                reservations: for (Reservation r : (availableOnly ? getSortedReservations(assignment, course) : getReservations(course))) {
                    if (r.mustBeUsed())
                        reservationMustBeUsed = true;
                    if (!r.isIncluded(e))
                        continue;
                    if (availableOnly && r.getReservedAvailableSpace(assignment, this) < getWeight())
                        continue;
                    if (mustHaveConfigReservation && r.getConfigs().isEmpty())
                        continue;
                    if (mustHaveSectionReservation)
                        for (Section s : sections) if (r.getSections(s.getSubpart()) == null && s.getTotalUnreservedSpace() < getWeight())
                            continue reservations;
                    enrollments.add(new Enrollment(this, priority, null, config, new HashSet<SctAssignment>(sections), r));
                    // only one available reservation suffice (the best matching one)
                    if (availableOnly)
                        return;
                }
                // a case w/o reservation
                if (!(mustHaveReservation || mustHaveConfigReservation || mustHaveSectionReservation) && !(availableOnly && config.getOffering().getUnreservedSpace(assignment, this) < getWeight()) && !reservationMustBeUsed) {
                    enrollments.add(new Enrollment(this, (getReservations(course).isEmpty() ? 0 : 1) + priority, null, config, new HashSet<SctAssignment>(sections), null));
                }
            }
        }
    } else {
        Subpart subpart = config.getSubparts().get(idx);
        HashSet<TimeLocation> times = (skipSameTime ? new HashSet<TimeLocation>() : null);
        List<Section> sectionsThisSubpart = subpart.getSections();
        if (skipSameTime) {
            sectionsThisSubpart = new ArrayList<Section>(subpart.getSections());
            Collections.sort(sectionsThisSubpart, new AssignmentComparator<Section, Request, Enrollment>(assignment));
        }
        List<Section> matchingSectionsThisSubpart = new ArrayList<Section>(subpart.getSections().size());
        boolean hasChildren = !subpart.getChildren().isEmpty();
        for (Section section : sectionsThisSubpart) {
            if (section.isCancelled())
                continue;
            if (getInitialAssignment() != null && (getModel() != null && ((StudentSectioningModel) getModel()).getKeepInitialAssignments()) && !getInitialAssignment().getAssignments().contains(section))
                continue;
            if (section.getParent() != null && !sections.contains(section.getParent()))
                continue;
            if (section.isOverlapping(sections))
                continue;
            if (selectedOnly && !isSelected(section))
                continue;
            if (!getStudent().isAvailable(section)) {
                boolean canOverlap = false;
                for (Reservation r : getReservations(course)) {
                    if (!r.isAllowOverlap())
                        continue;
                    if (r.getSections(subpart) != null && !r.getSections(subpart).contains(section))
                        continue;
                    if (r.getReservedAvailableSpace(assignment, this) < getWeight())
                        continue;
                    canOverlap = true;
                    break;
                }
                if (!canOverlap)
                    continue;
            }
            boolean canOverLimit = false;
            if (availableOnly) {
                for (Reservation r : getReservations(course)) {
                    if (!r.canBatchAssignOverLimit())
                        continue;
                    if (r.getSections(subpart) != null && !r.getSections(subpart).contains(section))
                        continue;
                    if (r.getReservedAvailableSpace(assignment, this) < getWeight())
                        continue;
                    canOverLimit = true;
                    break;
                }
            }
            if (!canOverLimit) {
                if (availableOnly && section.getLimit() >= 0 && SectionLimit.getEnrollmentWeight(assignment, section, this) > section.getLimit())
                    continue;
                if (config.getOffering().hasReservations()) {
                    boolean hasReservation = false, hasSectionReservation = false, reservationMustBeUsed = false;
                    for (Reservation r : getReservations(course)) {
                        if (r.mustBeUsed())
                            reservationMustBeUsed = true;
                        if (availableOnly && r.getReservedAvailableSpace(assignment, this) < getWeight())
                            continue;
                        if (r.getSections(subpart) == null) {
                            hasReservation = true;
                        } else if (r.getSections(subpart).contains(section)) {
                            hasReservation = true;
                            hasSectionReservation = true;
                        }
                    }
                    if (!hasSectionReservation && section.getTotalUnreservedSpace() < getWeight())
                        continue;
                    if (availableOnly && !hasSectionReservation && section.getUnreservedSpace(assignment, this) < getWeight())
                        continue;
                    if (!hasReservation && reservationMustBeUsed)
                        continue;
                }
            }
            if (skipSameTime && section.getTime() != null && !hasChildren && !times.add(section.getTime()) && !isSelected(section) && !isWaitlisted(section) && (section.getIgnoreConflictWithSectionIds() == null || section.getIgnoreConflictWithSectionIds().isEmpty()))
                continue;
            matchingSectionsThisSubpart.add(section);
        }
        if (random || limit > 0) {
            sectionsThisSubpart = new ArrayList<Section>(sectionsThisSubpart);
            Collections.shuffle(sectionsThisSubpart);
        }
        int i = 0;
        for (Section section : matchingSectionsThisSubpart) {
            sections.add(section);
            computeEnrollments(assignment, enrollments, priority, penalty + section.getPenalty(), course, config, sections, idx + 1, availableOnly, skipSameTime, selectedOnly, random, limit < 0 ? limit : Math.max(1, limit * (1 + i) / matchingSectionsThisSubpart.size()));
            sections.remove(section);
            i++;
        }
    }
}
Also used : TimeLocation(org.cpsolver.coursett.model.TimeLocation) ArrayList(java.util.ArrayList) Reservation(org.cpsolver.studentsct.reservation.Reservation) StudentSectioningModel(org.cpsolver.studentsct.StudentSectioningModel) HashSet(java.util.HashSet)

Example 17 with TimeLocation

use of org.cpsolver.coursett.model.TimeLocation in project cpsolver by UniTime.

the class StudentLuchBreak method nolunch.

public boolean nolunch(Placement p1, Placement p2) {
    if (p1 == null || p2 == null || overlaps(p1, p2))
        return false;
    if (p1.variable().isCommitted() && p2.variable().isCommitted())
        return false;
    TimeLocation t1 = p1.getTimeLocation(), t2 = p2.getTimeLocation();
    if (!t1.shareDays(t2) || !t1.shareWeeks(t2))
        return false;
    int s1 = t1.getStartSlot(), s2 = t2.getStartSlot();
    int e1 = t1.getStartSlot() + t1.getNrSlotsPerMeeting(), e2 = t2.getStartSlot() + t2.getNrSlotsPerMeeting();
    if (e1 + iLunchLength > s2 && e2 + iLunchLength > s1 && e1 > iLunchStart && iLunchEnd > s1 && e2 > iLunchStart && iLunchEnd > s2)
        return true;
    return false;
}
Also used : TimeLocation(org.cpsolver.coursett.model.TimeLocation)

Example 18 with TimeLocation

use of org.cpsolver.coursett.model.TimeLocation in project cpsolver by UniTime.

the class UselessHalfHours method countUselessSlotsHalfHours.

/** Number of useless half hours for this room 
     * @param rc room constraint assignment context
     * @param placement placement that is being considered
     * @return number of useless slots caused by the given placement
     **/
protected static int countUselessSlotsHalfHours(RoomConstraintContext rc, Placement placement) {
    int ret = 0;
    TimeLocation time = placement.getTimeLocation();
    int slot = time.getStartSlot() % Constants.SLOTS_PER_DAY;
    int days = time.getDayCode();
    for (int d = 0; d < Constants.NR_DAYS; d++) {
        if ((Constants.DAY_CODES[d] & days) == 0)
            continue;
        if (isUselessBefore(rc, d * Constants.SLOTS_PER_DAY + slot - 6, placement))
            ret++;
        if (isUselessAfter(rc, d * Constants.SLOTS_PER_DAY + slot + time.getNrSlotsPerMeeting(), placement))
            ret++;
        if (time.getNrSlotsPerMeeting() == 6 && isUseless(rc, d * Constants.SLOTS_PER_DAY + slot, placement))
            ret--;
    }
    return ret;
}
Also used : TimeLocation(org.cpsolver.coursett.model.TimeLocation)

Example 19 with TimeLocation

use of org.cpsolver.coursett.model.TimeLocation in project cpsolver by UniTime.

the class DistanceConflict method inConflict.

/**
     * Return true if the given two sections are in distance conflict. This
     * means that the sections are back-to-back and that they are placed in
     * locations that are two far.
     * 
     * @param s1
     *            a section
     * @param s2
     *            a section
     * @return true, if the given sections are in a distance conflict
     */
public boolean inConflict(Section s1, Section s2) {
    if (s1.getPlacement() == null || s2.getPlacement() == null)
        return false;
    TimeLocation t1 = s1.getTime();
    TimeLocation t2 = s2.getTime();
    if (!t1.shareDays(t2) || !t1.shareWeeks(t2))
        return false;
    int a1 = t1.getStartSlot(), a2 = t2.getStartSlot();
    if (getDistanceMetric().doComputeDistanceConflictsBetweenNonBTBClasses()) {
        if (a1 + t1.getNrSlotsPerMeeting() <= a2) {
            int dist = getDistanceInMinutes(s1.getPlacement(), s2.getPlacement());
            if (dist > t1.getBreakTime() + Constants.SLOT_LENGTH_MIN * (a2 - a1 - t1.getLength()))
                return true;
        } else if (a2 + t2.getNrSlotsPerMeeting() <= a1) {
            int dist = getDistanceInMinutes(s1.getPlacement(), s2.getPlacement());
            if (dist > t2.getBreakTime() + Constants.SLOT_LENGTH_MIN * (a1 - a2 - t2.getLength()))
                return true;
        }
    } else {
        if (a1 + t1.getNrSlotsPerMeeting() == a2) {
            int dist = getDistanceInMinutes(s1.getPlacement(), s2.getPlacement());
            if (dist > t1.getBreakTime())
                return true;
        } else if (a2 + t2.getNrSlotsPerMeeting() == a1) {
            int dist = getDistanceInMinutes(s1.getPlacement(), s2.getPlacement());
            if (dist > t2.getBreakTime())
                return true;
        }
    }
    return false;
}
Also used : TimeLocation(org.cpsolver.coursett.model.TimeLocation)

Example 20 with TimeLocation

use of org.cpsolver.coursett.model.TimeLocation in project cpsolver by UniTime.

the class Test method printSomeStuff.

/** Create info.txt with some more information about the problem 
     * @param solution current solution
     * @throws IOException an exception that may be thrown
     **/
public static void printSomeStuff(Solution<Lecture, Placement> solution) throws IOException {
    TimetableModel model = (TimetableModel) solution.getModel();
    Assignment<Lecture, Placement> assignment = solution.getAssignment();
    File outDir = new File(model.getProperties().getProperty("General.Output", "."));
    PrintWriter pw = new PrintWriter(new FileWriter(outDir.toString() + File.separator + "info.txt"));
    PrintWriter pwi = new PrintWriter(new FileWriter(outDir.toString() + File.separator + "info.csv"));
    String name = new File(model.getProperties().getProperty("General.Input")).getName();
    pwi.println("Instance," + name.substring(0, name.lastIndexOf('.')));
    pw.println("Solution info: " + ToolBox.dict2string(solution.getInfo(), 1));
    pw.println("Bounds: " + ToolBox.dict2string(model.getBounds(assignment), 1));
    Map<String, String> info = solution.getInfo();
    for (String key : new TreeSet<String>(info.keySet())) {
        if (key.equals("Memory usage"))
            continue;
        if (key.equals("Iteration"))
            continue;
        if (key.equals("Time"))
            continue;
        String value = info.get(key);
        if (value.indexOf(' ') > 0)
            value = value.substring(0, value.indexOf(' '));
        pwi.println(key + "," + value);
    }
    printRoomInfo(pw, model, assignment);
    printClassInfo(pw, model);
    long nrValues = 0;
    long nrTimes = 0;
    long nrRooms = 0;
    double totalMaxNormTimePref = 0.0;
    double totalMinNormTimePref = 0.0;
    double totalNormTimePref = 0.0;
    int totalMaxRoomPref = 0;
    int totalMinRoomPref = 0;
    int totalRoomPref = 0;
    long nrStudentEnrls = 0;
    long nrInevitableStudentConflicts = 0;
    long nrJenrls = 0;
    int nrHalfHours = 0;
    int nrMeetings = 0;
    int totalMinLimit = 0;
    int totalMaxLimit = 0;
    long nrReqRooms = 0;
    int nrSingleValueVariables = 0;
    int nrSingleTimeVariables = 0;
    int nrSingleRoomVariables = 0;
    long totalAvailableMinRoomSize = 0;
    long totalAvailableMaxRoomSize = 0;
    long totalRoomSize = 0;
    long nrOneOrMoreRoomVariables = 0;
    long nrOneRoomVariables = 0;
    HashSet<Student> students = new HashSet<Student>();
    HashSet<Long> offerings = new HashSet<Long>();
    HashSet<Long> configs = new HashSet<Long>();
    HashSet<Long> subparts = new HashSet<Long>();
    int[] sizeLimits = new int[] { 0, 25, 50, 75, 100, 150, 200, 400 };
    int[] nrRoomsOfSize = new int[sizeLimits.length];
    int[] minRoomOfSize = new int[sizeLimits.length];
    int[] maxRoomOfSize = new int[sizeLimits.length];
    int[] totalUsedSlots = new int[sizeLimits.length];
    int[] totalUsedSeats = new int[sizeLimits.length];
    int[] totalUsedSeats2 = new int[sizeLimits.length];
    int firstDaySlot = model.getProperties().getPropertyInt("General.FirstDaySlot", Constants.DAY_SLOTS_FIRST);
    int lastDaySlot = model.getProperties().getPropertyInt("General.LastDaySlot", Constants.DAY_SLOTS_LAST);
    int firstWorkDay = model.getProperties().getPropertyInt("General.FirstWorkDay", 0);
    int lastWorkDay = model.getProperties().getPropertyInt("General.LastWorkDay", Constants.NR_DAYS_WEEK - 1);
    for (Lecture lect : model.variables()) {
        if (lect.getConfiguration() != null) {
            offerings.add(lect.getConfiguration().getOfferingId());
            configs.add(lect.getConfiguration().getConfigId());
        }
        subparts.add(lect.getSchedulingSubpartId());
        nrStudentEnrls += (lect.students() == null ? 0 : lect.students().size());
        students.addAll(lect.students());
        nrValues += lect.values(solution.getAssignment()).size();
        nrReqRooms += lect.getNrRooms();
        for (RoomLocation room : lect.roomLocations()) if (room.getPreference() < Constants.sPreferenceLevelProhibited / 2)
            nrRooms++;
        for (TimeLocation time : lect.timeLocations()) if (time.getPreference() < Constants.sPreferenceLevelProhibited / 2)
            nrTimes++;
        totalMinLimit += lect.minClassLimit();
        totalMaxLimit += lect.maxClassLimit();
        if (!lect.values(solution.getAssignment()).isEmpty()) {
            Placement p = lect.values(solution.getAssignment()).get(0);
            nrMeetings += p.getTimeLocation().getNrMeetings();
            nrHalfHours += p.getTimeLocation().getNrMeetings() * p.getTimeLocation().getNrSlotsPerMeeting();
            totalMaxNormTimePref += lect.getMinMaxTimePreference()[1];
            totalMinNormTimePref += lect.getMinMaxTimePreference()[0];
            totalNormTimePref += Math.abs(lect.getMinMaxTimePreference()[1] - lect.getMinMaxTimePreference()[0]);
            totalMaxRoomPref += lect.getMinMaxRoomPreference()[1];
            totalMinRoomPref += lect.getMinMaxRoomPreference()[0];
            totalRoomPref += Math.abs(lect.getMinMaxRoomPreference()[1] - lect.getMinMaxRoomPreference()[0]);
            TimeLocation time = p.getTimeLocation();
            boolean hasRoomConstraint = false;
            for (RoomLocation roomLocation : lect.roomLocations()) {
                if (roomLocation.getRoomConstraint().getConstraint())
                    hasRoomConstraint = true;
            }
            if (hasRoomConstraint && lect.getNrRooms() > 0) {
                for (int d = firstWorkDay; d <= lastWorkDay; d++) {
                    if ((time.getDayCode() & Constants.DAY_CODES[d]) == 0)
                        continue;
                    for (int t = Math.max(time.getStartSlot(), firstDaySlot); t <= Math.min(time.getStartSlot() + time.getLength() - 1, lastDaySlot); t++) {
                        for (int l = 0; l < sizeLimits.length; l++) {
                            if (sizeLimits[l] <= lect.minRoomSize()) {
                                totalUsedSlots[l] += lect.getNrRooms();
                                totalUsedSeats[l] += lect.classLimit(assignment);
                                totalUsedSeats2[l] += lect.minRoomSize() * lect.getNrRooms();
                            }
                        }
                    }
                }
            }
        }
        if (lect.values(solution.getAssignment()).size() == 1) {
            nrSingleValueVariables++;
        }
        if (lect.timeLocations().size() == 1) {
            nrSingleTimeVariables++;
        }
        if (lect.roomLocations().size() == 1) {
            nrSingleRoomVariables++;
        }
        if (lect.getNrRooms() == 1) {
            nrOneRoomVariables++;
        }
        if (lect.getNrRooms() > 0) {
            nrOneOrMoreRoomVariables++;
        }
        if (!lect.roomLocations().isEmpty()) {
            int minRoomSize = Integer.MAX_VALUE;
            int maxRoomSize = Integer.MIN_VALUE;
            for (RoomLocation rl : lect.roomLocations()) {
                minRoomSize = Math.min(minRoomSize, rl.getRoomSize());
                maxRoomSize = Math.max(maxRoomSize, rl.getRoomSize());
                totalRoomSize += rl.getRoomSize();
            }
            totalAvailableMinRoomSize += minRoomSize;
            totalAvailableMaxRoomSize += maxRoomSize;
        }
    }
    for (JenrlConstraint jenrl : model.getJenrlConstraints()) {
        nrJenrls += jenrl.getJenrl();
        if ((jenrl.first()).timeLocations().size() == 1 && (jenrl.second()).timeLocations().size() == 1) {
            TimeLocation t1 = jenrl.first().timeLocations().get(0);
            TimeLocation t2 = jenrl.second().timeLocations().get(0);
            if (t1.hasIntersection(t2)) {
                nrInevitableStudentConflicts += jenrl.getJenrl();
                pw.println("Inevitable " + jenrl.getJenrl() + " student conflicts between " + jenrl.first() + " " + t1 + " and " + jenrl.second() + " " + t2);
            } else if (jenrl.first().values(solution.getAssignment()).size() == 1 && jenrl.second().values(solution.getAssignment()).size() == 1) {
                Placement p1 = jenrl.first().values(solution.getAssignment()).get(0);
                Placement p2 = jenrl.second().values(solution.getAssignment()).get(0);
                if (JenrlConstraint.isInConflict(p1, p2, ((TimetableModel) p1.variable().getModel()).getDistanceMetric())) {
                    nrInevitableStudentConflicts += jenrl.getJenrl();
                    pw.println("Inevitable " + jenrl.getJenrl() + (p1.getTimeLocation().hasIntersection(p2.getTimeLocation()) ? "" : " distance") + " student conflicts between " + p1 + " and " + p2);
                }
            }
        }
    }
    int totalCommitedPlacements = 0;
    for (Student student : students) {
        if (student.getCommitedPlacements() != null)
            totalCommitedPlacements += student.getCommitedPlacements().size();
    }
    pw.println("Total number of classes: " + model.variables().size());
    pwi.println("Number of classes," + model.variables().size());
    pw.println("Total number of instructional offerings: " + offerings.size() + " (" + sDoubleFormat.format(100.0 * offerings.size() / model.variables().size()) + "%)");
    // pwi.println("Number of instructional offerings,"+offerings.size());
    pw.println("Total number of configurations: " + configs.size() + " (" + sDoubleFormat.format(100.0 * configs.size() / model.variables().size()) + "%)");
    pw.println("Total number of scheduling subparts: " + subparts.size() + " (" + sDoubleFormat.format(100.0 * subparts.size() / model.variables().size()) + "%)");
    // pwi.println("Number of scheduling subparts,"+subparts.size());
    pw.println("Average number classes per subpart: " + sDoubleFormat.format(1.0 * model.variables().size() / subparts.size()));
    pwi.println("Avg. classes per instruction," + sDoubleFormat.format(1.0 * model.variables().size() / subparts.size()));
    pw.println("Average number classes per config: " + sDoubleFormat.format(1.0 * model.variables().size() / configs.size()));
    pw.println("Average number classes per offering: " + sDoubleFormat.format(1.0 * model.variables().size() / offerings.size()));
    pw.println("Total number of classes with only one value: " + nrSingleValueVariables + " (" + sDoubleFormat.format(100.0 * nrSingleValueVariables / model.variables().size()) + "%)");
    pw.println("Total number of classes with only one time: " + nrSingleTimeVariables + " (" + sDoubleFormat.format(100.0 * nrSingleTimeVariables / model.variables().size()) + "%)");
    pw.println("Total number of classes with only one room: " + nrSingleRoomVariables + " (" + sDoubleFormat.format(100.0 * nrSingleRoomVariables / model.variables().size()) + "%)");
    pwi.println("Classes with single value," + nrSingleValueVariables);
    // pwi.println("Classes with only one time/room,"+nrSingleTimeVariables+"/"+nrSingleRoomVariables);
    pw.println("Total number of classes requesting no room: " + (model.variables().size() - nrOneOrMoreRoomVariables) + " (" + sDoubleFormat.format(100.0 * (model.variables().size() - nrOneOrMoreRoomVariables) / model.variables().size()) + "%)");
    pw.println("Total number of classes requesting one room: " + nrOneRoomVariables + " (" + sDoubleFormat.format(100.0 * nrOneRoomVariables / model.variables().size()) + "%)");
    pw.println("Total number of classes requesting one or more rooms: " + nrOneOrMoreRoomVariables + " (" + sDoubleFormat.format(100.0 * nrOneOrMoreRoomVariables / model.variables().size()) + "%)");
    // pwi.println("% classes requesting no room,"+sDoubleFormat.format(100.0*(model.variables().size()-nrOneOrMoreRoomVariables)/model.variables().size())+"%");
    // pwi.println("% classes requesting one room,"+sDoubleFormat.format(100.0*nrOneRoomVariables/model.variables().size())+"%");
    // pwi.println("% classes requesting two or more rooms,"+sDoubleFormat.format(100.0*(nrOneOrMoreRoomVariables-nrOneRoomVariables)/model.variables().size())+"%");
    pw.println("Average number of requested rooms: " + sDoubleFormat.format(1.0 * nrReqRooms / model.variables().size()));
    pw.println("Average minimal class limit: " + sDoubleFormat.format(1.0 * totalMinLimit / model.variables().size()));
    pw.println("Average maximal class limit: " + sDoubleFormat.format(1.0 * totalMaxLimit / model.variables().size()));
    // pwi.println("Average class limit,"+sDoubleFormat.format(1.0*(totalMinLimit+totalMaxLimit)/(2*model.variables().size())));
    pw.println("Average number of placements: " + sDoubleFormat.format(1.0 * nrValues / model.variables().size()));
    // pwi.println("Average domain size,"+sDoubleFormat.format(1.0*nrValues/model.variables().size()));
    pwi.println("Avg. domain size," + sDoubleFormat.format(1.0 * nrValues / model.variables().size()));
    pw.println("Average number of time locations: " + sDoubleFormat.format(1.0 * nrTimes / model.variables().size()));
    pwi.println("Avg. number of avail. times/rooms," + sDoubleFormat.format(1.0 * nrTimes / model.variables().size()) + "/" + sDoubleFormat.format(1.0 * nrRooms / model.variables().size()));
    pw.println("Average number of room locations: " + sDoubleFormat.format(1.0 * nrRooms / model.variables().size()));
    pw.println("Average minimal requested room size: " + sDoubleFormat.format(1.0 * totalAvailableMinRoomSize / nrOneOrMoreRoomVariables));
    pw.println("Average maximal requested room size: " + sDoubleFormat.format(1.0 * totalAvailableMaxRoomSize / nrOneOrMoreRoomVariables));
    pw.println("Average requested room sizes: " + sDoubleFormat.format(1.0 * totalRoomSize / nrRooms));
    pwi.println("Average requested room size," + sDoubleFormat.format(1.0 * totalRoomSize / nrRooms));
    pw.println("Average maximum normalized time preference: " + sDoubleFormat.format(totalMaxNormTimePref / model.variables().size()));
    pw.println("Average minimum normalized time preference: " + sDoubleFormat.format(totalMinNormTimePref / model.variables().size()));
    pw.println("Average normalized time preference," + sDoubleFormat.format(totalNormTimePref / model.variables().size()));
    pw.println("Average maximum room preferences: " + sDoubleFormat.format(1.0 * totalMaxRoomPref / nrOneOrMoreRoomVariables));
    pw.println("Average minimum room preferences: " + sDoubleFormat.format(1.0 * totalMinRoomPref / nrOneOrMoreRoomVariables));
    pw.println("Average room preferences," + sDoubleFormat.format(1.0 * totalRoomPref / nrOneOrMoreRoomVariables));
    pw.println("Total number of students:" + students.size());
    pwi.println("Number of students," + students.size());
    pwi.println("Number of inevitable student conflicts," + nrInevitableStudentConflicts);
    pw.println("Total amount of student enrollments: " + nrStudentEnrls);
    pwi.println("Number of student enrollments," + nrStudentEnrls);
    pw.println("Total amount of joined enrollments: " + nrJenrls);
    pwi.println("Number of joint student enrollments," + nrJenrls);
    pw.println("Average number of students: " + sDoubleFormat.format(1.0 * students.size() / model.variables().size()));
    pw.println("Average number of enrollemnts (per student): " + sDoubleFormat.format(1.0 * nrStudentEnrls / students.size()));
    pwi.println("Avg. number of classes per student," + sDoubleFormat.format(1.0 * nrStudentEnrls / students.size()));
    pwi.println("Avg. number of committed classes per student," + sDoubleFormat.format(1.0 * totalCommitedPlacements / students.size()));
    pw.println("Total amount of inevitable student conflicts: " + nrInevitableStudentConflicts + " (" + sDoubleFormat.format(100.0 * nrInevitableStudentConflicts / nrStudentEnrls) + "%)");
    pw.println("Average number of meetings (per class): " + sDoubleFormat.format(1.0 * nrMeetings / model.variables().size()));
    pw.println("Average number of hours per class: " + sDoubleFormat.format(1.0 * nrHalfHours / model.variables().size() / 12.0));
    pwi.println("Avg. number of meetings per class," + sDoubleFormat.format(1.0 * nrMeetings / model.variables().size()));
    pwi.println("Avg. number of hours per class," + sDoubleFormat.format(1.0 * nrHalfHours / model.variables().size() / 12.0));
    int minRoomSize = Integer.MAX_VALUE;
    int maxRoomSize = Integer.MIN_VALUE;
    int nrDistancePairs = 0;
    double maxRoomDistance = Double.MIN_VALUE;
    double totalRoomDistance = 0.0;
    int[] totalAvailableSlots = new int[sizeLimits.length];
    int[] totalAvailableSeats = new int[sizeLimits.length];
    int nrOfRooms = 0;
    totalRoomSize = 0;
    for (RoomConstraint rc : model.getRoomConstraints()) {
        if (rc.variables().isEmpty())
            continue;
        nrOfRooms++;
        minRoomSize = Math.min(minRoomSize, rc.getCapacity());
        maxRoomSize = Math.max(maxRoomSize, rc.getCapacity());
        for (int l = 0; l < sizeLimits.length; l++) {
            if (sizeLimits[l] <= rc.getCapacity() && (l + 1 == sizeLimits.length || rc.getCapacity() < sizeLimits[l + 1])) {
                nrRoomsOfSize[l]++;
                if (minRoomOfSize[l] == 0)
                    minRoomOfSize[l] = rc.getCapacity();
                else
                    minRoomOfSize[l] = Math.min(minRoomOfSize[l], rc.getCapacity());
                if (maxRoomOfSize[l] == 0)
                    maxRoomOfSize[l] = rc.getCapacity();
                else
                    maxRoomOfSize[l] = Math.max(maxRoomOfSize[l], rc.getCapacity());
            }
        }
        totalRoomSize += rc.getCapacity();
        if (rc.getPosX() != null && rc.getPosY() != null) {
            for (RoomConstraint rc2 : model.getRoomConstraints()) {
                if (rc2.getResourceId().compareTo(rc.getResourceId()) > 0 && rc2.getPosX() != null && rc2.getPosY() != null) {
                    double distance = ((TimetableModel) solution.getModel()).getDistanceMetric().getDistanceInMinutes(rc.getId(), rc.getPosX(), rc.getPosY(), rc2.getId(), rc2.getPosX(), rc2.getPosY());
                    totalRoomDistance += distance;
                    nrDistancePairs++;
                    maxRoomDistance = Math.max(maxRoomDistance, distance);
                }
            }
        }
        for (int d = firstWorkDay; d <= lastWorkDay; d++) {
            for (int t = firstDaySlot; t <= lastDaySlot; t++) {
                if (rc.isAvailable(d * Constants.SLOTS_PER_DAY + t)) {
                    for (int l = 0; l < sizeLimits.length; l++) {
                        if (sizeLimits[l] <= rc.getCapacity()) {
                            totalAvailableSlots[l]++;
                            totalAvailableSeats[l] += rc.getCapacity();
                        }
                    }
                }
            }
        }
    }
    pw.println("Total number of rooms: " + nrOfRooms);
    pwi.println("Number of rooms," + nrOfRooms);
    pw.println("Minimal room size: " + minRoomSize);
    pw.println("Maximal room size: " + maxRoomSize);
    pwi.println("Room size min/max," + minRoomSize + "/" + maxRoomSize);
    pw.println("Average room size: " + sDoubleFormat.format(1.0 * totalRoomSize / model.getRoomConstraints().size()));
    pw.println("Maximal distance between two rooms: " + sDoubleFormat.format(maxRoomDistance));
    pw.println("Average distance between two rooms: " + sDoubleFormat.format(totalRoomDistance / nrDistancePairs));
    pwi.println("Average distance between two rooms [min]," + sDoubleFormat.format(totalRoomDistance / nrDistancePairs));
    pwi.println("Maximal distance between two rooms [min]," + sDoubleFormat.format(maxRoomDistance));
    for (int l = 0; l < sizeLimits.length; l++) {
        // sizeLimits.length;l++) {
        pwi.println("\"Room frequency (size>=" + sizeLimits[l] + ", used/avaiable times)\"," + sDoubleFormat.format(100.0 * totalUsedSlots[l] / totalAvailableSlots[l]) + "%");
        pwi.println("\"Room utilization (size>=" + sizeLimits[l] + ", used/available seats)\"," + sDoubleFormat.format(100.0 * totalUsedSeats[l] / totalAvailableSeats[l]) + "%");
        pwi.println("\"Number of rooms (size>=" + sizeLimits[l] + ")\"," + nrRoomsOfSize[l]);
        pwi.println("\"Min/max room size (size>=" + sizeLimits[l] + ")\"," + minRoomOfSize[l] + "-" + maxRoomOfSize[l]);
    // pwi.println("\"Room utilization (size>="+sizeLimits[l]+", minRoomSize)\","+sDoubleFormat.format(100.0*totalUsedSeats2[l]/totalAvailableSeats[l])+"%");
    }
    pw.println("Average hours available: " + sDoubleFormat.format(1.0 * totalAvailableSlots[0] / nrOfRooms / 12.0));
    int totalInstructedClasses = 0;
    for (InstructorConstraint ic : model.getInstructorConstraints()) {
        totalInstructedClasses += ic.variables().size();
    }
    pw.println("Total number of instructors: " + model.getInstructorConstraints().size());
    pwi.println("Number of instructors," + model.getInstructorConstraints().size());
    pw.println("Total class-instructor assignments: " + totalInstructedClasses + " (" + sDoubleFormat.format(100.0 * totalInstructedClasses / model.variables().size()) + "%)");
    pwi.println("Number of class-instructor assignments," + totalInstructedClasses);
    pw.println("Average classes per instructor: " + sDoubleFormat.format(1.0 * totalInstructedClasses / model.getInstructorConstraints().size()));
    pwi.println("Average classes per instructor," + sDoubleFormat.format(1.0 * totalInstructedClasses / model.getInstructorConstraints().size()));
    // pw.println("Average hours available: "+sDoubleFormat.format(1.0*totalAvailableSlots/model.getInstructorConstraints().size()/12.0));
    // pwi.println("Instructor availability [h],"+sDoubleFormat.format(1.0*totalAvailableSlots/model.getInstructorConstraints().size()/12.0));
    int nrGroupConstraints = model.getGroupConstraints().size() + model.getSpreadConstraints().size();
    int nrHardGroupConstraints = 0;
    int nrVarsInGroupConstraints = 0;
    for (GroupConstraint gc : model.getGroupConstraints()) {
        if (gc.isHard())
            nrHardGroupConstraints++;
        nrVarsInGroupConstraints += gc.variables().size();
    }
    for (SpreadConstraint sc : model.getSpreadConstraints()) {
        nrVarsInGroupConstraints += sc.variables().size();
    }
    pw.println("Total number of group constraints: " + nrGroupConstraints + " (" + sDoubleFormat.format(100.0 * nrGroupConstraints / model.variables().size()) + "%)");
    // pwi.println("Number of group constraints,"+nrGroupConstraints);
    pw.println("Total number of hard group constraints: " + nrHardGroupConstraints + " (" + sDoubleFormat.format(100.0 * nrHardGroupConstraints / model.variables().size()) + "%)");
    // pwi.println("Number of hard group constraints,"+nrHardGroupConstraints);
    pw.println("Average classes per group constraint: " + sDoubleFormat.format(1.0 * nrVarsInGroupConstraints / nrGroupConstraints));
    // pwi.println("Average classes per group constraint,"+sDoubleFormat.format(1.0*nrVarsInGroupConstraints/nrGroupConstraints));
    pwi.println("Avg. number distribution constraints per class," + sDoubleFormat.format(1.0 * nrVarsInGroupConstraints / model.variables().size()));
    pwi.println("Joint enrollment constraints," + model.getJenrlConstraints().size());
    pw.flush();
    pw.close();
    pwi.flush();
    pwi.close();
}
Also used : Lecture(org.cpsolver.coursett.model.Lecture) RoomConstraint(org.cpsolver.coursett.constraint.RoomConstraint) TimeLocation(org.cpsolver.coursett.model.TimeLocation) FileWriter(java.io.FileWriter) DepartmentSpreadConstraint(org.cpsolver.coursett.constraint.DepartmentSpreadConstraint) SpreadConstraint(org.cpsolver.coursett.constraint.SpreadConstraint) Placement(org.cpsolver.coursett.model.Placement) TreeSet(java.util.TreeSet) TimetableModel(org.cpsolver.coursett.model.TimetableModel) PrintWriter(java.io.PrintWriter) HashSet(java.util.HashSet) JenrlConstraint(org.cpsolver.coursett.constraint.JenrlConstraint) RoomLocation(org.cpsolver.coursett.model.RoomLocation) Student(org.cpsolver.coursett.model.Student) DepartmentSpreadConstraint(org.cpsolver.coursett.constraint.DepartmentSpreadConstraint) InstructorConstraint(org.cpsolver.coursett.constraint.InstructorConstraint) SpreadConstraint(org.cpsolver.coursett.constraint.SpreadConstraint) GroupConstraint(org.cpsolver.coursett.constraint.GroupConstraint) Constraint(org.cpsolver.ifs.model.Constraint) RoomConstraint(org.cpsolver.coursett.constraint.RoomConstraint) JenrlConstraint(org.cpsolver.coursett.constraint.JenrlConstraint) InstructorConstraint(org.cpsolver.coursett.constraint.InstructorConstraint) GroupConstraint(org.cpsolver.coursett.constraint.GroupConstraint) File(java.io.File)

Aggregations

TimeLocation (org.cpsolver.coursett.model.TimeLocation)36 Placement (org.cpsolver.coursett.model.Placement)17 Lecture (org.cpsolver.coursett.model.Lecture)14 HashSet (java.util.HashSet)12 RoomLocation (org.cpsolver.coursett.model.RoomLocation)9 Constraint (org.cpsolver.ifs.model.Constraint)9 ArrayList (java.util.ArrayList)8 BitSet (java.util.BitSet)7 HashMap (java.util.HashMap)7 Element (org.dom4j.Element)7 WeakeningConstraint (org.cpsolver.ifs.model.WeakeningConstraint)6 DecimalFormat (java.text.DecimalFormat)5 List (java.util.List)4 Map (java.util.Map)4 TreeSet (java.util.TreeSet)4 RoomConstraint (org.cpsolver.coursett.constraint.RoomConstraint)4 GroupConstraint (org.cpsolver.coursett.constraint.GroupConstraint)3 InstructorConstraint (org.cpsolver.coursett.constraint.InstructorConstraint)3 SpreadConstraint (org.cpsolver.coursett.constraint.SpreadConstraint)3 Student (org.cpsolver.coursett.model.Student)3