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++;
}
}
}
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;
}
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;
}
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;
}
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();
}
Aggregations