use of org.cpsolver.coursett.constraint.RoomConstraint in project cpsolver by UniTime.
the class TimetableXMLLoader method doLoad.
protected void doLoad(Solution<Lecture, Placement> currentSolution, Element root) {
if (root.attributeValue("term") != null)
getModel().getProperties().setProperty("Data.Term", root.attributeValue("term"));
if (root.attributeValue("year") != null)
getModel().setYear(Integer.parseInt(root.attributeValue("year")));
else if (root.attributeValue("term") != null)
getModel().setYear(Integer.parseInt(root.attributeValue("term").substring(0, 4)));
if (root.attributeValue("initiative") != null)
getModel().getProperties().setProperty("Data.Initiative", root.attributeValue("initiative"));
if (root.attributeValue("semester") != null && root.attributeValue("year") != null)
getModel().getProperties().setProperty("Data.Term", root.attributeValue("semester") + root.attributeValue("year"));
if (root.attributeValue("session") != null)
getModel().getProperties().setProperty("General.SessionId", root.attributeValue("session"));
if (root.attributeValue("solverGroup") != null)
getModel().getProperties().setProperty("General.SolverGroupId", root.attributeValue("solverGroup"));
String version = root.attributeValue("version");
// Student sectioning considers the whole course (including committed classes), since 2.5
boolean sectionWholeCourse = true;
if (version != null && version.indexOf('.') >= 0) {
int majorVersion = Integer.parseInt(version.substring(0, version.indexOf('.')));
int minorVersion = Integer.parseInt(version.substring(1 + version.indexOf('.')));
sectionWholeCourse = (majorVersion == 2 && minorVersion >= 5) || majorVersion > 2;
}
HashMap<Long, TimeLocation> perts = new HashMap<Long, TimeLocation>();
if (getModel().getProperties().getPropertyInt("MPP.TimePert", 0) > 0) {
int nrChanges = getModel().getProperties().getPropertyInt("MPP.TimePert", 0);
int idx = 0;
for (Iterator<?> i = root.element("perturbations").elementIterator("class"); i.hasNext() && idx < nrChanges; idx++) {
Element pertEl = (Element) i.next();
Long classId = Long.valueOf(pertEl.attributeValue("id"));
TimeLocation tl = new TimeLocation(Integer.parseInt(pertEl.attributeValue("days"), 2), Integer.parseInt(pertEl.attributeValue("start")), Integer.parseInt(pertEl.attributeValue("length")), 0, 0.0, 0, null, null, null, 0);
perts.put(classId, tl);
}
}
iProgress.setPhase("Creating rooms ...", root.element("rooms").elements("room").size());
HashMap<String, Element> roomElements = new HashMap<String, Element>();
HashMap<String, RoomConstraint> roomConstraints = new HashMap<String, RoomConstraint>();
HashMap<Long, List<Lecture>> sameLectures = new HashMap<Long, List<Lecture>>();
for (Iterator<?> i = root.element("rooms").elementIterator("room"); i.hasNext(); ) {
Element roomEl = (Element) i.next();
iProgress.incProgress();
roomElements.put(roomEl.attributeValue("id"), roomEl);
if ("false".equals(roomEl.attributeValue("constraint")))
continue;
RoomSharingModel sharingModel = null;
Element sharingEl = roomEl.element("sharing");
if (sharingEl != null) {
Character freeForAllPrefChar = null;
Element freeForAllEl = sharingEl.element("freeForAll");
if (freeForAllEl != null)
freeForAllPrefChar = freeForAllEl.attributeValue("value", "F").charAt(0);
Character notAvailablePrefChar = null;
Element notAvailableEl = sharingEl.element("notAvailable");
if (notAvailableEl != null)
notAvailablePrefChar = notAvailableEl.attributeValue("value", "X").charAt(0);
String pattern = sharingEl.element("pattern").getText();
int unit = Integer.parseInt(sharingEl.element("pattern").attributeValue("unit", "1"));
Map<Character, Long> departments = new HashMap<Character, Long>();
for (Iterator<?> j = sharingEl.elementIterator("department"); j.hasNext(); ) {
Element deptEl = (Element) j.next();
char value = deptEl.attributeValue("value", String.valueOf((char) ('0' + departments.size()))).charAt(0);
Long id = Long.valueOf(deptEl.attributeValue("id"));
departments.put(value, id);
}
sharingModel = new RoomSharingModel(unit, departments, pattern, freeForAllPrefChar, notAvailablePrefChar);
}
boolean ignoreTooFar = false;
if ("true".equals(roomEl.attributeValue("ignoreTooFar")))
ignoreTooFar = true;
boolean fake = false;
if ("true".equals(roomEl.attributeValue("fake")))
fake = true;
Double posX = null, posY = null;
if (roomEl.attributeValue("location") != null) {
String loc = roomEl.attributeValue("location");
posX = Double.valueOf(loc.substring(0, loc.indexOf(',')));
posY = Double.valueOf(loc.substring(loc.indexOf(',') + 1));
}
boolean discouraged = "true".equals(roomEl.attributeValue("discouraged"));
RoomConstraint constraint = (discouraged ? new DiscouragedRoomConstraint(getModel().getProperties(), Long.valueOf(roomEl.attributeValue("id")), (roomEl.attributeValue("name") != null ? roomEl.attributeValue("name") : "r" + roomEl.attributeValue("id")), (roomEl.attributeValue("building") == null ? null : Long.valueOf(roomEl.attributeValue("building"))), Integer.parseInt(roomEl.attributeValue("capacity")), sharingModel, posX, posY, ignoreTooFar, !fake) : new RoomConstraint(Long.valueOf(roomEl.attributeValue("id")), (roomEl.attributeValue("name") != null ? roomEl.attributeValue("name") : "r" + roomEl.attributeValue("id")), (roomEl.attributeValue("building") == null ? null : Long.valueOf(roomEl.attributeValue("building"))), Integer.parseInt(roomEl.attributeValue("capacity")), sharingModel, posX, posY, ignoreTooFar, !fake));
if (roomEl.attributeValue("type") != null)
constraint.setType(Long.valueOf(roomEl.attributeValue("type")));
getModel().addConstraint(constraint);
roomConstraints.put(roomEl.attributeValue("id"), constraint);
for (Iterator<?> j = roomEl.elementIterator("travel-time"); j.hasNext(); ) {
Element travelTimeEl = (Element) j.next();
getModel().getDistanceMetric().addTravelTime(constraint.getResourceId(), Long.valueOf(travelTimeEl.attributeValue("id")), Integer.valueOf(travelTimeEl.attributeValue("minutes")));
}
}
HashMap<String, InstructorConstraint> instructorConstraints = new HashMap<String, InstructorConstraint>();
if (root.element("instructors") != null) {
for (Iterator<?> i = root.element("instructors").elementIterator("instructor"); i.hasNext(); ) {
Element instructorEl = (Element) i.next();
InstructorConstraint instructorConstraint = new InstructorConstraint(Long.valueOf(instructorEl.attributeValue("id")), instructorEl.attributeValue("puid"), (instructorEl.attributeValue("name") != null ? instructorEl.attributeValue("name") : "i" + instructorEl.attributeValue("id")), "true".equals(instructorEl.attributeValue("ignDist")));
if (instructorEl.attributeValue("type") != null)
instructorConstraint.setType(Long.valueOf(instructorEl.attributeValue("type")));
instructorConstraints.put(instructorEl.attributeValue("id"), instructorConstraint);
getModel().addConstraint(instructorConstraint);
}
}
HashMap<Long, String> depts = new HashMap<Long, String>();
if (root.element("departments") != null) {
for (Iterator<?> i = root.element("departments").elementIterator("department"); i.hasNext(); ) {
Element deptEl = (Element) i.next();
depts.put(Long.valueOf(deptEl.attributeValue("id")), (deptEl.attributeValue("name") != null ? deptEl.attributeValue("name") : "d" + deptEl.attributeValue("id")));
}
}
HashMap<Long, Configuration> configs = new HashMap<Long, Configuration>();
HashMap<Long, List<Configuration>> alternativeConfigurations = new HashMap<Long, List<Configuration>>();
if (root.element("configurations") != null) {
for (Iterator<?> i = root.element("configurations").elementIterator("config"); i.hasNext(); ) {
Element configEl = (Element) i.next();
Long configId = Long.valueOf(configEl.attributeValue("id"));
int limit = Integer.parseInt(configEl.attributeValue("limit"));
Long offeringId = Long.valueOf(configEl.attributeValue("offering"));
Configuration config = new Configuration(offeringId, configId, limit);
configs.put(configId, config);
List<Configuration> altConfigs = alternativeConfigurations.get(offeringId);
if (altConfigs == null) {
altConfigs = new ArrayList<Configuration>();
alternativeConfigurations.put(offeringId, altConfigs);
}
altConfigs.add(config);
config.setAltConfigurations(altConfigs);
}
}
iProgress.setPhase("Creating variables ...", root.element("classes").elements("class").size());
HashMap<String, Element> classElements = new HashMap<String, Element>();
HashMap<String, Lecture> lectures = new HashMap<String, Lecture>();
HashMap<Lecture, Placement> assignedPlacements = new HashMap<Lecture, Placement>();
HashMap<Lecture, String> parents = new HashMap<Lecture, String>();
int ord = 0;
for (Iterator<?> i1 = root.element("classes").elementIterator("class"); i1.hasNext(); ) {
Element classEl = (Element) i1.next();
Configuration config = null;
if (classEl.attributeValue("config") != null) {
config = configs.get(Long.valueOf(classEl.attributeValue("config")));
}
if (config == null && classEl.attributeValue("offering") != null) {
Long offeringId = Long.valueOf(classEl.attributeValue("offering"));
Long configId = Long.valueOf(classEl.attributeValue("config"));
List<Configuration> altConfigs = alternativeConfigurations.get(offeringId);
if (altConfigs == null) {
altConfigs = new ArrayList<Configuration>();
alternativeConfigurations.put(offeringId, altConfigs);
}
for (Configuration c : altConfigs) {
if (c.getConfigId().equals(configId)) {
config = c;
break;
}
}
if (config == null) {
config = new Configuration(offeringId, configId, -1);
altConfigs.add(config);
config.setAltConfigurations(altConfigs);
configs.put(config.getConfigId(), config);
}
}
DatePattern defaultDatePattern = new DatePattern();
if (classEl.attributeValue("dates") == null) {
int startDay = Integer.parseInt(classEl.attributeValue("startDay", "0"));
int endDay = Integer.parseInt(classEl.attributeValue("endDay", "1"));
defaultDatePattern.setPattern(startDay, endDay);
defaultDatePattern.setName(sDF.format(getDate(getModel().getYear(), startDay)) + "-" + sDF.format(getDate(getModel().getYear(), endDay)));
} else {
defaultDatePattern.setId(classEl.attributeValue("datePattern") == null ? null : Long.valueOf(classEl.attributeValue("datePattern")));
defaultDatePattern.setName(classEl.attributeValue("datePatternName"));
defaultDatePattern.setPattern(classEl.attributeValue("dates"));
}
Hashtable<Long, DatePattern> datePatterns = new Hashtable<Long, TimetableXMLLoader.DatePattern>();
for (Iterator<?> i2 = classEl.elementIterator("date"); i2.hasNext(); ) {
Element dateEl = (Element) i2.next();
Long id = Long.valueOf(dateEl.attributeValue("id"));
datePatterns.put(id, new DatePattern(id, dateEl.attributeValue("name"), dateEl.attributeValue("pattern")));
}
classElements.put(classEl.attributeValue("id"), classEl);
List<InstructorConstraint> ics = new ArrayList<InstructorConstraint>();
for (Iterator<?> i2 = classEl.elementIterator("instructor"); i2.hasNext(); ) {
Element instructorEl = (Element) i2.next();
InstructorConstraint instructorConstraint = instructorConstraints.get(instructorEl.attributeValue("id"));
if (instructorConstraint == null) {
instructorConstraint = new InstructorConstraint(Long.valueOf(instructorEl.attributeValue("id")), instructorEl.attributeValue("puid"), (instructorEl.attributeValue("name") != null ? instructorEl.attributeValue("name") : "i" + instructorEl.attributeValue("id")), "true".equals(instructorEl.attributeValue("ignDist")));
instructorConstraints.put(instructorEl.attributeValue("id"), instructorConstraint);
getModel().addConstraint(instructorConstraint);
}
ics.add(instructorConstraint);
}
List<RoomLocation> roomLocations = new ArrayList<RoomLocation>();
List<RoomConstraint> roomConstraintsThisClass = new ArrayList<RoomConstraint>();
List<RoomLocation> initialRoomLocations = new ArrayList<RoomLocation>();
List<RoomLocation> assignedRoomLocations = new ArrayList<RoomLocation>();
List<RoomLocation> bestRoomLocations = new ArrayList<RoomLocation>();
for (Iterator<?> i2 = classEl.elementIterator("room"); i2.hasNext(); ) {
Element roomLocationEl = (Element) i2.next();
Element roomEl = roomElements.get(roomLocationEl.attributeValue("id"));
RoomConstraint roomConstraint = roomConstraints.get(roomLocationEl.attributeValue("id"));
Long roomId = null;
String roomName = null;
Long bldgId = null;
if (roomConstraint != null) {
roomConstraintsThisClass.add(roomConstraint);
roomId = roomConstraint.getResourceId();
roomName = roomConstraint.getRoomName();
bldgId = roomConstraint.getBuildingId();
} else {
roomId = Long.valueOf(roomEl.attributeValue("id"));
roomName = (roomEl.attributeValue("name") != null ? roomEl.attributeValue("name") : "r" + roomEl.attributeValue("id"));
bldgId = (roomEl.attributeValue("building") == null ? null : Long.valueOf(roomEl.attributeValue("building")));
}
boolean ignoreTooFar = false;
if ("true".equals(roomEl.attributeValue("ignoreTooFar")))
ignoreTooFar = true;
Double posX = null, posY = null;
if (roomEl.attributeValue("location") != null) {
String loc = roomEl.attributeValue("location");
posX = Double.valueOf(loc.substring(0, loc.indexOf(',')));
posY = Double.valueOf(loc.substring(loc.indexOf(',') + 1));
}
RoomLocation rl = new RoomLocation(roomId, roomName, bldgId, Integer.parseInt(roomLocationEl.attributeValue("pref")), Integer.parseInt(roomEl.attributeValue("capacity")), posX, posY, ignoreTooFar, roomConstraint);
if ("true".equals(roomLocationEl.attributeValue("initial")))
initialRoomLocations.add(rl);
if ("true".equals(roomLocationEl.attributeValue("solution")))
assignedRoomLocations.add(rl);
if ("true".equals(roomLocationEl.attributeValue("best")))
bestRoomLocations.add(rl);
roomLocations.add(rl);
}
List<TimeLocation> timeLocations = new ArrayList<TimeLocation>();
TimeLocation initialTimeLocation = null;
TimeLocation assignedTimeLocation = null;
TimeLocation bestTimeLocation = null;
TimeLocation prohibitedTime = perts.get(Long.valueOf(classEl.attributeValue("id")));
for (Iterator<?> i2 = classEl.elementIterator("time"); i2.hasNext(); ) {
Element timeLocationEl = (Element) i2.next();
DatePattern dp = defaultDatePattern;
if (timeLocationEl.attributeValue("date") != null)
dp = datePatterns.get(Long.valueOf(timeLocationEl.attributeValue("date")));
TimeLocation tl = new TimeLocation(Integer.parseInt(timeLocationEl.attributeValue("days"), 2), Integer.parseInt(timeLocationEl.attributeValue("start")), Integer.parseInt(timeLocationEl.attributeValue("length")), (int) Double.parseDouble(timeLocationEl.attributeValue("pref")), Double.parseDouble(timeLocationEl.attributeValue("npref", timeLocationEl.attributeValue("pref"))), Integer.parseInt(timeLocationEl.attributeValue("datePref", "0")), dp.getId(), dp.getName(), dp.getPattern(), Integer.parseInt(timeLocationEl.attributeValue("breakTime") == null ? "-1" : timeLocationEl.attributeValue("breakTime")));
if (tl.getBreakTime() < 0)
tl.setBreakTime(tl.getLength() == 18 ? 15 : 10);
if (timeLocationEl.attributeValue("pattern") != null)
tl.setTimePatternId(Long.valueOf(timeLocationEl.attributeValue("pattern")));
/*
* if (timePatternTransform) tl =
* transformTimePattern(Long.valueOf
* (classEl.attributeValue("id")),tl);
*/
if (prohibitedTime != null && prohibitedTime.getDayCode() == tl.getDayCode() && prohibitedTime.getStartSlot() == tl.getStartSlot() && prohibitedTime.getLength() == tl.getLength()) {
sLogger.info("Time " + tl.getLongName(true) + " is prohibited for class " + classEl.attributeValue("id"));
continue;
}
if ("true".equals(timeLocationEl.attributeValue("solution")))
assignedTimeLocation = tl;
if ("true".equals(timeLocationEl.attributeValue("initial")))
initialTimeLocation = tl;
if ("true".equals(timeLocationEl.attributeValue("best")))
bestTimeLocation = tl;
timeLocations.add(tl);
}
if (timeLocations.isEmpty()) {
sLogger.error(" ERROR: No time.");
continue;
}
int minClassLimit = 0;
int maxClassLimit = 0;
float room2limitRatio = 1.0f;
if (!"true".equals(classEl.attributeValue("committed"))) {
if (classEl.attributeValue("expectedCapacity") != null) {
minClassLimit = maxClassLimit = Integer.parseInt(classEl.attributeValue("expectedCapacity"));
int roomCapacity = Integer.parseInt(classEl.attributeValue("roomCapacity", classEl.attributeValue("expectedCapacity")));
if (minClassLimit == 0)
minClassLimit = maxClassLimit = roomCapacity;
room2limitRatio = (minClassLimit == 0 ? 1.0f : ((float) roomCapacity) / minClassLimit);
} else {
if (classEl.attribute("classLimit") != null) {
minClassLimit = maxClassLimit = Integer.parseInt(classEl.attributeValue("classLimit"));
} else {
minClassLimit = Integer.parseInt(classEl.attributeValue("minClassLimit"));
maxClassLimit = Integer.parseInt(classEl.attributeValue("maxClassLimit"));
}
room2limitRatio = Float.parseFloat(classEl.attributeValue("roomToLimitRatio", "1.0"));
}
}
Lecture lecture = new Lecture(Long.valueOf(classEl.attributeValue("id")), (classEl.attributeValue("solverGroup") != null ? Long.valueOf(classEl.attributeValue("solverGroup")) : null), Long.valueOf(classEl.attributeValue("subpart", classEl.attributeValue("course", "-1"))), (classEl.attributeValue("name") != null ? classEl.attributeValue("name") : "c" + classEl.attributeValue("id")), timeLocations, roomLocations, Integer.parseInt(classEl.attributeValue("nrRooms", roomLocations.isEmpty() ? "0" : "1")), null, minClassLimit, maxClassLimit, room2limitRatio);
lecture.setNote(classEl.attributeValue("note"));
if ("true".equals(classEl.attributeValue("committed")))
lecture.setCommitted(true);
if (!lecture.isCommitted() && classEl.attributeValue("ord") != null)
lecture.setOrd(Integer.parseInt(classEl.attributeValue("ord")));
else
lecture.setOrd(ord++);
lecture.setWeight(Double.parseDouble(classEl.attributeValue("weight", "1.0")));
if (lecture.getNrRooms() > 1)
lecture.setMaxRoomCombinations(Integer.parseInt(classEl.attributeValue("maxRoomCombinations", "-1")));
if (config != null)
lecture.setConfiguration(config);
if (initialTimeLocation != null && initialRoomLocations.size() == lecture.getNrRooms()) {
lecture.setInitialAssignment(new Placement(lecture, initialTimeLocation, initialRoomLocations));
}
if (assignedTimeLocation != null && assignedRoomLocations.size() == lecture.getNrRooms()) {
assignedPlacements.put(lecture, new Placement(lecture, assignedTimeLocation, assignedRoomLocations));
} else if (lecture.getInitialAssignment() != null) {
assignedPlacements.put(lecture, lecture.getInitialAssignment());
}
if (bestTimeLocation != null && bestRoomLocations.size() == lecture.getNrRooms()) {
lecture.setBestAssignment(new Placement(lecture, bestTimeLocation, bestRoomLocations), 0);
} else if (assignedTimeLocation != null && assignedRoomLocations.size() == lecture.getNrRooms()) {
lecture.setBestAssignment(assignedPlacements.get(lecture), 0);
}
lectures.put(classEl.attributeValue("id"), lecture);
if (classEl.attributeValue("department") != null)
lecture.setDepartment(Long.valueOf(classEl.attributeValue("department")));
if (classEl.attribute("scheduler") != null)
lecture.setScheduler(Long.valueOf(classEl.attributeValue("scheduler")));
if ((sectionWholeCourse || !lecture.isCommitted()) && classEl.attributeValue("subpart", classEl.attributeValue("course")) != null) {
Long subpartId = Long.valueOf(classEl.attributeValue("subpart", classEl.attributeValue("course")));
List<Lecture> sames = sameLectures.get(subpartId);
if (sames == null) {
sames = new ArrayList<Lecture>();
sameLectures.put(subpartId, sames);
}
sames.add(lecture);
}
String parent = classEl.attributeValue("parent");
if (parent != null)
parents.put(lecture, parent);
getModel().addVariable(lecture);
if (lecture.isCommitted()) {
Placement placement = assignedPlacements.get(lecture);
if (classEl.attribute("assignment") != null)
placement.setAssignmentId(Long.valueOf(classEl.attributeValue("assignment")));
for (InstructorConstraint ic : ics) ic.setNotAvailable(placement);
for (RoomConstraint rc : roomConstraintsThisClass) rc.setNotAvailable(placement);
} else {
for (InstructorConstraint ic : ics) ic.addVariable(lecture);
for (RoomConstraint rc : roomConstraintsThisClass) rc.addVariable(lecture);
}
iProgress.incProgress();
}
for (Map.Entry<Lecture, String> entry : parents.entrySet()) {
Lecture lecture = entry.getKey();
Lecture parent = lectures.get(entry.getValue());
if (parent == null) {
iProgress.warn("Parent class " + entry.getValue() + " does not exists.");
} else {
lecture.setParent(parent);
}
}
iProgress.setPhase("Creating constraints ...", root.element("groupConstraints").elements("constraint").size());
HashMap<String, Element> grConstraintElements = new HashMap<String, Element>();
HashMap<String, Constraint<Lecture, Placement>> groupConstraints = new HashMap<String, Constraint<Lecture, Placement>>();
for (Iterator<?> i1 = root.element("groupConstraints").elementIterator("constraint"); i1.hasNext(); ) {
Element grConstraintEl = (Element) i1.next();
Constraint<Lecture, Placement> c = null;
if ("SPREAD".equals(grConstraintEl.attributeValue("type"))) {
c = new SpreadConstraint(getModel().getProperties(), grConstraintEl.attributeValue("name", "spread"));
} else if ("MIN_ROOM_USE".equals(grConstraintEl.attributeValue("type"))) {
c = new MinimizeNumberOfUsedRoomsConstraint(getModel().getProperties());
} else if ("CLASS_LIMIT".equals(grConstraintEl.attributeValue("type"))) {
if (grConstraintEl.element("parentClass") == null) {
c = new ClassLimitConstraint(Integer.parseInt(grConstraintEl.attributeValue("courseLimit")), grConstraintEl.attributeValue("name", "class-limit"));
} else {
String classId = grConstraintEl.element("parentClass").attributeValue("id");
c = new ClassLimitConstraint(lectures.get(classId), grConstraintEl.attributeValue("name", "class-limit"));
}
if (grConstraintEl.attributeValue("delta") != null)
((ClassLimitConstraint) c).setClassLimitDelta(Integer.parseInt(grConstraintEl.attributeValue("delta")));
} else if ("MIN_GRUSE(10x1h)".equals(grConstraintEl.attributeValue("type"))) {
c = new MinimizeNumberOfUsedGroupsOfTime(getModel().getProperties(), "10x1h", MinimizeNumberOfUsedGroupsOfTime.sGroups10of1h);
} else if ("MIN_GRUSE(5x2h)".equals(grConstraintEl.attributeValue("type"))) {
c = new MinimizeNumberOfUsedGroupsOfTime(getModel().getProperties(), "5x2h", MinimizeNumberOfUsedGroupsOfTime.sGroups5of2h);
} else if ("MIN_GRUSE(3x3h)".equals(grConstraintEl.attributeValue("type"))) {
c = new MinimizeNumberOfUsedGroupsOfTime(getModel().getProperties(), "3x3h", MinimizeNumberOfUsedGroupsOfTime.sGroups3of3h);
} else if ("MIN_GRUSE(2x5h)".equals(grConstraintEl.attributeValue("type"))) {
c = new MinimizeNumberOfUsedGroupsOfTime(getModel().getProperties(), "2x5h", MinimizeNumberOfUsedGroupsOfTime.sGroups2of5h);
} else if (IgnoreStudentConflictsConstraint.REFERENCE.equals(grConstraintEl.attributeValue("type"))) {
c = new IgnoreStudentConflictsConstraint();
} else {
try {
FlexibleConstraintType f = FlexibleConstraintType.valueOf(grConstraintEl.attributeValue("type"));
try {
c = f.create(Long.valueOf(grConstraintEl.attributeValue("id")), grConstraintEl.attributeValue("owner"), grConstraintEl.attributeValue("pref"), grConstraintEl.attributeValue("reference"));
} catch (IllegalArgumentException e) {
iProgress.warn("Failed to create flexible constraint " + grConstraintEl.attributeValue("type") + ": " + e.getMessage(), e);
continue;
}
} catch (IllegalArgumentException e) {
// type did not match, continue with group constraint types
c = new GroupConstraint(Long.valueOf(grConstraintEl.attributeValue("id")), GroupConstraint.ConstraintType.get(grConstraintEl.attributeValue("type")), grConstraintEl.attributeValue("pref"));
}
}
getModel().addConstraint(c);
for (Iterator<?> i2 = grConstraintEl.elementIterator("class"); i2.hasNext(); ) {
String classId = ((Element) i2.next()).attributeValue("id");
Lecture other = lectures.get(classId);
if (other != null)
c.addVariable(other);
else
iProgress.warn("Class " + classId + " does not exists, but it is referred from group constraint " + c.getId() + " (" + c.getName() + ")");
}
grConstraintElements.put(grConstraintEl.attributeValue("id"), grConstraintEl);
groupConstraints.put(grConstraintEl.attributeValue("id"), c);
iProgress.incProgress();
}
iProgress.setPhase("Loading students ...", root.element("students").elements("student").size());
boolean initialSectioning = true;
HashMap<Long, Student> students = new HashMap<Long, Student>();
HashMap<Long, Set<Student>> offering2students = new HashMap<Long, Set<Student>>();
for (Iterator<?> i1 = root.element("students").elementIterator("student"); i1.hasNext(); ) {
Element studentEl = (Element) i1.next();
List<Lecture> lecturesThisStudent = new ArrayList<Lecture>();
Long studentId = Long.valueOf(studentEl.attributeValue("id"));
Student student = students.get(studentId);
if (student == null) {
student = new Student(studentId);
students.put(studentId, student);
getModel().addStudent(student);
}
student.setAcademicArea(studentEl.attributeValue("area"));
student.setAcademicClassification(studentEl.attributeValue("classification"));
student.setMajor(studentEl.attributeValue("major"));
student.setCurriculum(studentEl.attributeValue("curriculum"));
for (Iterator<?> i2 = studentEl.elementIterator("offering"); i2.hasNext(); ) {
Element ofEl = (Element) i2.next();
Long offeringId = Long.valueOf(ofEl.attributeValue("id"));
String priority = ofEl.attributeValue("priority");
student.addOffering(offeringId, Double.parseDouble(ofEl.attributeValue("weight", "1.0")), priority == null ? null : Double.valueOf(priority));
Set<Student> studentsThisOffering = offering2students.get(offeringId);
if (studentsThisOffering == null) {
studentsThisOffering = new HashSet<Student>();
offering2students.put(offeringId, studentsThisOffering);
}
studentsThisOffering.add(student);
}
for (Iterator<?> i2 = studentEl.elementIterator("class"); i2.hasNext(); ) {
String classId = ((Element) i2.next()).attributeValue("id");
Lecture lecture = lectures.get(classId);
if (lecture == null) {
iProgress.warn("Class " + classId + " does not exists, but it is referred from student " + student.getId());
continue;
}
if (lecture.isCommitted()) {
if (sectionWholeCourse && (lecture.getParent() != null || lecture.getConfiguration() != null)) {
// committed, but with course structure -- sectioning can be used
student.addLecture(lecture);
student.addConfiguration(lecture.getConfiguration());
lecture.addStudent(getAssignment(), student);
lecturesThisStudent.add(lecture);
initialSectioning = false;
} else {
Placement placement = assignedPlacements.get(lecture);
student.addCommitedPlacement(placement);
}
} else {
student.addLecture(lecture);
student.addConfiguration(lecture.getConfiguration());
lecture.addStudent(getAssignment(), student);
lecturesThisStudent.add(lecture);
initialSectioning = false;
}
}
for (Iterator<?> i2 = studentEl.elementIterator("prohibited-class"); i2.hasNext(); ) {
String classId = ((Element) i2.next()).attributeValue("id");
Lecture lecture = lectures.get(classId);
if (lecture != null)
student.addCanNotEnroll(lecture);
else
iProgress.warn("Class " + classId + " does not exists, but it is referred from student " + student.getId());
}
if (studentEl.attributeValue("instructor") != null)
student.setInstructor(instructorConstraints.get(studentEl.attributeValue("instructor")));
iProgress.incProgress();
}
if (root.element("groups") != null) {
iProgress.setPhase("Loading student groups ...", root.element("groups").elements("group").size());
for (Iterator<?> i1 = root.element("groups").elementIterator("group"); i1.hasNext(); ) {
Element groupEl = (Element) i1.next();
long groupId = Long.parseLong(groupEl.attributeValue("id"));
StudentGroup group = new StudentGroup(groupId, Double.parseDouble(groupEl.attributeValue("weight", "1.0")), groupEl.attributeValue("name", "Group-" + groupId));
getModel().addStudentGroup(group);
for (Iterator<?> i2 = groupEl.elementIterator("student"); i2.hasNext(); ) {
Element studentEl = (Element) i2.next();
Student student = students.get(Long.valueOf(studentEl.attributeValue("id")));
if (student != null) {
group.addStudent(student);
student.addGroup(group);
}
}
}
}
for (List<Lecture> sames : sameLectures.values()) {
for (Lecture lect : sames) {
lect.setSameSubpartLectures(sames);
}
}
if (initialSectioning) {
iProgress.setPhase("Initial sectioning ...", offering2students.size());
for (Map.Entry<Long, Set<Student>> entry : offering2students.entrySet()) {
Long offeringId = entry.getKey();
Set<Student> studentsThisOffering = entry.getValue();
List<Configuration> altConfigs = alternativeConfigurations.get(offeringId);
getModel().getStudentSectioning().initialSectioning(getAssignment(), offeringId, String.valueOf(offeringId), studentsThisOffering, altConfigs);
iProgress.incProgress();
}
for (Student student : students.values()) {
student.clearDistanceCache();
if (student.getInstructor() != null)
for (Lecture lecture : student.getInstructor().variables()) {
student.addLecture(lecture);
student.addConfiguration(lecture.getConfiguration());
lecture.addStudent(getAssignment(), student);
}
}
}
iProgress.setPhase("Computing jenrl ...", students.size());
HashMap<Lecture, HashMap<Lecture, JenrlConstraint>> jenrls = new HashMap<Lecture, HashMap<Lecture, JenrlConstraint>>();
for (Iterator<Student> i1 = students.values().iterator(); i1.hasNext(); ) {
Student st = i1.next();
for (Iterator<Lecture> i2 = st.getLectures().iterator(); i2.hasNext(); ) {
Lecture l1 = i2.next();
for (Iterator<Lecture> i3 = st.getLectures().iterator(); i3.hasNext(); ) {
Lecture l2 = i3.next();
if (l1.getId() >= l2.getId())
continue;
HashMap<Lecture, JenrlConstraint> x = jenrls.get(l1);
if (x == null) {
x = new HashMap<Lecture, JenrlConstraint>();
jenrls.put(l1, x);
}
JenrlConstraint jenrl = x.get(l2);
if (jenrl == null) {
jenrl = new JenrlConstraint();
jenrl.addVariable(l1);
jenrl.addVariable(l2);
getModel().addConstraint(jenrl);
x.put(l2, jenrl);
}
jenrl.incJenrl(getAssignment(), st);
}
}
iProgress.incProgress();
}
if (iDeptBalancing) {
iProgress.setPhase("Creating dept. spread constraints ...", getModel().variables().size());
HashMap<Long, DepartmentSpreadConstraint> depSpreadConstraints = new HashMap<Long, DepartmentSpreadConstraint>();
for (Lecture lecture : getModel().variables()) {
if (lecture.getDepartment() == null)
continue;
DepartmentSpreadConstraint deptConstr = depSpreadConstraints.get(lecture.getDepartment());
if (deptConstr == null) {
String name = depts.get(lecture.getDepartment());
deptConstr = new DepartmentSpreadConstraint(getModel().getProperties(), lecture.getDepartment(), (name != null ? name : "d" + lecture.getDepartment()));
depSpreadConstraints.put(lecture.getDepartment(), deptConstr);
getModel().addConstraint(deptConstr);
}
deptConstr.addVariable(lecture);
iProgress.incProgress();
}
}
if (getModel().getProperties().getPropertyBoolean("General.PurgeInvalidPlacements", true)) {
iProgress.setPhase("Purging invalid placements ...", getModel().variables().size());
for (Lecture lecture : getModel().variables()) {
lecture.purgeInvalidValues(iInteractiveMode);
iProgress.incProgress();
}
}
if (getModel().hasConstantVariables() && getModel().constantVariables().size() > 0) {
iProgress.setPhase("Assigning committed classes ...", assignedPlacements.size());
for (Map.Entry<Lecture, Placement> entry : assignedPlacements.entrySet()) {
Lecture lecture = entry.getKey();
Placement placement = entry.getValue();
if (!lecture.isCommitted()) {
iProgress.incProgress();
continue;
}
lecture.setConstantValue(placement);
getModel().weaken(getAssignment(), placement);
Map<Constraint<Lecture, Placement>, Set<Placement>> conflictConstraints = getModel().conflictConstraints(getAssignment(), placement);
if (conflictConstraints.isEmpty()) {
getAssignment().assign(0, placement);
} else {
sLogger.warn("WARNING: Unable to assign " + lecture.getName() + " := " + placement.getName());
sLogger.debug(" Reason:");
for (Constraint<Lecture, Placement> c : conflictConstraints.keySet()) {
Set<Placement> vals = conflictConstraints.get(c);
for (Placement v : vals) {
sLogger.debug(" " + v.variable().getName() + " = " + v.getName());
}
sLogger.debug(" in constraint " + c);
}
}
iProgress.incProgress();
}
}
if (currentSolution != null) {
iProgress.setPhase("Creating best assignment ...", 2 * getModel().variables().size());
for (Lecture lecture : getModel().variables()) {
iProgress.incProgress();
Placement placement = lecture.getBestAssignment();
if (placement == null)
continue;
getModel().weaken(getAssignment(), placement);
getAssignment().assign(0, placement);
}
currentSolution.saveBest();
for (Lecture lecture : getModel().variables()) {
iProgress.incProgress();
getAssignment().unassign(0, lecture);
}
}
iProgress.setPhase("Creating initial assignment ...", assignedPlacements.size());
for (Map.Entry<Lecture, Placement> entry : assignedPlacements.entrySet()) {
Lecture lecture = entry.getKey();
Placement placement = entry.getValue();
if (lecture.isCommitted()) {
iProgress.incProgress();
continue;
}
getModel().weaken(getAssignment(), placement);
Map<Constraint<Lecture, Placement>, Set<Placement>> conflictConstraints = getModel().conflictConstraints(getAssignment(), placement);
if (conflictConstraints.isEmpty()) {
if (!placement.isValid()) {
sLogger.warn("WARNING: Lecture " + lecture.getName() + " does not contain assignment " + placement.getLongName(true) + " in its domain (" + placement.getNotValidReason(getAssignment(), true) + ").");
} else
getAssignment().assign(0, placement);
} else {
sLogger.warn("WARNING: Unable to assign " + lecture.getName() + " := " + placement.getName());
sLogger.debug(" Reason:");
for (Constraint<Lecture, Placement> c : conflictConstraints.keySet()) {
Set<Placement> vals = conflictConstraints.get(c);
for (Placement v : vals) {
sLogger.debug(" " + v.variable().getName() + " = " + v.getName());
}
sLogger.debug(" in constraint " + c);
}
}
iProgress.incProgress();
}
if (initialSectioning && getAssignment().nrAssignedVariables() != 0 && !getModel().getProperties().getPropertyBoolean("Global.LoadStudentEnrlsFromSolution", false))
getModel().switchStudents(getAssignment());
if (iForcedPerturbances > 0) {
iProgress.setPhase("Forcing perturbances", iForcedPerturbances);
for (int i = 0; i < iForcedPerturbances; i++) {
iProgress.setProgress(i);
Lecture var = null;
do {
var = ToolBox.random(getModel().variables());
} while (var.getInitialAssignment() == null || var.values(getAssignment()).size() <= 1);
var.removeInitialValue();
}
}
/*
for (Constraint<Lecture, Placement> c : getModel().constraints()) {
if (c instanceof SpreadConstraint)
((SpreadConstraint) c).init();
if (c instanceof DiscouragedRoomConstraint)
((DiscouragedRoomConstraint) c).setEnabled(true);
if (c instanceof MinimizeNumberOfUsedRoomsConstraint)
((MinimizeNumberOfUsedRoomsConstraint) c).setEnabled(true);
if (c instanceof MinimizeNumberOfUsedGroupsOfTime)
((MinimizeNumberOfUsedGroupsOfTime) c).setEnabled(true);
}
*/
}
use of org.cpsolver.coursett.constraint.RoomConstraint in project cpsolver by UniTime.
the class TimetableXMLSaver method doSave.
protected void doSave(Element root) {
root.addAttribute("version", "2.5");
root.addAttribute("initiative", getModel().getProperties().getProperty("Data.Initiative"));
root.addAttribute("term", getModel().getProperties().getProperty("Data.Term"));
root.addAttribute("year", String.valueOf(getModel().getYear()));
root.addAttribute("created", String.valueOf(new Date()));
root.addAttribute("nrDays", String.valueOf(Constants.DAY_CODES.length));
root.addAttribute("slotsPerDay", String.valueOf(Constants.SLOTS_PER_DAY));
if (!iConvertIds && getModel().getProperties().getProperty("General.SessionId") != null)
root.addAttribute("session", getModel().getProperties().getProperty("General.SessionId"));
if (iShowNames && !iConvertIds && getModel().getProperties().getProperty("General.SolverGroupId") != null)
root.addAttribute("solverGroup", getId("solverGroup", getModel().getProperties().getProperty("General.SolverGroupId")));
HashMap<String, Element> roomElements = new HashMap<String, Element>();
Element roomsEl = root.addElement("rooms");
for (RoomConstraint roomConstraint : getModel().getRoomConstraints()) {
Element roomEl = roomsEl.addElement("room").addAttribute("id", getId("room", roomConstraint.getResourceId()));
roomEl.addAttribute("constraint", "true");
if (roomConstraint instanceof DiscouragedRoomConstraint)
roomEl.addAttribute("discouraged", "true");
if (iShowNames) {
roomEl.addAttribute("name", roomConstraint.getRoomName());
}
if (!iConvertIds && roomConstraint.getBuildingId() != null)
roomEl.addAttribute("building", getId("bldg", roomConstraint.getBuildingId()));
roomElements.put(getId("room", roomConstraint.getResourceId()), roomEl);
roomEl.addAttribute("capacity", String.valueOf(roomConstraint.getCapacity()));
if (roomConstraint.getPosX() != null && roomConstraint.getPosY() != null)
roomEl.addAttribute("location", roomConstraint.getPosX() + "," + roomConstraint.getPosY());
if (roomConstraint.getIgnoreTooFar())
roomEl.addAttribute("ignoreTooFar", "true");
if (!roomConstraint.getConstraint())
roomEl.addAttribute("fake", "true");
if (roomConstraint.getSharingModel() != null) {
RoomSharingModel sharingModel = roomConstraint.getSharingModel();
Element sharingEl = roomEl.addElement("sharing");
sharingEl.addElement("pattern").addAttribute("unit", String.valueOf(sharingModel.getStep())).setText(sharingModel.getPreferences());
sharingEl.addElement("freeForAll").addAttribute("value", String.valueOf(sharingModel.getFreeForAllPrefChar()));
sharingEl.addElement("notAvailable").addAttribute("value", String.valueOf(sharingModel.getNotAvailablePrefChar()));
for (Long id : sharingModel.getDepartmentIds()) {
sharingEl.addElement("department").addAttribute("value", String.valueOf(sharingModel.getCharacter(id))).addAttribute("id", getId("dept", id));
}
}
if (roomConstraint.getType() != null && iShowNames)
roomEl.addAttribute("type", roomConstraint.getType().toString());
Map<Long, Integer> travelTimes = getModel().getDistanceMetric().getTravelTimes().get(roomConstraint.getResourceId());
if (travelTimes != null)
for (Map.Entry<Long, Integer> time : travelTimes.entrySet()) roomEl.addElement("travel-time").addAttribute("id", getId("room", time.getKey())).addAttribute("minutes", time.getValue().toString());
}
Element instructorsEl = root.addElement("instructors");
Element departmentsEl = root.addElement("departments");
HashMap<Long, String> depts = new HashMap<Long, String>();
Element configsEl = (iShowNames ? root.addElement("configurations") : null);
HashSet<Configuration> configs = new HashSet<Configuration>();
Element classesEl = root.addElement("classes");
HashMap<Long, Element> classElements = new HashMap<Long, Element>();
List<Lecture> vars = new ArrayList<Lecture>(getModel().variables());
if (getModel().hasConstantVariables())
vars.addAll(getModel().constantVariables());
for (Lecture lecture : vars) {
Placement placement = getAssignment().getValue(lecture);
if (lecture.isCommitted() && placement == null)
placement = lecture.getInitialAssignment();
Placement initialPlacement = lecture.getInitialAssignment();
// if (initialPlacement==null) initialPlacement =
// (Placement)lecture.getAssignment();
Placement bestPlacement = lecture.getBestAssignment();
Element classEl = classesEl.addElement("class").addAttribute("id", getId("class", lecture.getClassId()));
classElements.put(lecture.getClassId(), classEl);
if (iShowNames && lecture.getNote() != null)
classEl.addAttribute("note", lecture.getNote());
if (iShowNames && !lecture.isCommitted())
classEl.addAttribute("ord", String.valueOf(lecture.getOrd()));
if (lecture.getWeight() != 1.0)
classEl.addAttribute("weight", String.valueOf(lecture.getWeight()));
if (iShowNames && lecture.getSolverGroupId() != null)
classEl.addAttribute("solverGroup", getId("solverGroup", lecture.getSolverGroupId()));
if (lecture.getParent() == null && lecture.getConfiguration() != null) {
if (!iShowNames)
classEl.addAttribute("offering", getId("offering", lecture.getConfiguration().getOfferingId().toString()));
classEl.addAttribute("config", getId("config", lecture.getConfiguration().getConfigId().toString()));
if (iShowNames && configs.add(lecture.getConfiguration())) {
configsEl.addElement("config").addAttribute("id", getId("config", lecture.getConfiguration().getConfigId().toString())).addAttribute("limit", String.valueOf(lecture.getConfiguration().getLimit())).addAttribute("offering", getId("offering", lecture.getConfiguration().getOfferingId().toString()));
}
}
classEl.addAttribute("committed", (lecture.isCommitted() ? "true" : "false"));
if (lecture.getParent() != null)
classEl.addAttribute("parent", getId("class", lecture.getParent().getClassId()));
if (lecture.getSchedulingSubpartId() != null)
classEl.addAttribute("subpart", getId("subpart", lecture.getSchedulingSubpartId()));
if (iShowNames && lecture.isCommitted() && placement != null && placement.getAssignmentId() != null) {
classEl.addAttribute("assignment", getId("assignment", placement.getAssignmentId()));
}
if (!lecture.isCommitted()) {
if (lecture.minClassLimit() == lecture.maxClassLimit()) {
classEl.addAttribute("classLimit", String.valueOf(lecture.maxClassLimit()));
} else {
classEl.addAttribute("minClassLimit", String.valueOf(lecture.minClassLimit()));
classEl.addAttribute("maxClassLimit", String.valueOf(lecture.maxClassLimit()));
}
if (lecture.roomToLimitRatio() != 1.0f)
classEl.addAttribute("roomToLimitRatio", sStudentWeightFormat.format(lecture.roomToLimitRatio()));
}
if (lecture.getNrRooms() != 1)
classEl.addAttribute("nrRooms", String.valueOf(lecture.getNrRooms()));
if (lecture.getNrRooms() > 1 && lecture.getMaxRoomCombinations() > 0)
classEl.addAttribute("maxRoomCombinations", String.valueOf(lecture.getMaxRoomCombinations()));
if (iShowNames)
classEl.addAttribute("name", lecture.getName());
if (lecture.getDeptSpreadConstraint() != null) {
classEl.addAttribute("department", getId("dept", lecture.getDeptSpreadConstraint().getDepartmentId()));
depts.put(lecture.getDeptSpreadConstraint().getDepartmentId(), lecture.getDeptSpreadConstraint().getName());
}
if (lecture.getScheduler() != null)
classEl.addAttribute("scheduler", getId("dept", lecture.getScheduler()));
for (InstructorConstraint ic : lecture.getInstructorConstraints()) {
Element instrEl = classEl.addElement("instructor").addAttribute("id", getId("inst", ic.getResourceId()));
if ((lecture.isCommitted() || iSaveCurrent) && placement != null)
instrEl.addAttribute("solution", "true");
if (iSaveInitial && initialPlacement != null)
instrEl.addAttribute("initial", "true");
if (iSaveBest && bestPlacement != null && !bestPlacement.equals(placement))
instrEl.addAttribute("best", "true");
}
for (RoomLocation rl : lecture.roomLocations()) {
Element roomLocationEl = classEl.addElement("room");
roomLocationEl.addAttribute("id", getId("room", rl.getId()));
roomLocationEl.addAttribute("pref", String.valueOf(rl.getPreference()));
if ((lecture.isCommitted() || iSaveCurrent) && placement != null && placement.hasRoomLocation(rl.getId()))
roomLocationEl.addAttribute("solution", "true");
if (iSaveInitial && initialPlacement != null && initialPlacement.hasRoomLocation(rl.getId()))
roomLocationEl.addAttribute("initial", "true");
if (iSaveBest && bestPlacement != null && !bestPlacement.equals(placement) && bestPlacement.hasRoomLocation(rl.getId()))
roomLocationEl.addAttribute("best", "true");
if (!roomElements.containsKey(getId("room", rl.getId()))) {
// room location without room constraint
Element roomEl = roomsEl.addElement("room").addAttribute("id", getId("room", rl.getId()));
roomEl.addAttribute("constraint", "false");
if (!iConvertIds && rl.getBuildingId() != null)
roomEl.addAttribute("building", getId("bldg", rl.getBuildingId()));
if (iShowNames) {
roomEl.addAttribute("name", rl.getName());
}
roomElements.put(getId("room", rl.getId()), roomEl);
roomEl.addAttribute("capacity", String.valueOf(rl.getRoomSize()));
if (rl.getPosX() != null && rl.getPosY() != null)
roomEl.addAttribute("location", rl.getPosX() + "," + rl.getPosY());
if (rl.getIgnoreTooFar())
roomEl.addAttribute("ignoreTooFar", "true");
}
}
boolean first = true;
Set<Long> dp = new HashSet<Long>();
for (TimeLocation tl : lecture.timeLocations()) {
Element timeLocationEl = classEl.addElement("time");
timeLocationEl.addAttribute("days", sDF[7].format(Long.parseLong(Integer.toBinaryString(tl.getDayCode()))));
timeLocationEl.addAttribute("start", String.valueOf(tl.getStartSlot()));
timeLocationEl.addAttribute("length", String.valueOf(tl.getLength()));
timeLocationEl.addAttribute("breakTime", String.valueOf(tl.getBreakTime()));
if (iShowNames) {
timeLocationEl.addAttribute("pref", String.valueOf(tl.getPreference()));
timeLocationEl.addAttribute("npref", String.valueOf(tl.getNormalizedPreference()));
} else {
timeLocationEl.addAttribute("pref", String.valueOf(tl.getNormalizedPreference()));
}
if (!iConvertIds && tl.getTimePatternId() != null)
timeLocationEl.addAttribute("pattern", getId("pat", tl.getTimePatternId()));
if (tl.getDatePatternId() != null && dp.add(tl.getDatePatternId())) {
Element dateEl = classEl.addElement("date");
dateEl.addAttribute("id", getId("dpat", String.valueOf(tl.getDatePatternId())));
if (iShowNames)
dateEl.addAttribute("name", tl.getDatePatternName());
dateEl.addAttribute("pattern", bitset2string(tl.getWeekCode()));
}
if (tl.getDatePatternPreference() != 0)
timeLocationEl.addAttribute("datePref", String.valueOf(tl.getDatePatternPreference()));
if (tl.getTimePatternId() == null && first) {
if (iShowNames)
classEl.addAttribute("datePatternName", tl.getDatePatternName());
classEl.addAttribute("dates", bitset2string(tl.getWeekCode()));
first = false;
}
if (tl.getDatePatternId() != null) {
timeLocationEl.addAttribute("date", getId("dpat", String.valueOf(tl.getDatePatternId())));
}
if ((lecture.isCommitted() || iSaveCurrent) && placement != null && placement.getTimeLocation().equals(tl))
timeLocationEl.addAttribute("solution", "true");
if (iSaveInitial && initialPlacement != null && initialPlacement.getTimeLocation().equals(tl))
timeLocationEl.addAttribute("initial", "true");
if (iSaveBest && bestPlacement != null && !bestPlacement.equals(placement) && bestPlacement.getTimeLocation().equals(tl))
timeLocationEl.addAttribute("best", "true");
}
}
for (InstructorConstraint ic : getModel().getInstructorConstraints()) {
if (iShowNames || ic.isIgnoreDistances()) {
Element instrEl = instructorsEl.addElement("instructor").addAttribute("id", getId("inst", ic.getResourceId()));
if (iShowNames) {
if (ic.getPuid() != null && ic.getPuid().length() > 0)
instrEl.addAttribute("puid", ic.getPuid());
instrEl.addAttribute("name", ic.getName());
if (ic.getType() != null && iShowNames)
instrEl.addAttribute("type", ic.getType().toString());
}
if (ic.isIgnoreDistances()) {
instrEl.addAttribute("ignDist", "true");
}
}
if (ic.getUnavailabilities() != null) {
for (Placement placement : ic.getUnavailabilities()) {
Lecture lecture = placement.variable();
Element classEl = classElements.get(lecture.getClassId());
classEl.addElement("instructor").addAttribute("id", getId("inst", ic.getResourceId())).addAttribute("solution", "true");
}
}
}
if (instructorsEl.elements().isEmpty())
root.remove(instructorsEl);
Element grConstraintsEl = root.addElement("groupConstraints");
for (GroupConstraint gc : getModel().getGroupConstraints()) {
Element grEl = grConstraintsEl.addElement("constraint").addAttribute("id", getId("gr", String.valueOf(gc.getId())));
grEl.addAttribute("type", gc.getType().reference());
grEl.addAttribute("pref", gc.getPrologPreference());
for (Lecture l : gc.variables()) {
grEl.addElement("class").addAttribute("id", getId("class", l.getClassId()));
}
}
for (SpreadConstraint spread : getModel().getSpreadConstraints()) {
Element grEl = grConstraintsEl.addElement("constraint").addAttribute("id", getId("gr", String.valueOf(spread.getId())));
grEl.addAttribute("type", "SPREAD");
grEl.addAttribute("pref", Constants.sPreferenceRequired);
if (iShowNames)
grEl.addAttribute("name", spread.getName());
for (Lecture l : spread.variables()) {
grEl.addElement("class").addAttribute("id", getId("class", l.getClassId()));
}
}
for (Constraint<Lecture, Placement> c : getModel().constraints()) {
if (c instanceof MinimizeNumberOfUsedRoomsConstraint) {
Element grEl = grConstraintsEl.addElement("constraint").addAttribute("id", getId("gr", String.valueOf(c.getId())));
grEl.addAttribute("type", "MIN_ROOM_USE");
grEl.addAttribute("pref", Constants.sPreferenceRequired);
for (Lecture l : c.variables()) {
grEl.addElement("class").addAttribute("id", getId("class", l.getClassId()));
}
}
if (c instanceof MinimizeNumberOfUsedGroupsOfTime) {
Element grEl = grConstraintsEl.addElement("constraint").addAttribute("id", getId("gr", String.valueOf(c.getId())));
grEl.addAttribute("type", ((MinimizeNumberOfUsedGroupsOfTime) c).getConstraintName());
grEl.addAttribute("pref", Constants.sPreferenceRequired);
for (Lecture l : c.variables()) {
grEl.addElement("class").addAttribute("id", getId("class", l.getClassId()));
}
}
if (c instanceof IgnoreStudentConflictsConstraint) {
Element grEl = grConstraintsEl.addElement("constraint").addAttribute("id", getId("gr", String.valueOf(c.getId())));
grEl.addAttribute("type", IgnoreStudentConflictsConstraint.REFERENCE);
grEl.addAttribute("pref", Constants.sPreferenceRequired);
for (Lecture l : c.variables()) {
grEl.addElement("class").addAttribute("id", getId("class", l.getClassId()));
}
}
}
for (ClassLimitConstraint clc : getModel().getClassLimitConstraints()) {
Element grEl = grConstraintsEl.addElement("constraint").addAttribute("id", getId("gr", String.valueOf(clc.getId())));
grEl.addAttribute("type", "CLASS_LIMIT");
grEl.addAttribute("pref", Constants.sPreferenceRequired);
if (clc.getParentLecture() != null) {
grEl.addElement("parentClass").addAttribute("id", getId("class", clc.getParentLecture().getClassId()));
} else
grEl.addAttribute("courseLimit", String.valueOf(clc.classLimit() - clc.getClassLimitDelta()));
if (clc.getClassLimitDelta() != 0)
grEl.addAttribute("delta", String.valueOf(clc.getClassLimitDelta()));
if (iShowNames)
grEl.addAttribute("name", clc.getName());
for (Lecture l : clc.variables()) {
grEl.addElement("class").addAttribute("id", getId("class", l.getClassId()));
}
}
for (FlexibleConstraint gc : getModel().getFlexibleConstraints()) {
Element flEl = grConstraintsEl.addElement("constraint").addAttribute("id", getId("gr", String.valueOf(gc.getId())));
flEl.addAttribute("reference", gc.getReference());
flEl.addAttribute("owner", gc.getOwner());
flEl.addAttribute("pref", gc.getPrologPreference());
flEl.addAttribute("type", gc.getType().toString());
for (Lecture l : gc.variables()) {
flEl.addElement("class").addAttribute("id", getId("class", l.getClassId()));
}
}
HashMap<Student, List<String>> students = new HashMap<Student, List<String>>();
for (Lecture lecture : vars) {
for (Student student : lecture.students()) {
List<String> enrls = students.get(student);
if (enrls == null) {
enrls = new ArrayList<String>();
students.put(student, enrls);
}
enrls.add(getId("class", lecture.getClassId()));
}
}
Element studentsEl = root.addElement("students");
Element groupsEl = root.addElement("groups");
Map<StudentGroup, Element> groups = new HashMap<StudentGroup, Element>();
for (Student student : new TreeSet<Student>(students.keySet())) {
Element stEl = studentsEl.addElement("student").addAttribute("id", getId("student", student.getId()));
if (iShowNames) {
if (student.getAcademicArea() != null)
stEl.addAttribute("area", student.getAcademicArea());
if (student.getAcademicClassification() != null)
stEl.addAttribute("classification", student.getAcademicClassification());
if (student.getMajor() != null)
stEl.addAttribute("major", student.getMajor());
if (student.getCurriculum() != null)
stEl.addAttribute("curriculum", student.getCurriculum());
}
for (Map.Entry<Long, Double> entry : student.getOfferingsMap().entrySet()) {
Long offeringId = entry.getKey();
Double weight = entry.getValue();
Element offEl = stEl.addElement("offering").addAttribute("id", getId("offering", offeringId.toString()));
if (weight.doubleValue() != 1.0)
offEl.addAttribute("weight", sStudentWeightFormat.format(weight));
Double priority = student.getPriority(offeringId);
if (priority != null)
offEl.addAttribute("priority", priority.toString());
}
if (iExportStudentSectioning || getModel().nrUnassignedVariables(getAssignment()) == 0 || student.getOfferingsMap().isEmpty()) {
List<String> lectures = students.get(student);
Collections.sort(lectures);
for (String classId : lectures) {
stEl.addElement("class").addAttribute("id", classId);
}
}
Map<Long, Set<Lecture>> canNotEnroll = student.canNotEnrollSections();
if (canNotEnroll != null) {
for (Set<Lecture> canNotEnrollLects : canNotEnroll.values()) {
for (Iterator<Lecture> i3 = canNotEnrollLects.iterator(); i3.hasNext(); ) {
stEl.addElement("prohibited-class").addAttribute("id", getId("class", (i3.next()).getClassId()));
}
}
}
if (student.getCommitedPlacements() != null) {
for (Placement placement : student.getCommitedPlacements()) {
stEl.addElement("class").addAttribute("id", getId("class", placement.variable().getClassId()));
}
}
if (student.getInstructor() != null)
stEl.addAttribute("instructor", getId("inst", student.getInstructor().getResourceId()));
for (StudentGroup group : student.getGroups()) {
Element groupEl = groups.get(group);
if (groupEl == null) {
groupEl = groupsEl.addElement("group");
groupEl.addAttribute("id", getId("group", group.getId()));
if (group.getWeight() != 1.0)
groupEl.addAttribute("weight", String.valueOf(group.getWeight()));
if (iShowNames && group.getName() != null)
groupEl.addAttribute("name", group.getName());
groups.put(group, groupEl);
}
groupEl.addElement("student").addAttribute("id", getId("student", student.getId()));
}
}
if (getModel().getProperties().getPropertyInt("MPP.GenTimePert", 0) > 0) {
Element perturbationsEl = root.addElement("perturbations");
int nrChanges = getModel().getProperties().getPropertyInt("MPP.GenTimePert", 0);
List<Lecture> lectures = new ArrayList<Lecture>();
while (lectures.size() < nrChanges) {
Lecture lecture = ToolBox.random(getAssignment().assignedVariables());
if (lecture.isCommitted() || lecture.timeLocations().size() <= 1 || lectures.contains(lecture))
continue;
Placement placement = getAssignment().getValue(lecture);
TimeLocation tl = placement.getTimeLocation();
perturbationsEl.addElement("class").addAttribute("id", getId("class", lecture.getClassId())).addAttribute("days", sDF[7].format(Long.parseLong(Integer.toBinaryString(tl.getDayCode())))).addAttribute("start", String.valueOf(tl.getStartSlot())).addAttribute("length", String.valueOf(tl.getLength()));
lectures.add(lecture);
}
}
for (Map.Entry<Long, String> entry : depts.entrySet()) {
Long id = entry.getKey();
String name = entry.getValue();
if (iShowNames) {
departmentsEl.addElement("department").addAttribute("id", getId("dept", id.toString())).addAttribute("name", name);
}
}
if (departmentsEl.elements().isEmpty())
root.remove(departmentsEl);
}
use of org.cpsolver.coursett.constraint.RoomConstraint in project cpsolver by UniTime.
the class BrokenTimePatterns method getValue.
@Override
public double getValue(Assignment<Lecture, Placement> assignment, Collection<Lecture> variables) {
double ret = 0;
Set<RoomConstraint> constraints = new HashSet<RoomConstraint>();
for (Lecture lect : variables) {
Placement placement = assignment.getValue(lect);
if (placement == null)
continue;
if (placement.isMultiRoom()) {
for (RoomLocation r : placement.getRoomLocations()) {
if (r.getRoomConstraint() != null && constraints.add(r.getRoomConstraint()))
ret += penalty(r.getRoomConstraint().getContext(assignment));
}
} else if (placement.getRoomLocation().getRoomConstraint() != null && constraints.add(placement.getRoomLocation().getRoomConstraint())) {
ret += penalty(placement.getRoomLocation().getRoomConstraint().getContext(assignment));
}
}
return ret;
}
use of org.cpsolver.coursett.constraint.RoomConstraint 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();
}
use of org.cpsolver.coursett.constraint.RoomConstraint in project cpsolver by UniTime.
the class Test method saveOutputCSV.
public static void saveOutputCSV(Solution<Lecture, Placement> s, File file) {
try {
DecimalFormat dx = new DecimalFormat("000");
PrintWriter w = new PrintWriter(new FileWriter(file));
TimetableModel m = (TimetableModel) s.getModel();
int firstDaySlot = m.getProperties().getPropertyInt("General.FirstDaySlot", Constants.DAY_SLOTS_FIRST);
int lastDaySlot = m.getProperties().getPropertyInt("General.LastDaySlot", Constants.DAY_SLOTS_LAST);
int firstWorkDay = m.getProperties().getPropertyInt("General.FirstWorkDay", 0);
int lastWorkDay = m.getProperties().getPropertyInt("General.LastWorkDay", Constants.NR_DAYS_WEEK - 1);
Assignment<Lecture, Placement> a = s.getAssignment();
int idx = 1;
w.println("000." + dx.format(idx++) + " Assigned variables," + a.nrAssignedVariables());
w.println("000." + dx.format(idx++) + " Time [sec]," + sDoubleFormat.format(s.getBestTime()));
w.println("000." + dx.format(idx++) + " Hard student conflicts," + Math.round(m.getCriterion(StudentHardConflict.class).getValue(a)));
if (m.getProperties().getPropertyBoolean("General.UseDistanceConstraints", true))
w.println("000." + dx.format(idx++) + " Distance student conf.," + Math.round(m.getCriterion(StudentDistanceConflict.class).getValue(a)));
w.println("000." + dx.format(idx++) + " Student conflicts," + Math.round(m.getCriterion(StudentConflict.class).getValue(a)));
w.println("000." + dx.format(idx++) + " Committed student conflicts," + Math.round(m.getCriterion(StudentCommittedConflict.class).getValue(a)));
w.println("000." + dx.format(idx++) + " All Student conflicts," + Math.round(m.getCriterion(StudentConflict.class).getValue(a) + m.getCriterion(StudentCommittedConflict.class).getValue(a)));
w.println("000." + dx.format(idx++) + " Time preferences," + sDoubleFormat.format(m.getCriterion(TimePreferences.class).getValue(a)));
w.println("000." + dx.format(idx++) + " Room preferences," + Math.round(m.getCriterion(RoomPreferences.class).getValue(a)));
w.println("000." + dx.format(idx++) + " Useless half-hours," + Math.round(m.getCriterion(UselessHalfHours.class).getValue(a)));
w.println("000." + dx.format(idx++) + " Broken time patterns," + Math.round(m.getCriterion(BrokenTimePatterns.class).getValue(a)));
w.println("000." + dx.format(idx++) + " Too big room," + Math.round(m.getCriterion(TooBigRooms.class).getValue(a)));
w.println("000." + dx.format(idx++) + " Distribution preferences," + sDoubleFormat.format(m.getCriterion(DistributionPreferences.class).getValue(a)));
if (m.getProperties().getPropertyBoolean("General.UseDistanceConstraints", true))
w.println("000." + dx.format(idx++) + " Back-to-back instructor pref.," + Math.round(m.getCriterion(BackToBackInstructorPreferences.class).getValue(a)));
if (m.getProperties().getPropertyBoolean("General.DeptBalancing", true)) {
w.println("000." + dx.format(idx++) + " Dept. balancing penalty," + sDoubleFormat.format(m.getCriterion(DepartmentBalancingPenalty.class).getValue(a)));
}
w.println("000." + dx.format(idx++) + " Same subpart balancing penalty," + sDoubleFormat.format(m.getCriterion(SameSubpartBalancingPenalty.class).getValue(a)));
if (m.getProperties().getPropertyBoolean("General.MPP", false)) {
Map<String, Double> mppInfo = ((UniversalPerturbationsCounter) ((Perturbations) m.getCriterion(Perturbations.class)).getPerturbationsCounter()).getCompactInfo(a, m, false, false);
int pidx = 51;
w.println("000." + dx.format(pidx++) + " Perturbation penalty," + sDoubleFormat.format(m.getCriterion(Perturbations.class).getValue(a)));
w.println("000." + dx.format(pidx++) + " Additional perturbations," + m.perturbVariables(a).size());
int nrPert = 0, nrStudentPert = 0;
for (Lecture lecture : m.variables()) {
if (lecture.getInitialAssignment() != null)
continue;
nrPert++;
nrStudentPert += lecture.classLimit(a);
}
w.println("000." + dx.format(pidx++) + " Given perturbations," + nrPert);
w.println("000." + dx.format(pidx++) + " Given student perturbations," + nrStudentPert);
for (String key : new TreeSet<String>(mppInfo.keySet())) {
Double value = mppInfo.get(key);
w.println("000." + dx.format(pidx++) + " " + key + "," + sDoubleFormat.format(value));
}
}
HashSet<Student> students = new HashSet<Student>();
int enrls = 0;
int minRoomPref = 0, maxRoomPref = 0;
int minGrPref = 0, maxGrPref = 0;
int minTimePref = 0, maxTimePref = 0;
int worstInstrPref = 0;
HashSet<Constraint<Lecture, Placement>> used = new HashSet<Constraint<Lecture, Placement>>();
for (Lecture lecture : m.variables()) {
enrls += (lecture.students() == null ? 0 : lecture.students().size());
students.addAll(lecture.students());
int[] minMaxRoomPref = lecture.getMinMaxRoomPreference();
maxRoomPref += minMaxRoomPref[1] - minMaxRoomPref[0];
double[] minMaxTimePref = lecture.getMinMaxTimePreference();
maxTimePref += minMaxTimePref[1] - minMaxTimePref[0];
for (Constraint<Lecture, Placement> c : lecture.constraints()) {
if (!used.add(c))
continue;
if (c instanceof InstructorConstraint) {
InstructorConstraint ic = (InstructorConstraint) c;
worstInstrPref += ic.getWorstPreference();
}
if (c instanceof GroupConstraint) {
GroupConstraint gc = (GroupConstraint) c;
if (gc.isHard())
continue;
maxGrPref += Math.abs(gc.getPreference()) * (1 + (gc.variables().size() * (gc.variables().size() - 1)) / 2);
}
}
}
int totalCommitedPlacements = 0;
for (Student student : students) {
if (student.getCommitedPlacements() != null)
totalCommitedPlacements += student.getCommitedPlacements().size();
}
HashMap<Long, List<Lecture>> subs = new HashMap<Long, List<Lecture>>();
for (Lecture lecture : m.variables()) {
if (lecture.isCommitted() || lecture.getScheduler() == null)
continue;
List<Lecture> vars = subs.get(lecture.getScheduler());
if (vars == null) {
vars = new ArrayList<Lecture>();
subs.put(lecture.getScheduler(), vars);
}
vars.add(lecture);
}
int bidx = 101;
w.println("000." + dx.format(bidx++) + " Assigned variables max," + m.variables().size());
w.println("000." + dx.format(bidx++) + " Student enrollments," + enrls);
w.println("000." + dx.format(bidx++) + " Student commited enrollments," + totalCommitedPlacements);
w.println("000." + dx.format(bidx++) + " All student enrollments," + (enrls + totalCommitedPlacements));
w.println("000." + dx.format(bidx++) + " Time preferences min," + minTimePref);
w.println("000." + dx.format(bidx++) + " Time preferences max," + maxTimePref);
w.println("000." + dx.format(bidx++) + " Room preferences min," + minRoomPref);
w.println("000." + dx.format(bidx++) + " Room preferences max," + maxRoomPref);
w.println("000." + dx.format(bidx++) + " Useless half-hours max," + (Constants.sPreferenceLevelStronglyDiscouraged * m.getRoomConstraints().size() * (lastDaySlot - firstDaySlot + 1) * (lastWorkDay - firstWorkDay + 1)));
w.println("000." + dx.format(bidx++) + " Too big room max," + (Constants.sPreferenceLevelStronglyDiscouraged * m.variables().size()));
w.println("000." + dx.format(bidx++) + " Distribution preferences min," + minGrPref);
w.println("000." + dx.format(bidx++) + " Distribution preferences max," + maxGrPref);
w.println("000." + dx.format(bidx++) + " Back-to-back instructor pref max," + worstInstrPref);
for (Long scheduler : new TreeSet<Long>(subs.keySet())) {
List<Lecture> vars = subs.get(scheduler);
idx = 001;
bidx = 101;
int nrAssg = 0;
enrls = 0;
int roomPref = 0;
minRoomPref = 0;
maxRoomPref = 0;
double timePref = 0;
minTimePref = 0;
maxTimePref = 0;
double grPref = 0;
minGrPref = 0;
maxGrPref = 0;
long allSC = 0, hardSC = 0, distSC = 0;
int instPref = 0;
worstInstrPref = 0;
int spreadPen = 0, deptSpreadPen = 0;
int tooBigRooms = 0;
int rcs = 0, uselessSlots = 0;
used = new HashSet<Constraint<Lecture, Placement>>();
for (Lecture lecture : vars) {
if (lecture.isCommitted())
continue;
enrls += lecture.students().size();
Placement placement = a.getValue(lecture);
if (placement != null) {
nrAssg++;
}
int[] minMaxRoomPref = lecture.getMinMaxRoomPreference();
minRoomPref += minMaxRoomPref[0];
maxRoomPref += minMaxRoomPref[1];
double[] minMaxTimePref = lecture.getMinMaxTimePreference();
minTimePref += minMaxTimePref[0];
maxTimePref += minMaxTimePref[1];
if (placement != null) {
roomPref += placement.getRoomPreference();
timePref += placement.getTimeLocation().getNormalizedPreference();
tooBigRooms += TooBigRooms.getTooBigRoomPreference(placement);
}
for (Constraint<Lecture, Placement> c : lecture.constraints()) {
if (!used.add(c))
continue;
if (c instanceof InstructorConstraint) {
InstructorConstraint ic = (InstructorConstraint) c;
instPref += ic.getPreference(a);
worstInstrPref += ic.getWorstPreference();
}
if (c instanceof DepartmentSpreadConstraint) {
DepartmentSpreadConstraint dsc = (DepartmentSpreadConstraint) c;
deptSpreadPen += dsc.getPenalty(a);
} else if (c instanceof SpreadConstraint) {
SpreadConstraint sc = (SpreadConstraint) c;
spreadPen += sc.getPenalty(a);
}
if (c instanceof GroupConstraint) {
GroupConstraint gc = (GroupConstraint) c;
if (gc.isHard())
continue;
minGrPref -= Math.abs(gc.getPreference());
maxGrPref += 0;
grPref += Math.min(0, gc.getCurrentPreference(a));
// minGrPref += Math.min(gc.getPreference(), 0);
// maxGrPref += Math.max(gc.getPreference(), 0);
// grPref += gc.getCurrentPreference();
}
if (c instanceof JenrlConstraint) {
JenrlConstraint jc = (JenrlConstraint) c;
if (!jc.isInConflict(a) || !jc.isOfTheSameProblem())
continue;
Lecture l1 = jc.first();
Lecture l2 = jc.second();
allSC += jc.getJenrl();
if (l1.areStudentConflictsHard(l2))
hardSC += jc.getJenrl();
Placement p1 = a.getValue(l1);
Placement p2 = a.getValue(l2);
if (!p1.getTimeLocation().hasIntersection(p2.getTimeLocation()))
distSC += jc.getJenrl();
}
if (c instanceof RoomConstraint) {
RoomConstraint rc = (RoomConstraint) c;
uselessSlots += UselessHalfHours.countUselessSlotsHalfHours(rc.getContext(a)) + BrokenTimePatterns.countUselessSlotsBrokenTimePatterns(rc.getContext(a));
rcs++;
}
}
}
w.println(dx.format(scheduler) + "." + dx.format(idx++) + " Assigned variables," + nrAssg);
w.println(dx.format(scheduler) + "." + dx.format(bidx++) + " Assigned variables max," + vars.size());
w.println(dx.format(scheduler) + "." + dx.format(idx++) + " Hard student conflicts," + hardSC);
w.println(dx.format(scheduler) + "." + dx.format(bidx++) + " Student enrollments," + enrls);
if (m.getProperties().getPropertyBoolean("General.UseDistanceConstraints", true))
w.println(dx.format(scheduler) + "." + dx.format(idx++) + " Distance student conf.," + distSC);
w.println(dx.format(scheduler) + "." + dx.format(idx++) + " Student conflicts," + allSC);
w.println(dx.format(scheduler) + "." + dx.format(idx++) + " Time preferences," + timePref);
w.println(dx.format(scheduler) + "." + dx.format(bidx++) + " Time preferences min," + minTimePref);
w.println(dx.format(scheduler) + "." + dx.format(bidx++) + " Time preferences max," + maxTimePref);
w.println(dx.format(scheduler) + "." + dx.format(idx++) + " Room preferences," + roomPref);
w.println(dx.format(scheduler) + "." + dx.format(bidx++) + " Room preferences min," + minRoomPref);
w.println(dx.format(scheduler) + "." + dx.format(bidx++) + " Room preferences max," + maxRoomPref);
w.println(dx.format(scheduler) + "." + dx.format(idx++) + " Useless half-hours," + uselessSlots);
w.println(dx.format(scheduler) + "." + dx.format(bidx++) + " Useless half-hours max," + (Constants.sPreferenceLevelStronglyDiscouraged * rcs * (lastDaySlot - firstDaySlot + 1) * (lastWorkDay - firstWorkDay + 1)));
w.println(dx.format(scheduler) + "." + dx.format(idx++) + " Too big room," + tooBigRooms);
w.println(dx.format(scheduler) + "." + dx.format(bidx++) + " Too big room max," + (Constants.sPreferenceLevelStronglyDiscouraged * vars.size()));
w.println(dx.format(scheduler) + "." + dx.format(idx++) + " Distribution preferences," + grPref);
w.println(dx.format(scheduler) + "." + dx.format(bidx++) + " Distribution preferences min," + minGrPref);
w.println(dx.format(scheduler) + "." + dx.format(bidx++) + " Distribution preferences max," + maxGrPref);
if (m.getProperties().getPropertyBoolean("General.UseDistanceConstraints", true))
w.println(dx.format(scheduler) + "." + dx.format(idx++) + " Back-to-back instructor pref," + instPref);
w.println(dx.format(scheduler) + "." + dx.format(bidx++) + " Back-to-back instructor pref max," + worstInstrPref);
if (m.getProperties().getPropertyBoolean("General.DeptBalancing", true)) {
w.println(dx.format(scheduler) + "." + dx.format(idx++) + " Department balancing penalty," + sDoubleFormat.format((deptSpreadPen) / 12.0));
}
w.println(dx.format(scheduler) + "." + dx.format(idx++) + " Same subpart balancing penalty," + sDoubleFormat.format((spreadPen) / 12.0));
}
w.flush();
w.close();
} catch (java.io.IOException io) {
sLogger.error(io.getMessage(), io);
}
}
Aggregations