use of org.cpsolver.studentsct.model.Request in project cpsolver by UniTime.
the class TimeOverlapConflictTable method createTable.
/**
* Create report
*
* @param assignment current assignment
* @param includeLastLikeStudents
* true, if last-like students should be included (i.e.,
* {@link Student#isDummy()} is true)
* @param includeRealStudents
* true, if real students should be included (i.e.,
* {@link Student#isDummy()} is false)
* @param useAmPm use 12-hour format
* @return report as comma separated text file
*/
public CSVFile createTable(Assignment<Request, Enrollment> assignment, boolean includeLastLikeStudents, boolean includeRealStudents, boolean useAmPm) {
CSVFile csv = new CSVFile();
csv.setHeader(new CSVFile.CSVField[] { new CSVFile.CSVField("Course"), new CSVFile.CSVField("Total\nConflicts"), new CSVFile.CSVField("Class"), new CSVFile.CSVField("Meeting Time"), new CSVFile.CSVField("Time\nConflicts"), new CSVFile.CSVField("% of Total\nConflicts"), new CSVFile.CSVField("Conflicting\nClass"), new CSVFile.CSVField("Conflicting\nMeeting Time"), new CSVFile.CSVField("Overlap [min]"), new CSVFile.CSVField("Joined\nConflicts"), new CSVFile.CSVField("% of Total\nConflicts") });
Set<Conflict> confs = new HashSet<Conflict>();
for (Request r1 : getModel().variables()) {
Enrollment e1 = assignment.getValue(r1);
if (e1 == null || r1 instanceof FreeTimeRequest)
continue;
for (Request r2 : r1.getStudent().getRequests()) {
Enrollment e2 = assignment.getValue(r2);
if (r2 instanceof FreeTimeRequest) {
FreeTimeRequest ft = (FreeTimeRequest) r2;
confs.addAll(iTOC.conflicts(e1, ft.createEnrollment()));
} else if (e2 != null && r1.getId() < r2.getId()) {
confs.addAll(iTOC.conflicts(e1, e2));
}
}
}
HashMap<Course, Set<Long>> totals = new HashMap<Course, Set<Long>>();
HashMap<CourseSection, Map<CourseSection, Double>> conflictingPairs = new HashMap<CourseSection, Map<CourseSection, Double>>();
HashMap<CourseSection, Set<Long>> sectionOverlaps = new HashMap<CourseSection, Set<Long>>();
for (Conflict conflict : confs) {
if (conflict.getStudent().isDummy() && !includeLastLikeStudents)
continue;
if (!conflict.getStudent().isDummy() && !includeRealStudents)
continue;
if (conflict.getR1() == null || conflict.getR1() instanceof FreeTimeRequest || conflict.getR2() == null || conflict.getR2() instanceof FreeTimeRequest)
continue;
Section s1 = (Section) conflict.getS1(), s2 = (Section) conflict.getS2();
Request r1 = conflict.getR1();
Course c1 = assignment.getValue(conflict.getR1()).getCourse();
Request r2 = conflict.getR2();
Course c2 = assignment.getValue(conflict.getR2()).getCourse();
CourseSection a = new CourseSection(c1, s1);
CourseSection b = new CourseSection(c2, s2);
Set<Long> students = totals.get(c1);
if (students == null) {
students = new HashSet<Long>();
totals.put(c1, students);
}
students.add(r1.getStudent().getId());
students = totals.get(c2);
if (students == null) {
students = new HashSet<Long>();
totals.put(c2, students);
}
students.add(r2.getStudent().getId());
Set<Long> total = sectionOverlaps.get(a);
if (total == null) {
total = new HashSet<Long>();
sectionOverlaps.put(a, total);
}
total.add(r1.getStudent().getId());
Map<CourseSection, Double> pair = conflictingPairs.get(a);
if (pair == null) {
pair = new HashMap<CourseSection, Double>();
conflictingPairs.put(a, pair);
}
Double prev = pair.get(b);
pair.put(b, r2.getWeight() + (prev == null ? 0.0 : prev.doubleValue()));
total = sectionOverlaps.get(b);
if (total == null) {
total = new HashSet<Long>();
sectionOverlaps.put(b, total);
}
total.add(r2.getStudent().getId());
pair = conflictingPairs.get(b);
if (pair == null) {
pair = new HashMap<CourseSection, Double>();
conflictingPairs.put(b, pair);
}
prev = pair.get(a);
pair.put(a, r1.getWeight() + (prev == null ? 0.0 : prev.doubleValue()));
}
Comparator<Course> courseComparator = new Comparator<Course>() {
@Override
public int compare(Course a, Course b) {
int cmp = a.getName().compareTo(b.getName());
if (cmp != 0)
return cmp;
return a.getId() < b.getId() ? -1 : a.getId() == b.getId() ? 0 : 1;
}
};
Comparator<Section> sectionComparator = new Comparator<Section>() {
@Override
public int compare(Section a, Section b) {
int cmp = a.getSubpart().getConfig().getOffering().getName().compareTo(b.getSubpart().getConfig().getOffering().getName());
if (cmp != 0)
return cmp;
cmp = a.getSubpart().getInstructionalType().compareTo(b.getSubpart().getInstructionalType());
// cmp = a.getName().compareTo(b.getName());
if (cmp != 0)
return cmp;
return a.getId() < b.getId() ? -1 : a.getId() == b.getId() ? 0 : 1;
}
};
TreeSet<Course> courses = new TreeSet<Course>(courseComparator);
courses.addAll(totals.keySet());
for (Course course : courses) {
Set<Long> total = totals.get(course);
TreeSet<Section> sections = new TreeSet<Section>(sectionComparator);
for (Map.Entry<CourseSection, Set<Long>> entry : sectionOverlaps.entrySet()) if (course.equals(entry.getKey().getCourse()))
sections.add(entry.getKey().getSection());
boolean firstCourse = true;
for (Section section : sections) {
Set<Long> sectionOverlap = sectionOverlaps.get(new CourseSection(course, section));
Map<CourseSection, Double> pair = conflictingPairs.get(new CourseSection(course, section));
boolean firstClass = true;
for (CourseSection other : new TreeSet<CourseSection>(pair.keySet())) {
List<CSVFile.CSVField> line = new ArrayList<CSVFile.CSVField>();
line.add(new CSVFile.CSVField(firstCourse && firstClass ? course.getName() : ""));
line.add(new CSVFile.CSVField(firstCourse && firstClass ? total.size() : ""));
line.add(new CSVFile.CSVField(firstClass ? section.getSubpart().getName() + " " + section.getName(course.getId()) : ""));
line.add(new CSVFile.CSVField(firstClass ? section.getTime() == null ? "" : section.getTime().getDayHeader() + " " + section.getTime().getStartTimeHeader(useAmPm) + " - " + section.getTime().getEndTimeHeader(useAmPm) : ""));
line.add(new CSVFile.CSVField(firstClass && sectionOverlap != null ? String.valueOf(sectionOverlap.size()) : ""));
line.add(new CSVFile.CSVField(firstClass && sectionOverlap != null ? sDF2.format(((double) sectionOverlap.size()) / total.size()) : ""));
line.add(new CSVFile.CSVField(other.getCourse().getName() + " " + other.getSection().getSubpart().getName() + " " + other.getSection().getName(other.getCourse().getId())));
line.add(new CSVFile.CSVField(other.getSection().getTime().getDayHeader() + " " + other.getSection().getTime().getStartTimeHeader(useAmPm) + " - " + other.getSection().getTime().getEndTimeHeader(useAmPm)));
line.add(new CSVFile.CSVField(sDF1.format(5 * iTOC.share(section, other.getSection()))));
line.add(new CSVFile.CSVField(sDF1.format(pair.get(other))));
line.add(new CSVFile.CSVField(sDF2.format(pair.get(other) / total.size())));
csv.addLine(line);
firstClass = false;
}
firstCourse = false;
}
csv.addLine();
}
return csv;
}
use of org.cpsolver.studentsct.model.Request in project cpsolver by UniTime.
the class MultiCriteriaBranchAndBoundSelection method backTrack.
/** branch & bound search */
public void backTrack(int idx) {
if (iTimeout > 0 && (JProf.currentTimeMillis() - iT0) > iTimeout) {
iTimeoutReached = true;
return;
}
if (idx == iCurrentAssignment.length) {
if (iBestAssignment == null || iComparator.compare(iAssignment, iCurrentAssignment, iBestAssignment) < 0)
saveBest();
return;
} else if (iBestAssignment != null && !iComparator.canImprove(iAssignment, idx, iCurrentAssignment, iBestAssignment)) {
return;
}
Request request = iStudent.getRequests().get(idx);
if (!canAssign(request, idx)) {
backTrack(idx + 1);
return;
}
List<Enrollment> values = null;
if (request instanceof CourseRequest) {
CourseRequest courseRequest = (CourseRequest) request;
if (!courseRequest.getSelectedChoices().isEmpty()) {
values = courseRequest.getSelectedEnrollments(iAssignment, true);
if (values != null && !values.isEmpty()) {
boolean hasNoConflictValue = false;
for (Enrollment enrollment : values) {
if (inConflict(idx, enrollment))
continue;
hasNoConflictValue = true;
iCurrentAssignment[idx] = enrollment;
backTrack(idx + 1);
iCurrentAssignment[idx] = null;
}
if (hasNoConflictValue && iBranchWhenSelectedHasNoConflict)
return;
}
}
values = iValues.get(courseRequest);
if (values == null) {
values = values(courseRequest);
iValues.put(courseRequest, values);
}
} else {
values = request.computeEnrollments(iAssignment);
}
boolean hasNoConflictValue = false;
for (Enrollment enrollment : values) {
if (inConflict(idx, enrollment))
continue;
hasNoConflictValue = true;
iCurrentAssignment[idx] = enrollment;
backTrack(idx + 1);
iCurrentAssignment[idx] = null;
}
if (canLeaveUnassigned(request) || (!hasNoConflictValue && request instanceof CourseRequest))
backTrack(idx + 1);
}
use of org.cpsolver.studentsct.model.Request in project cpsolver by UniTime.
the class StudentPreferencePenalties method setPenalties.
/**
* Set the computed penalties to all sections of all requests of the given
* student
* @param student given student
* @param distributionType penalty distribution type
*/
public static void setPenalties(Student student, int distributionType) {
if (sDebug)
sLog.debug("Setting penalties for " + student);
StudentPreferencePenalties penalties = new StudentPreferencePenalties(distributionType);
for (Request request : student.getRequests()) {
if (!(request instanceof CourseRequest))
continue;
CourseRequest courseRequest = (CourseRequest) request;
if (sDebug)
sLog.debug("-- " + courseRequest);
for (Course course : courseRequest.getCourses()) {
if (sDebug)
sLog.debug(" -- " + course.getName());
for (Config config : course.getOffering().getConfigs()) {
if (sDebug)
sLog.debug(" -- " + config.getName());
for (Subpart subpart : config.getSubparts()) {
if (sDebug)
sLog.debug(" -- " + subpart.getName());
for (Section section : subpart.getSections()) {
section.setPenalty(penalties.getPenalty(section));
if (sDebug)
sLog.debug(" -- " + section);
}
}
}
}
courseRequest.clearCache();
}
}
use of org.cpsolver.studentsct.model.Request in project cpsolver by UniTime.
the class StudentSctBBTest method getMessages.
/**
* Return a list of messages ({@link Message} objects) from the sectioning
* of the given student
* @return enrollment messages
*/
public List<Message> getMessages() {
Assignment<Request, Enrollment> assignment = getSolution().getAssignment();
List<Message> ret = new ArrayList<Message>();
ret.add(new Message(Message.sMsgLevelInfo, null, "<li>Solution found in " + iTime + " ms."));
if (iTimeoutReached)
ret.add(new Message(Message.sMsgLevelInfo, null, "<li>Time out reached, solution optimality can not be guaranteed."));
for (Request request : getStudent().getRequests()) {
if (!request.isAlternative() && assignment.getValue(request) == null) {
ret.add(new Message(Message.sMsgLevelWarn, request, "<li>Unable to enroll to " + request + ", " + (request instanceof CourseRequest ? ((CourseRequest) request).getCourses().size() == 1 ? "course is" : "courses are" : "time is") + " not available."));
Collection<Enrollment> values = (request instanceof CourseRequest ? (Collection<Enrollment>) ((CourseRequest) request).getAvaiableEnrollmentsSkipSameTime(assignment) : request.computeEnrollments(assignment));
for (Iterator<Enrollment> f = values.iterator(); f.hasNext(); ) {
Enrollment enrollment = f.next();
Set<Enrollment> conf = conflictValues(assignment, enrollment);
if (conf != null && !conf.isEmpty()) {
Enrollment conflict = conf.iterator().next();
if (conflict.equals(enrollment))
ret.add(new Message(Message.sMsgLevelInfo, request, "<ul>Assignment of " + enrollment.getName().replaceAll("\n", "<br> ") + "<br> is not available."));
else
ret.add(new Message(Message.sMsgLevelInfo, request, "<ul>Assignment of " + enrollment.getName().replaceAll("\n", "<br> ") + "<br> conflicts with " + conflict.getName().replaceAll("\n", "<br> ") + "</ul>"));
}
}
}
if (request instanceof CourseRequest && assignment.getValue(request) != null) {
CourseRequest courseRequest = (CourseRequest) request;
Enrollment enrollment = assignment.getValue(request);
List<Enrollment> selectedEnrollments = courseRequest.getSelectedEnrollments(assignment, false);
if (selectedEnrollments != null && !selectedEnrollments.isEmpty() && !selectedEnrollments.contains(enrollment)) {
Course course = (courseRequest.getSelectedChoices().iterator().next()).getOffering().getCourse(getStudent());
Enrollment selected = selectedEnrollments.get(0);
Set<Enrollment> conf = conflictValues(assignment, selected);
if (conf != null && !conf.isEmpty()) {
ret.add(new Message(Message.sMsgLevelWarn, request, "<li>Unable to enroll selected enrollment for " + course.getName() + ", seleted " + (courseRequest.getSelectedChoices().size() == 1 ? "class is" : "classes are") + " conflicting with other choices."));
Enrollment conflict = conf.iterator().next();
if (conflict.equals(selected))
ret.add(new Message(Message.sMsgLevelInfo, request, "<ul>Assignment of " + selected.getName().replaceAll("\n", "<br> ") + "<br> is not available."));
else
ret.add(new Message(Message.sMsgLevelInfo, request, "<ul>Assignment of " + selected.getName().replaceAll("\n", "<br> ") + "<br> conflicts with " + conflict.getName().replaceAll("\n", "<br> ") + "</ul>"));
} else {
ret.add(new Message(Message.sMsgLevelWarn, request, "<li>Unable to enroll selected enrollment for " + course.getName() + "."));
}
}
}
}
return ret;
}
use of org.cpsolver.studentsct.model.Request in project cpsolver by UniTime.
the class Solution2Expectations method main.
public static void main(String[] args) {
try {
ToolBox.configureLogging();
DataProperties config = new DataProperties();
String command = args[0];
if ("real2exp".equals(command)) {
StudentSectioningModel model = new StudentSectioningModel(config);
Assignment<Request, Enrollment> assignment = new DefaultSingleAssignment<Request, Enrollment>();
StudentSectioningXMLLoader loader = new StudentSectioningXMLLoader(model, assignment);
loader.setInputFile(new File(args[1]));
loader.load();
sLog.info("Loaded: " + ToolBox.dict2string(model.getExtendedInfo(assignment), 2));
for (Student s : model.getStudents()) s.setDummy(true);
model.computeOnlineSectioningInfos(assignment);
for (Student s : model.getStudents()) s.setDummy(false);
for (Request request : model.variables()) assignment.unassign(0, request);
Solution<Request, Enrollment> solution = new Solution<Request, Enrollment>(model, assignment, 0, 0);
Solver<Request, Enrollment> solver = new Solver<Request, Enrollment>(config);
solver.setInitalSolution(solution);
new StudentSectioningXMLSaver(solver).save(new File(args[2]));
sLog.info("Saved: " + ToolBox.dict2string(model.getExtendedInfo(assignment), 2));
} else if ("ll2exp".equals(command)) {
StudentSectioningModel model = new StudentSectioningModel(config);
Assignment<Request, Enrollment> assignment = new DefaultSingleAssignment<Request, Enrollment>();
StudentSectioningXMLLoader loader = new StudentSectioningXMLLoader(model, assignment);
loader.setInputFile(new File(args[1]));
loader.load();
sLog.info("Loaded: " + ToolBox.dict2string(model.getExtendedInfo(assignment), 2));
model.computeOnlineSectioningInfos(assignment);
for (Request request : model.variables()) assignment.unassign(0, request);
Solution<Request, Enrollment> solution = new Solution<Request, Enrollment>(model, assignment, 0, 0);
Solver<Request, Enrollment> solver = new Solver<Request, Enrollment>(config);
solver.setInitalSolution(solution);
new StudentSectioningXMLSaver(solver).save(new File(args[2]));
sLog.info("Saved: " + ToolBox.dict2string(model.getExtendedInfo(assignment), 2));
} else if ("students".equals(command)) {
StudentSectioningModel model = new StudentSectioningModel(config);
Assignment<Request, Enrollment> assignment = new DefaultSingleAssignment<Request, Enrollment>();
StudentSectioningXMLLoader loader = new StudentSectioningXMLLoader(model, assignment);
loader.setInputFile(new File(args[1]));
loader.setLoadStudents(false);
loader.load();
sLog.info("Loaded [1]: " + ToolBox.dict2string(model.getExtendedInfo(assignment), 2));
StudentSectioningXMLLoader loder2 = new StudentSectioningXMLLoader(model, assignment);
loder2.setInputFile(new File(args[2]));
loder2.setLoadOfferings(false);
loder2.setLoadStudents(true);
loder2.load();
sLog.info("Loaded [2]: " + ToolBox.dict2string(model.getExtendedInfo(assignment), 2));
Solution<Request, Enrollment> solution = new Solution<Request, Enrollment>(model, assignment, 0, 0);
Solver<Request, Enrollment> solver = new Solver<Request, Enrollment>(config);
solver.setInitalSolution(solution);
new StudentSectioningXMLSaver(solver).save(new File(args[3]));
sLog.info("Saved [3]: " + ToolBox.dict2string(model.getExtendedInfo(assignment), 2));
} else {
sLog.error("Unknown command: " + command);
}
} catch (Exception e) {
sLog.error(e.getMessage(), e);
}
}
Aggregations