use of org.cpsolver.instructor.constraints.SameInstructorConstraint in project cpsolver by UniTime.
the class InstructorSchedulingModel method load.
/**
* Load the problem (and its solution) from an XML format
* @param document XML document
* @param assignment current assignment
* @return true, if the problem was successfully loaded in
*/
public boolean load(Document document, Assignment<TeachingRequest.Variable, TeachingAssignment> assignment) {
boolean loadInitial = getProperties().getPropertyBoolean("Xml.LoadInitial", true);
boolean loadBest = getProperties().getPropertyBoolean("Xml.LoadBest", true);
boolean loadSolution = getProperties().getPropertyBoolean("Xml.LoadSolution", true);
String defaultBtb = getProperties().getProperty("Defaults.BackToBack", "0");
String defaultSameDays = getProperties().getProperty("Defaults.SameDays", "0");
String defaultSameRoom = getProperties().getProperty("Defaults.SameRoom", "0");
String defaultConjunctive = getProperties().getProperty("Defaults.Conjunctive", "false");
String defaultRequired = getProperties().getProperty("Defaults.Required", "false");
String defaultSameCourse = getProperties().getProperty("Defaults.SameCourse", "R");
String defaultSameCommon = getProperties().getProperty("Defaults.SameCommon", "R");
Element root = document.getRootElement();
if (!"instructor-schedule".equals(root.getName()))
return false;
Map<String, Attribute.Type> types = new HashMap<String, Attribute.Type>();
Map<Long, Attribute> attributes = new HashMap<Long, Attribute>();
Map<Long, Long> parents = new HashMap<Long, Long>();
if (root.element("attributes") != null) {
for (Iterator<?> i = root.element("attributes").elementIterator("type"); i.hasNext(); ) {
Element typeEl = (Element) i.next();
Attribute.Type type = new Attribute.Type(Long.parseLong(typeEl.attributeValue("id")), typeEl.attributeValue("name"), "true".equalsIgnoreCase(typeEl.attributeValue("conjunctive", defaultConjunctive)), "true".equalsIgnoreCase(typeEl.attributeValue("required", defaultRequired)));
addAttributeType(type);
if (type.getTypeName() != null)
types.put(type.getTypeName(), type);
for (Iterator<?> j = typeEl.elementIterator("attribute"); j.hasNext(); ) {
Element attributeEl = (Element) j.next();
Attribute attribute = new Attribute(Long.parseLong(attributeEl.attributeValue("id")), attributeEl.attributeValue("name"), type);
attributes.put(attribute.getAttributeId(), attribute);
if (attributeEl.attributeValue("parent") != null)
parents.put(attribute.getAttributeId(), Long.parseLong(attributeEl.attributeValue("parent")));
}
}
}
Map<Long, Course> courses = new HashMap<Long, Course>();
if (root.element("courses") != null) {
for (Iterator<?> i = root.element("courses").elementIterator("course"); i.hasNext(); ) {
Element courseEl = (Element) i.next();
Course course = new Course(Long.parseLong(courseEl.attributeValue("id")), courseEl.attributeValue("name"));
courses.put(course.getCourseId(), course);
}
}
Map<Long, Instructor> instructors = new HashMap<Long, Instructor>();
for (Iterator<?> i = root.element("instructors").elementIterator("instructor"); i.hasNext(); ) {
Element instructorEl = (Element) i.next();
Instructor instructor = new Instructor(Long.parseLong(instructorEl.attributeValue("id")), instructorEl.attributeValue("externalId"), instructorEl.attributeValue("name"), string2preference(instructorEl.attributeValue("preference")), Float.parseFloat(instructorEl.attributeValue("maxLoad", "0")));
instructor.setBackToBackPreference(Integer.valueOf(instructorEl.attributeValue("btb", defaultBtb)));
instructor.setSameDaysPreference(Integer.valueOf(instructorEl.attributeValue("same-days", defaultSameDays)));
instructor.setSameRoomPreference(Integer.valueOf(instructorEl.attributeValue("same-room", defaultSameRoom)));
for (Iterator<?> j = instructorEl.elementIterator("attribute"); j.hasNext(); ) {
Element f = (Element) j.next();
Long attributeId = Long.valueOf(f.attributeValue("id"));
Attribute attribute = attributes.get(attributeId);
if (attribute == null) {
Attribute.Type type = types.get(f.attributeValue("type"));
if (type == null) {
type = new Attribute.Type(types.size(), f.attributeValue("type"), "true".equalsIgnoreCase(f.attributeValue("conjunctive", defaultConjunctive)), "true".equalsIgnoreCase(f.attributeValue("required", defaultRequired)));
types.put(type.getTypeName(), type);
}
attribute = new Attribute(attributeId, f.attributeValue("name"), type);
attributes.put(attributeId, attribute);
if (f.attributeValue("parent") != null)
parents.put(attribute.getAttributeId(), Long.parseLong(f.attributeValue("parent")));
}
instructor.addAttribute(attribute);
}
for (Iterator<?> j = instructorEl.elementIterator("time"); j.hasNext(); ) {
Element f = (Element) j.next();
Element classEl = f.element("section");
Element courseEl = f.element("course");
TimeLocation time = null;
if (classEl != null) {
time = new EnrolledClass(courseEl == null || courseEl.attributeValue("id") == null ? null : Long.valueOf(courseEl.attributeValue("id")), classEl.attributeValue("id") == null ? null : Long.valueOf(classEl.attributeValue("id")), courseEl == null ? null : courseEl.attributeValue("name"), classEl.attributeValue("type"), classEl.attributeValue("name"), classEl.attributeValue("externalId"), Integer.parseInt(f.attributeValue("days"), 2), Integer.parseInt(f.attributeValue("start")), Integer.parseInt(f.attributeValue("length")), f.attributeValue("datePattern") == null ? null : Long.valueOf(f.attributeValue("datePattern")), f.attributeValue("datePatternName", ""), createBitSet(f.attributeValue("dates")), Integer.parseInt(f.attributeValue("breakTime", "0")), classEl.attributeValue("room"), "instructor".equalsIgnoreCase(classEl.attributeValue("role", "instructor")));
} else {
time = new TimeLocation(Integer.parseInt(f.attributeValue("days"), 2), Integer.parseInt(f.attributeValue("start")), Integer.parseInt(f.attributeValue("length")), 0, 0, f.attributeValue("datePattern") == null ? null : Long.valueOf(f.attributeValue("datePattern")), f.attributeValue("datePatternName", ""), createBitSet(f.attributeValue("dates")), Integer.parseInt(f.attributeValue("breakTime", "0")));
}
if (f.attributeValue("pattern") != null)
time.setTimePatternId(Long.valueOf(f.attributeValue("pattern")));
instructor.addTimePreference(new Preference<TimeLocation>(time, string2preference(f.attributeValue("preference"))));
}
for (Iterator<?> j = instructorEl.elementIterator("course"); j.hasNext(); ) {
Element f = (Element) j.next();
instructor.addCoursePreference(new Preference<Course>(new Course(Long.parseLong(f.attributeValue("id")), f.attributeValue("name")), string2preference(f.attributeValue("preference"))));
}
addInstructor(instructor);
instructors.put(instructor.getInstructorId(), instructor);
}
Map<Long, TeachingRequest> requests = new HashMap<Long, TeachingRequest>();
Map<TeachingRequest, Map<Integer, Instructor>> current = new HashMap<TeachingRequest, Map<Integer, Instructor>>();
Map<TeachingRequest, Map<Integer, Instructor>> best = new HashMap<TeachingRequest, Map<Integer, Instructor>>();
Map<TeachingRequest, Map<Integer, Instructor>> initial = new HashMap<TeachingRequest, Map<Integer, Instructor>>();
for (Iterator<?> i = root.element("teaching-requests").elementIterator("request"); i.hasNext(); ) {
Element requestEl = (Element) i.next();
Element courseEl = requestEl.element("course");
Course course = null;
if (courseEl != null) {
Long courseId = Long.valueOf(courseEl.attributeValue("id"));
course = courses.get(courseId);
if (course == null) {
course = new Course(courseId, courseEl.attributeValue("name"));
}
} else {
course = courses.get(Long.valueOf(requestEl.attributeValue("course")));
}
List<Section> sections = new ArrayList<Section>();
for (Iterator<?> j = requestEl.elementIterator("section"); j.hasNext(); ) {
Element f = (Element) j.next();
TimeLocation time = null;
Element timeEl = f.element("time");
if (timeEl != null) {
time = new TimeLocation(Integer.parseInt(timeEl.attributeValue("days"), 2), Integer.parseInt(timeEl.attributeValue("start")), Integer.parseInt(timeEl.attributeValue("length")), 0, 0, timeEl.attributeValue("datePattern") == null ? null : Long.valueOf(timeEl.attributeValue("datePattern")), timeEl.attributeValue("datePatternName", ""), createBitSet(timeEl.attributeValue("dates")), Integer.parseInt(timeEl.attributeValue("breakTime", "0")));
if (timeEl.attributeValue("pattern") != null)
time.setTimePatternId(Long.valueOf(timeEl.attributeValue("pattern")));
}
Section section = new Section(Long.valueOf(f.attributeValue("id")), f.attributeValue("externalId"), f.attributeValue("type"), f.attributeValue("name"), time, f.attributeValue("room"), "true".equalsIgnoreCase(f.attributeValue("canOverlap", "false")), "true".equalsIgnoreCase(f.attributeValue("common", "false")));
sections.add(section);
}
TeachingRequest request = new TeachingRequest(Long.parseLong(requestEl.attributeValue("id")), Integer.parseInt(requestEl.attributeValue("nrInstructors", "1")), course, Float.valueOf(requestEl.attributeValue("load", "0")), sections, Constants.preference2preferenceLevel(requestEl.attributeValue("sameCourse", defaultSameCourse)), Constants.preference2preferenceLevel(requestEl.attributeValue("sameCommon", defaultSameCommon)));
requests.put(request.getRequestId(), request);
for (Iterator<?> j = requestEl.elementIterator("attribute"); j.hasNext(); ) {
Element f = (Element) j.next();
Long attributeId = Long.valueOf(f.attributeValue("id"));
Attribute attribute = attributes.get(attributeId);
if (attribute == null) {
Attribute.Type type = types.get(f.attributeValue("type"));
if (type == null) {
type = new Attribute.Type(types.size(), f.attributeValue("type"), "true".equalsIgnoreCase(f.attributeValue("conjunctive", defaultConjunctive)), "true".equalsIgnoreCase(f.attributeValue("required", defaultRequired)));
types.put(type.getTypeName(), type);
}
attribute = new Attribute(attributeId, f.attributeValue("name"), type);
attributes.put(attributeId, attribute);
if (f.attributeValue("parent") != null)
parents.put(attribute.getAttributeId(), Long.parseLong(f.attributeValue("parent")));
}
request.addAttributePreference(new Preference<Attribute>(attribute, string2preference(f.attributeValue("preference"))));
}
for (Iterator<?> j = requestEl.elementIterator("instructor"); j.hasNext(); ) {
Element f = (Element) j.next();
Long instructorId = Long.valueOf(f.attributeValue("id"));
Instructor instructor = instructors.get(instructorId);
if (instructor != null)
request.addInstructorPreference(new Preference<Instructor>(instructor, string2preference(f.attributeValue("preference"))));
}
if (loadBest) {
for (Iterator<?> j = requestEl.elementIterator("best-instructor"); j.hasNext(); ) {
Element f = (Element) j.next();
Map<Integer, Instructor> idx2inst = best.get(request);
if (idx2inst == null) {
idx2inst = new HashMap<Integer, Instructor>();
best.put(request, idx2inst);
}
int index = 1 + Integer.parseInt(f.attributeValue("index", String.valueOf(idx2inst.size())));
Instructor instructor = instructors.get(Long.valueOf(f.attributeValue("id")));
if (instructor != null)
idx2inst.put(index, instructor);
}
}
if (loadInitial) {
for (Iterator<?> j = requestEl.elementIterator("initial-instructor"); j.hasNext(); ) {
Element f = (Element) j.next();
Map<Integer, Instructor> idx2inst = initial.get(request);
if (idx2inst == null) {
idx2inst = new HashMap<Integer, Instructor>();
initial.put(request, idx2inst);
}
int index = 1 + Integer.parseInt(f.attributeValue("index", String.valueOf(idx2inst.size())));
Instructor instructor = instructors.get(Long.valueOf(f.attributeValue("id")));
if (instructor != null)
idx2inst.put(index, instructor);
}
}
if (loadSolution) {
for (Iterator<?> j = requestEl.elementIterator("assigned-instructor"); j.hasNext(); ) {
Element f = (Element) j.next();
Map<Integer, Instructor> idx2inst = current.get(request);
if (idx2inst == null) {
idx2inst = new HashMap<Integer, Instructor>();
current.put(request, idx2inst);
}
int index = Integer.parseInt(f.attributeValue("index", String.valueOf(idx2inst.size())));
Instructor instructor = instructors.get(Long.valueOf(f.attributeValue("id")));
if (instructor != null)
idx2inst.put(index, instructor);
}
}
addRequest(request);
}
if (root.element("constraints") != null) {
for (Iterator<?> i = root.element("constraints").elementIterator(); i.hasNext(); ) {
Element constraintEl = (Element) i.next();
Constraint<TeachingRequest.Variable, TeachingAssignment> constraint = null;
if ("same-link".equals(constraintEl.getName())) {
constraint = new SameLinkConstraint((constraintEl.attributeValue("id") == null ? null : Long.valueOf(constraintEl.attributeValue("id"))), constraintEl.attributeValue("name"), constraintEl.attributeValue("preference"));
} else if ("same-instructor".equals(constraintEl.getName())) {
constraint = new SameInstructorConstraint((constraintEl.attributeValue("id") == null ? null : Long.valueOf(constraintEl.attributeValue("id"))), constraintEl.attributeValue("name"), constraintEl.attributeValue("preference"));
}
if (constraint != null) {
for (Iterator<?> j = constraintEl.elementIterator("request"); j.hasNext(); ) {
Element f = (Element) j.next();
TeachingRequest request = requests.get(Long.valueOf(f.attributeValue("id")));
if (request != null) {
int index = Integer.valueOf(f.attributeValue("index", "0"));
if (index >= 0 && index < request.getNrInstructors())
constraint.addVariable(request.getVariables()[index]);
}
}
addConstraint(constraint);
}
}
}
for (Map.Entry<Long, Long> e : parents.entrySet()) attributes.get(e.getKey()).setParentAttribute(attributes.get(e.getValue()));
for (Map.Entry<TeachingRequest, Map<Integer, Instructor>> e1 : best.entrySet()) for (Map.Entry<Integer, Instructor> e2 : e1.getValue().entrySet()) if (e2.getKey() >= 0 && e2.getKey() < e1.getKey().getNrInstructors()) {
TeachingRequest.Variable variable = e1.getKey().getVariables()[e2.getKey()];
variable.setBestAssignment(new TeachingAssignment(variable, e2.getValue()), 0l);
}
for (Map.Entry<TeachingRequest, Map<Integer, Instructor>> e1 : initial.entrySet()) for (Map.Entry<Integer, Instructor> e2 : e1.getValue().entrySet()) if (e2.getKey() >= 0 && e2.getKey() < e1.getKey().getNrInstructors()) {
TeachingRequest.Variable variable = e1.getKey().getVariables()[e2.getKey()];
variable.setInitialAssignment(new TeachingAssignment(variable, e2.getValue()));
}
if (!current.isEmpty()) {
for (Map.Entry<TeachingRequest, Map<Integer, Instructor>> e1 : current.entrySet()) for (Map.Entry<Integer, Instructor> e2 : e1.getValue().entrySet()) if (e2.getKey() >= 0 && e2.getKey() < e1.getKey().getNrInstructors()) {
TeachingRequest.Variable variable = e1.getKey().getVariables()[e2.getKey()];
TeachingAssignment ta = new TeachingAssignment(variable, e2.getValue());
Set<TeachingAssignment> conf = conflictValues(assignment, ta);
if (conf.isEmpty()) {
assignment.assign(0, ta);
} else {
sLog.error("Unable to assign " + ta.getName() + " to " + variable.getName());
sLog.error("Conflicts:" + ToolBox.dict2string(conflictConstraints(assignment, ta), 2));
}
}
}
return true;
}
use of org.cpsolver.instructor.constraints.SameInstructorConstraint in project cpsolver by UniTime.
the class InstructorSchedulingModel method save.
/**
* Store the problem (together with its solution) in an XML format
* @param assignment current assignment
* @return XML document with the problem
*/
public Document save(Assignment<TeachingRequest.Variable, TeachingAssignment> assignment) {
DecimalFormat sDF7 = new DecimalFormat("0000000");
boolean saveInitial = getProperties().getPropertyBoolean("Xml.SaveInitial", false);
boolean saveBest = getProperties().getPropertyBoolean("Xml.SaveBest", false);
boolean saveSolution = getProperties().getPropertyBoolean("Xml.SaveSolution", true);
Document document = DocumentHelper.createDocument();
if (assignment != null && assignment.nrAssignedVariables() > 0) {
StringBuffer comments = new StringBuffer("Solution Info:\n");
Map<String, String> solutionInfo = (getProperties().getPropertyBoolean("Xml.ExtendedInfo", true) ? getExtendedInfo(assignment) : getInfo(assignment));
for (String key : new TreeSet<String>(solutionInfo.keySet())) {
String value = solutionInfo.get(key);
comments.append(" " + key + ": " + value + "\n");
}
document.addComment(comments.toString());
}
Element root = document.addElement("instructor-schedule");
root.addAttribute("version", "1.0");
root.addAttribute("created", String.valueOf(new Date()));
Element typesEl = root.addElement("attributes");
for (Attribute.Type type : getAttributeTypes()) {
Element typeEl = typesEl.addElement("type");
if (type.getTypeId() != null)
typeEl.addAttribute("id", String.valueOf(type.getTypeId()));
typeEl.addAttribute("name", type.getTypeName());
typeEl.addAttribute("conjunctive", type.isConjunctive() ? "true" : "false");
typeEl.addAttribute("required", type.isRequired() ? "true" : "false");
Set<Attribute> attributes = new HashSet<Attribute>();
for (TeachingRequest request : getRequests()) {
for (Preference<Attribute> pref : request.getAttributePreferences()) {
Attribute attribute = pref.getTarget();
if (type.equals(attribute.getType()) && attributes.add(attribute)) {
Element attributeEl = typeEl.addElement("attribute");
if (attribute.getAttributeId() != null)
attributeEl.addAttribute("id", String.valueOf(attribute.getAttributeId()));
attributeEl.addAttribute("name", attribute.getAttributeName());
if (attribute.getParentAttribute() != null && attribute.getParentAttribute().getAttributeId() != null)
attributeEl.addAttribute("parent", String.valueOf(attribute.getParentAttribute().getAttributeId()));
}
}
for (Instructor instructor : getInstructors()) {
for (Attribute attribute : instructor.getAttributes()) {
if (type.equals(attribute.getType()) && attributes.add(attribute)) {
Element attributeEl = typeEl.addElement("attribute");
if (attribute.getAttributeId() != null)
attributeEl.addAttribute("id", String.valueOf(attribute.getAttributeId()));
attributeEl.addAttribute("name", attribute.getAttributeName());
if (attribute.getParentAttribute() != null && attribute.getParentAttribute().getAttributeId() != null)
attributeEl.addAttribute("parent", String.valueOf(attribute.getParentAttribute().getAttributeId()));
}
}
}
}
}
Element requestsEl = root.addElement("teaching-requests");
for (TeachingRequest request : getRequests()) {
Element requestEl = requestsEl.addElement("request");
requestEl.addAttribute("id", String.valueOf(request.getRequestId()));
if (request.getNrInstructors() != 1)
requestEl.addAttribute("nrInstructors", String.valueOf(request.getNrInstructors()));
Course course = request.getCourse();
Element courseEl = requestEl.addElement("course");
if (course.getCourseId() != null)
courseEl.addAttribute("id", String.valueOf(course.getCourseId()));
if (course.getCourseName() != null)
courseEl.addAttribute("name", String.valueOf(course.getCourseName()));
for (Section section : request.getSections()) {
Element sectionEl = requestEl.addElement("section");
sectionEl.addAttribute("id", String.valueOf(section.getSectionId()));
if (section.getExternalId() != null && !section.getExternalId().isEmpty())
sectionEl.addAttribute("externalId", section.getExternalId());
if (section.getSectionType() != null && !section.getSectionType().isEmpty())
sectionEl.addAttribute("type", section.getSectionType());
if (section.getSectionName() != null && !section.getSectionName().isEmpty())
sectionEl.addAttribute("name", section.getSectionName());
if (section.hasTime()) {
TimeLocation tl = section.getTime();
Element timeEl = sectionEl.addElement("time");
timeEl.addAttribute("days", sDF7.format(Long.parseLong(Integer.toBinaryString(tl.getDayCode()))));
timeEl.addAttribute("start", String.valueOf(tl.getStartSlot()));
timeEl.addAttribute("length", String.valueOf(tl.getLength()));
if (tl.getBreakTime() != 0)
timeEl.addAttribute("breakTime", String.valueOf(tl.getBreakTime()));
if (tl.getTimePatternId() != null)
timeEl.addAttribute("pattern", tl.getTimePatternId().toString());
if (tl.getDatePatternId() != null)
timeEl.addAttribute("datePattern", tl.getDatePatternId().toString());
if (tl.getDatePatternName() != null && !tl.getDatePatternName().isEmpty())
timeEl.addAttribute("datePatternName", tl.getDatePatternName());
if (tl.getWeekCode() != null)
timeEl.addAttribute("dates", bitset2string(tl.getWeekCode()));
timeEl.setText(tl.getLongName(false));
}
if (section.hasRoom())
sectionEl.addAttribute("room", section.getRoom());
if (section.isAllowOverlap())
sectionEl.addAttribute("canOverlap", "true");
if (section.isCommon())
sectionEl.addAttribute("common", "true");
}
requestEl.addAttribute("load", sDoubleFormat.format(request.getLoad()));
requestEl.addAttribute("sameCourse", Constants.preferenceLevel2preference(request.getSameCoursePreference()));
requestEl.addAttribute("sameCommon", Constants.preferenceLevel2preference(request.getSameCommonPreference()));
for (Preference<Attribute> pref : request.getAttributePreferences()) {
Element attributeEl = requestEl.addElement("attribute");
if (pref.getTarget().getAttributeId() != null)
attributeEl.addAttribute("id", String.valueOf(pref.getTarget().getAttributeId()));
attributeEl.addAttribute("name", pref.getTarget().getAttributeName());
attributeEl.addAttribute("type", pref.getTarget().getType().getTypeName());
attributeEl.addAttribute("preference", (pref.isRequired() ? "R" : pref.isProhibited() ? "P" : String.valueOf(pref.getPreference())));
if (pref.getTarget().getParentAttribute() != null && pref.getTarget().getParentAttribute().getAttributeId() != null)
attributeEl.addAttribute("parent", String.valueOf(pref.getTarget().getParentAttribute().getAttributeId()));
}
for (Preference<Instructor> pref : request.getInstructorPreferences()) {
Element instructorEl = requestEl.addElement("instructor");
instructorEl.addAttribute("id", String.valueOf(pref.getTarget().getInstructorId()));
if (pref.getTarget().hasExternalId())
instructorEl.addAttribute("externalId", pref.getTarget().getExternalId());
if (pref.getTarget().hasName())
instructorEl.addAttribute("name", pref.getTarget().getName());
instructorEl.addAttribute("preference", (pref.isRequired() ? "R" : pref.isProhibited() ? "P" : String.valueOf(pref.getPreference())));
}
if (saveBest)
for (TeachingRequest.Variable variable : request.getVariables()) {
if (variable.getBestAssignment() != null) {
Instructor instructor = variable.getBestAssignment().getInstructor();
Element instructorEl = requestEl.addElement("best-instructor");
instructorEl.addAttribute("id", String.valueOf(instructor.getInstructorId()));
if (request.getNrInstructors() != 1)
instructorEl.addAttribute("index", String.valueOf(variable.getInstructorIndex()));
if (instructor.hasExternalId())
instructorEl.addAttribute("externalId", instructor.getExternalId());
if (instructor.hasName())
instructorEl.addAttribute("name", instructor.getName());
}
}
if (saveInitial)
for (TeachingRequest.Variable variable : request.getVariables()) {
if (variable.getInitialAssignment() != null) {
Instructor instructor = variable.getInitialAssignment().getInstructor();
Element instructorEl = requestEl.addElement("initial-instructor");
instructorEl.addAttribute("id", String.valueOf(instructor.getInstructorId()));
if (request.getNrInstructors() != 1)
instructorEl.addAttribute("index", String.valueOf(variable.getInstructorIndex()));
if (instructor.hasExternalId())
instructorEl.addAttribute("externalId", instructor.getExternalId());
if (instructor.hasName())
instructorEl.addAttribute("name", instructor.getName());
}
}
if (saveSolution)
for (TeachingRequest.Variable variable : request.getVariables()) {
TeachingAssignment ta = assignment.getValue(variable);
if (ta != null) {
Instructor instructor = ta.getInstructor();
Element instructorEl = requestEl.addElement("assigned-instructor");
instructorEl.addAttribute("id", String.valueOf(instructor.getInstructorId()));
if (request.getNrInstructors() != 1)
instructorEl.addAttribute("index", String.valueOf(variable.getInstructorIndex()));
if (instructor.hasExternalId())
instructorEl.addAttribute("externalId", instructor.getExternalId());
if (instructor.hasName())
instructorEl.addAttribute("name", instructor.getName());
}
}
}
Element instructorsEl = root.addElement("instructors");
for (Instructor instructor : getInstructors()) {
Element instructorEl = instructorsEl.addElement("instructor");
instructorEl.addAttribute("id", String.valueOf(instructor.getInstructorId()));
if (instructor.hasExternalId())
instructorEl.addAttribute("externalId", instructor.getExternalId());
if (instructor.hasName())
instructorEl.addAttribute("name", instructor.getName());
if (instructor.getPreference() != 0)
instructorEl.addAttribute("preference", String.valueOf(instructor.getPreference()));
if (instructor.getBackToBackPreference() != 0)
instructorEl.addAttribute("btb", String.valueOf(instructor.getBackToBackPreference()));
if (instructor.getSameDaysPreference() != 0)
instructorEl.addAttribute("same-days", String.valueOf(instructor.getSameDaysPreference()));
if (instructor.getSameRoomPreference() != 0)
instructorEl.addAttribute("same-room", String.valueOf(instructor.getSameRoomPreference()));
for (Attribute attribute : instructor.getAttributes()) {
Element attributeEl = instructorEl.addElement("attribute");
if (attribute.getAttributeId() != null)
attributeEl.addAttribute("id", String.valueOf(attribute.getAttributeId()));
attributeEl.addAttribute("name", attribute.getAttributeName());
attributeEl.addAttribute("type", attribute.getType().getTypeName());
if (attribute.getParentAttribute() != null && attribute.getParentAttribute().getAttributeId() != null)
attributeEl.addAttribute("parent", String.valueOf(attribute.getParentAttribute().getAttributeId()));
}
instructorEl.addAttribute("maxLoad", sDoubleFormat.format(instructor.getMaxLoad()));
for (Preference<TimeLocation> tp : instructor.getTimePreferences()) {
Element timeEl = instructorEl.addElement("time");
TimeLocation tl = tp.getTarget();
timeEl.addAttribute("days", sDF7.format(Long.parseLong(Integer.toBinaryString(tl.getDayCode()))));
timeEl.addAttribute("start", String.valueOf(tl.getStartSlot()));
timeEl.addAttribute("length", String.valueOf(tl.getLength()));
if (tl.getBreakTime() != 0)
timeEl.addAttribute("breakTime", String.valueOf(tl.getBreakTime()));
if (tl.getTimePatternId() != null)
timeEl.addAttribute("pattern", tl.getTimePatternId().toString());
if (tl.getDatePatternId() != null)
timeEl.addAttribute("datePattern", tl.getDatePatternId().toString());
if (tl.getDatePatternName() != null && !tl.getDatePatternName().isEmpty())
timeEl.addAttribute("datePatternName", tl.getDatePatternName());
if (tl.getWeekCode() != null)
timeEl.addAttribute("dates", bitset2string(tl.getWeekCode()));
timeEl.addAttribute("preference", tp.isProhibited() ? "P" : tp.isRequired() ? "R" : String.valueOf(tp.getPreference()));
if (tp.getTarget() instanceof EnrolledClass) {
Element classEl = timeEl.addElement("section");
Element courseEl = null;
EnrolledClass ec = (EnrolledClass) tp.getTarget();
if (ec.getCourseId() != null || ec.getCourse() != null) {
courseEl = timeEl.addElement("course");
if (ec.getCourseId() != null)
courseEl.addAttribute("id", String.valueOf(ec.getCourseId()));
if (ec.getCourse() != null)
courseEl.addAttribute("name", ec.getCourse());
}
if (ec.getClassId() != null)
classEl.addAttribute("id", String.valueOf(ec.getClassId()));
if (ec.getType() != null)
classEl.addAttribute("type", ec.getType());
if (ec.getSection() != null)
classEl.addAttribute("name", ec.getSection());
if (ec.getExternalId() != null)
classEl.addAttribute("externalId", ec.getExternalId());
if (ec.getRoom() != null)
classEl.addAttribute("room", ec.getRoom());
classEl.addAttribute("role", ec.isInstructor() ? "instructor" : "student");
} else {
timeEl.setText(tl.getLongName(false));
}
}
for (Preference<Course> cp : instructor.getCoursePreferences()) {
Element courseEl = instructorEl.addElement("course");
Course course = cp.getTarget();
if (course.getCourseId() != null)
courseEl.addAttribute("id", String.valueOf(course.getCourseId()));
if (course.getCourseName() != null)
courseEl.addAttribute("name", String.valueOf(course.getCourseName()));
courseEl.addAttribute("preference", cp.isProhibited() ? "P" : cp.isRequired() ? "R" : String.valueOf(cp.getPreference()));
}
}
Element constraintsEl = root.addElement("constraints");
for (Constraint<TeachingRequest.Variable, TeachingAssignment> c : constraints()) {
if (c instanceof SameInstructorConstraint) {
SameInstructorConstraint si = (SameInstructorConstraint) c;
Element sameInstEl = constraintsEl.addElement("same-instructor");
if (si.getConstraintId() != null)
sameInstEl.addAttribute("id", String.valueOf(si.getConstraintId()));
if (si.getName() != null)
sameInstEl.addAttribute("name", si.getName());
sameInstEl.addAttribute("preference", Constants.preferenceLevel2preference(si.getPreference()));
for (TeachingRequest.Variable request : c.variables()) {
Element assignmentEl = sameInstEl.addElement("request");
assignmentEl.addAttribute("id", String.valueOf(request.getRequest().getRequestId()));
if (request.getRequest().getNrInstructors() != 1)
assignmentEl.addAttribute("index", String.valueOf(request.getInstructorIndex()));
}
} else if (c instanceof SameLinkConstraint) {
SameLinkConstraint si = (SameLinkConstraint) c;
Element sameInstEl = constraintsEl.addElement("same-link");
if (si.getConstraintId() != null)
sameInstEl.addAttribute("id", String.valueOf(si.getConstraintId()));
if (si.getName() != null)
sameInstEl.addAttribute("name", si.getName());
sameInstEl.addAttribute("preference", Constants.preferenceLevel2preference(si.getPreference()));
for (TeachingRequest.Variable request : c.variables()) {
Element assignmentEl = sameInstEl.addElement("request");
assignmentEl.addAttribute("id", String.valueOf(request.getRequest().getRequestId()));
if (request.getRequest().getNrInstructors() != 1)
assignmentEl.addAttribute("index", String.valueOf(request.getInstructorIndex()));
}
}
}
return document;
}
use of org.cpsolver.instructor.constraints.SameInstructorConstraint in project cpsolver by UniTime.
the class MathTest method load.
@Override
protected boolean load(File dir, Assignment<TeachingRequest.Variable, TeachingAssignment> assignment) {
if (!dir.isDirectory())
return super.load(dir, assignment);
try {
String line = null;
BufferedReader r = new BufferedReader(new FileReader(new File(dir, "courses.csv")));
Map<String, Course> courses = new HashMap<String, Course>();
Map<Long, List<TeachingRequest>> id2classes = new HashMap<Long, List<TeachingRequest>>();
Map<String, List<TeachingRequest>> link2classes = new HashMap<String, List<TeachingRequest>>();
long assId = 0, reqId = 0;
while ((line = r.readLine()) != null) {
if (line.trim().isEmpty())
continue;
String[] fields = line.split(",");
Long id = Long.valueOf(fields[0]);
String course = fields[1];
String section = fields[2];
int idx = 3;
int dayCode = 0;
idx: while (idx < fields.length && (idx == 3 || fields[idx].length() == 1)) {
for (int i = 0; i < fields[idx].length(); i++) {
switch(fields[idx].charAt(i)) {
case 'M':
dayCode += Constants.DAY_CODES[0];
break;
case 'T':
dayCode += Constants.DAY_CODES[1];
break;
case 'W':
dayCode += Constants.DAY_CODES[2];
break;
case 'R':
dayCode += Constants.DAY_CODES[3];
break;
case 'F':
dayCode += Constants.DAY_CODES[4];
break;
default:
break idx;
}
}
idx++;
}
int startSlot = 0;
if (dayCode > 0) {
int time = Integer.parseInt(fields[idx++]);
startSlot = 12 * (time / 100) + (time % 100) / 5;
}
String room = null;
if (idx < fields.length)
room = fields[idx++];
String link = null;
if (idx < fields.length)
link = fields[idx++];
int length = 12;
if (idx < fields.length) {
int time = Integer.parseInt(fields[idx++]);
int endSlot = 12 * (time / 100) + (time % 100) / 5;
length = endSlot - startSlot;
if (length == 10)
length = 12;
else if (length == 15)
length = 18;
}
List<Section> sections = new ArrayList<Section>();
TimeLocation time = new TimeLocation(dayCode, startSlot, length, 0, 0.0, 0, null, "", null, (length == 18 ? 15 : 10));
sections.add(new Section(assId++, id.toString(), section, course + " " + section + " " + time.getName(true) + (room == null ? "" : " " + room), time, room, false, false));
Course c = courses.get(course);
if (c == null) {
c = new Course(courses.size(), course);
courses.put(course, c);
}
TeachingRequest clazz = new TeachingRequest(reqId++, 1, c, 0f, sections, Constants.sPreferenceLevelRequired, Constants.sPreferenceLevelNeutral);
addRequest(clazz);
List<TeachingRequest> classes = id2classes.get(id);
if (classes == null) {
classes = new ArrayList<TeachingRequest>();
id2classes.put(id, classes);
}
classes.add(clazz);
if (link != null && !link.isEmpty()) {
List<TeachingRequest> linked = link2classes.get(course + "-" + link);
if (linked == null) {
linked = new ArrayList<TeachingRequest>();
link2classes.put(course + "-" + link, linked);
}
linked.add(clazz);
}
}
for (Map.Entry<Long, List<TeachingRequest>> e : id2classes.entrySet()) {
Long id = e.getKey();
List<TeachingRequest> classes = e.getValue();
if (classes.size() > 1) {
SameInstructorConstraint sa = new SameInstructorConstraint(id, "A" + id.toString(), Constants.sPreferenceRequired);
for (TeachingRequest c : classes) sa.addVariable(c.getVariables()[0]);
addConstraint(sa);
}
}
for (Map.Entry<String, List<TeachingRequest>> e : link2classes.entrySet()) {
String link = e.getKey();
List<TeachingRequest> classes = e.getValue();
if (classes.size() > 1) {
SameLinkConstraint sa = new SameLinkConstraint(null, link, Constants.sPreferencePreferred);
for (TeachingRequest c : classes) sa.addVariable(c.getVariables()[0]);
addConstraint(sa);
}
}
Attribute.Type level = new Attribute.Type(0l, "Level", false, true);
addAttributeType(level);
Map<String, Attribute> code2attribute = new HashMap<String, Attribute>();
r = new BufferedReader(new FileReader(new File(dir, "level_codes.csv")));
String[] codes = r.readLine().split(",");
while ((line = r.readLine()) != null) {
if (line.trim().isEmpty())
continue;
String[] fields = line.split(",");
String code = fields[0];
if (code.startsWith("\"") && code.endsWith("\""))
code = code.substring(1, code.length() - 1);
Attribute attribute = code2attribute.get(code);
if (attribute == null) {
attribute = new Attribute(code2attribute.size(), code, level);
code2attribute.put(code, attribute);
}
for (int i = 1; i < codes.length; i++) {
int pref = Integer.parseInt(fields[i]);
if (pref > 0)
for (TeachingRequest clazz : getRequests()) {
if (clazz.getCourse().getCourseName().contains(codes[i]))
clazz.addAttributePreference(new Preference<Attribute>(attribute, -pref));
}
}
}
r = new BufferedReader(new FileReader(new File(dir, "hours_per_course.csv")));
while ((line = r.readLine()) != null) {
if (line.trim().isEmpty())
continue;
String[] fields = line.split(",");
for (TeachingRequest clazz : getRequests()) {
if (clazz.getCourse().getCourseName().contains(fields[0]))
clazz.setLoad(Float.parseFloat(fields[1]));
}
}
String defaultCode = getProperties().getProperty("TA.DefaultLevelCode", "XXX");
Attribute defaultAttribute = code2attribute.get(defaultCode);
if (defaultAttribute == null) {
defaultAttribute = new Attribute(code2attribute.size(), defaultCode, level);
code2attribute.put(defaultCode, defaultAttribute);
}
for (TeachingRequest.Variable clazz : variables()) {
sLog.info("Added class " + toString(clazz));
if (clazz.getRequest().getAttributePreferences().isEmpty()) {
sLog.error("No level: " + toString(clazz));
clazz.getRequest().addAttributePreference(new Preference<Attribute>(defaultAttribute, -1));
}
if (clazz.getRequest().getLoad() == 0.0) {
sLog.error("No load: " + toString(clazz));
clazz.getRequest().setLoad(getProperties().getPropertyFloat("TA.DefaultLoad", 10f));
}
}
r = new BufferedReader(new FileReader(new File(dir, "students.csv")));
Set<String> studentIds = new HashSet<String>();
double studentMaxLoad = 0.0;
while ((line = r.readLine()) != null) {
if (line.trim().isEmpty())
continue;
String[] fields = line.split(",");
if ("puid".equals(fields[0]))
continue;
int idx = 0;
String id = fields[idx++];
if (!studentIds.add(id)) {
sLog.error("Student " + id + " is two or more times in the file.");
}
boolean[] av = new boolean[50];
for (int i = 0; i < 50; i++) av[i] = "1".equals(fields[idx++]);
List<String> prefs = new ArrayList<String>();
for (int i = 0; i < 3; i++) {
String p = fields[idx++].replace("Large lecture", "LEC").replace("Lecture", "LEC").replace("Recitation", "REC");
if (p.startsWith("MA "))
p = p.substring(3);
if ("I have no preference".equals(p))
continue;
prefs.add(p);
}
boolean grad = "Yes".equals(fields[idx++]);
int b2b = Integer.parseInt(fields[idx++]);
float maxLoad = Float.parseFloat(fields[idx++]);
if (maxLoad == 0)
maxLoad = getProperties().getPropertyFloat("TA.DefaultMaxLoad", 20f);
String code = (idx < fields.length ? fields[idx++] : null);
Instructor instructor = new Instructor(Long.valueOf(id.replace("-", "")), id, null, grad ? Constants.sPreferenceLevelNeutral : Constants.sPreferenceLevelDiscouraged, maxLoad);
for (int i = 0; i < prefs.size(); i++) {
String pref = prefs.get(i);
if (pref.indexOf(' ') > 0)
pref = pref.substring(0, pref.indexOf(' '));
Course c = courses.get(pref);
if (c == null) {
c = new Course(courses.size(), pref);
courses.put(pref, c);
}
instructor.addCoursePreference(new Preference<Course>(c, i == 0 ? -10 : i == 1 ? -8 : -5));
}
if (code != null) {
Attribute attribute = code2attribute.get(code);
if (attribute == null) {
attribute = new Attribute(code2attribute.size(), code, level);
code2attribute.put(code, attribute);
}
instructor.addAttribute(attribute);
}
if (b2b == 1)
instructor.setBackToBackPreference(Constants.sPreferenceLevelPreferred);
else if (b2b == -1)
instructor.setBackToBackPreference(Constants.sPreferenceLevelDiscouraged);
for (int d = 0; d < 5; d++) {
int f = -1;
for (int t = 0; t < 10; t++) {
if (!av[10 * d + t]) {
if (f < 0)
f = t;
} else {
if (f >= 0) {
instructor.addTimePreference(new Preference<TimeLocation>(new TimeLocation(Constants.DAY_CODES[d], 90 + 12 * f, (t - f) * 12, 0, 0.0, null, "", null, 0), Constants.sPreferenceLevelProhibited));
f = -1;
}
}
}
if (f >= 0) {
instructor.addTimePreference(new Preference<TimeLocation>(new TimeLocation(Constants.DAY_CODES[d], 90 + 12 * f, (10 - f) * 12, 0, 0.0, null, "", null, 0), Constants.sPreferenceLevelProhibited));
f = -1;
}
}
if (instructor.getMaxLoad() > 0) {
addInstructor(instructor);
sLog.info("Added student " + toString(instructor));
int nrClasses = 0;
for (TeachingRequest.Variable req : variables()) {
if (instructor.canTeach(req.getRequest()) && !req.getRequest().getAttributePreference(instructor).isProhibited()) {
sLog.info(" -- " + toString(req) + "," + (-req.getRequest().getAttributePreference(instructor).getPreferenceInt()) + "," + (-instructor.getCoursePreference(req.getCourse()).getPreference()));
nrClasses++;
}
}
if (nrClasses == 0) {
sLog.info(" -- no courses available");
}
studentMaxLoad += instructor.getMaxLoad();
} else {
sLog.info("Ignoring student " + instructor);
if (instructor.getMaxLoad() == 0)
sLog.info(" -- zero max load");
else
sLog.info(" -- no courses available");
}
}
double totalLoad = 0.0;
for (TeachingRequest.Variable clazz : variables()) {
if (clazz.values(getEmptyAssignment()).isEmpty())
sLog.error("No values: " + toString(clazz));
totalLoad += clazz.getRequest().getLoad();
}
Map<String, Double> studentLevel2load = new HashMap<String, Double>();
for (Instructor instructor : getInstructors()) {
Set<Attribute> levels = instructor.getAttributes(level);
String studentLevel = (levels.isEmpty() ? "null" : levels.iterator().next().getAttributeName());
Double load = studentLevel2load.get(studentLevel);
studentLevel2load.put(studentLevel, instructor.getMaxLoad() + (load == null ? 0.0 : load));
}
sLog.info("Student max loads: (total: " + sDoubleFormat.format(studentMaxLoad) + ")");
for (String studentLevel : new TreeSet<String>(studentLevel2load.keySet())) {
Double load = studentLevel2load.get(studentLevel);
sLog.info(" " + studentLevel + ": " + sDoubleFormat.format(load));
}
Map<String, Double> clazzLevel2load = new HashMap<String, Double>();
for (TeachingRequest.Variable clazz : variables()) {
String classLevel = null;
TreeSet<String> levels = new TreeSet<String>();
for (Preference<Attribute> ap : clazz.getRequest().getAttributePreferences()) levels.add(ap.getTarget().getAttributeName());
for (String l : levels) {
classLevel = (classLevel == null ? "" : classLevel + ",") + l;
}
if (classLevel == null)
classLevel = "null";
if (clazz.getId() < 0)
classLevel = clazz.getName();
Double load = clazzLevel2load.get(level);
clazzLevel2load.put(classLevel, clazz.getRequest().getLoad() + (load == null ? 0.0 : load));
}
sLog.info("Class loads: (total: " + sDoubleFormat.format(totalLoad) + ")");
for (String classLevel : new TreeSet<String>(clazzLevel2load.keySet())) {
Double load = clazzLevel2load.get(classLevel);
sLog.info(" " + level + ": " + sDoubleFormat.format(load));
}
return true;
} catch (IOException e) {
sLog.error("Failed to load the problem: " + e.getMessage(), e);
return false;
}
}
Aggregations