use of org.cpsolver.studentsct.model.CourseRequest in project cpsolver by UniTime.
the class EqualStudentWeights method main.
/**
* Test case -- run to see the weights for a few courses
* @param args program arguments
*/
public static void main(String[] args) {
EqualStudentWeights pw = new EqualStudentWeights(new DataProperties());
DecimalFormat df = new DecimalFormat("0.0000");
Student s = new Student(0l);
new CourseRequest(1l, 0, false, s, ToolBox.toList(new Course(1, "A", "1", new Offering(0, "A")), new Course(1, "A", "2", new Offering(0, "A")), new Course(1, "A", "3", new Offering(0, "A"))), false, null);
new CourseRequest(2l, 1, false, s, ToolBox.toList(new Course(1, "B", "1", new Offering(0, "B")), new Course(1, "B", "2", new Offering(0, "B")), new Course(1, "B", "3", new Offering(0, "B"))), false, null);
new CourseRequest(3l, 2, false, s, ToolBox.toList(new Course(1, "C", "1", new Offering(0, "C")), new Course(1, "C", "2", new Offering(0, "C")), new Course(1, "C", "3", new Offering(0, "C"))), false, null);
new CourseRequest(5l, 4, false, s, ToolBox.toList(new Course(1, "E", "1", new Offering(0, "E")), new Course(1, "E", "2", new Offering(0, "E")), new Course(1, "E", "3", new Offering(0, "E"))), false, null);
new CourseRequest(6l, 5, true, s, ToolBox.toList(new Course(1, "F", "1", new Offering(0, "F")), new Course(1, "F", "2", new Offering(0, "F")), new Course(1, "F", "3", new Offering(0, "F"))), false, null);
new CourseRequest(7l, 6, true, s, ToolBox.toList(new Course(1, "G", "1", new Offering(0, "G")), new Course(1, "G", "2", new Offering(0, "G")), new Course(1, "G", "3", new Offering(0, "G"))), false, null);
Assignment<Request, Enrollment> assignment = new DefaultSingleAssignment<Request, Enrollment>();
Placement p = new Placement(null, new TimeLocation(1, 90, 12, 0, 0, null, null, new BitSet(), 10), new ArrayList<RoomLocation>());
for (Request r : s.getRequests()) {
CourseRequest cr = (CourseRequest) r;
double[] w = new double[] { 0.0, 0.0, 0.0 };
for (int i = 0; i < cr.getCourses().size(); i++) {
Config cfg = new Config(0l, -1, "", cr.getCourses().get(i).getOffering());
Set<SctAssignment> sections = new HashSet<SctAssignment>();
sections.add(new Section(0, 1, "x", new Subpart(0, "Lec", "Lec", cfg, null), p, null));
Enrollment e = new Enrollment(cr, i, cfg, sections, assignment);
w[i] = pw.getWeight(assignment, e, null, null);
}
System.out.println(cr + ": " + df.format(w[0]) + " " + df.format(w[1]) + " " + df.format(w[2]));
}
System.out.println("With one distance conflict:");
for (Request r : s.getRequests()) {
CourseRequest cr = (CourseRequest) r;
double[] w = new double[] { 0.0, 0.0, 0.0 };
for (int i = 0; i < cr.getCourses().size(); i++) {
Config cfg = new Config(0l, -1, "", cr.getCourses().get(i).getOffering());
Set<SctAssignment> sections = new HashSet<SctAssignment>();
sections.add(new Section(0, 1, "x", new Subpart(0, "Lec", "Lec", cfg, null), p, null));
Enrollment e = new Enrollment(cr, i, cfg, sections, assignment);
Set<DistanceConflict.Conflict> dc = new HashSet<DistanceConflict.Conflict>();
dc.add(new DistanceConflict.Conflict(s, e, (Section) sections.iterator().next(), e, (Section) sections.iterator().next()));
w[i] = pw.getWeight(assignment, e, dc, null);
}
System.out.println(cr + ": " + df.format(w[0]) + " " + df.format(w[1]) + " " + df.format(w[2]));
}
System.out.println("With two distance conflicts:");
for (Request r : s.getRequests()) {
CourseRequest cr = (CourseRequest) r;
double[] w = new double[] { 0.0, 0.0, 0.0 };
for (int i = 0; i < cr.getCourses().size(); i++) {
Config cfg = new Config(0l, -1, "", cr.getCourses().get(i).getOffering());
Set<SctAssignment> sections = new HashSet<SctAssignment>();
sections.add(new Section(0, 1, "x", new Subpart(0, "Lec", "Lec", cfg, null), p, null));
Enrollment e = new Enrollment(cr, i, cfg, sections, assignment);
Set<DistanceConflict.Conflict> dc = new HashSet<DistanceConflict.Conflict>();
dc.add(new DistanceConflict.Conflict(s, e, (Section) sections.iterator().next(), e, (Section) sections.iterator().next()));
dc.add(new DistanceConflict.Conflict(s, e, (Section) sections.iterator().next(), e, new Section(1, 1, "x", new Subpart(0, "Lec", "Lec", cfg, null), p, null)));
w[i] = pw.getWeight(assignment, e, dc, null);
}
System.out.println(cr + ": " + df.format(w[0]) + " " + df.format(w[1]) + " " + df.format(w[2]));
}
System.out.println("With 25% time overlapping conflict:");
for (Request r : s.getRequests()) {
CourseRequest cr = (CourseRequest) r;
double[] w = new double[] { 0.0, 0.0, 0.0 };
for (int i = 0; i < cr.getCourses().size(); i++) {
Config cfg = new Config(0l, -1, "", cr.getCourses().get(i).getOffering());
Set<SctAssignment> sections = new HashSet<SctAssignment>();
sections.add(new Section(0, 1, "x", new Subpart(0, "Lec", "Lec", cfg, null), p, null));
Enrollment e = new Enrollment(cr, i, cfg, sections, assignment);
Set<TimeOverlapsCounter.Conflict> toc = new HashSet<TimeOverlapsCounter.Conflict>();
toc.add(new TimeOverlapsCounter.Conflict(s, 3, e, sections.iterator().next(), e, sections.iterator().next()));
w[i] = pw.getWeight(assignment, e, null, toc);
}
System.out.println(cr + ": " + df.format(w[0]) + " " + df.format(w[1]) + " " + df.format(w[2]));
}
System.out.println("Disbalanced sections (by 2 / 10 students):");
for (Request r : s.getRequests()) {
CourseRequest cr = (CourseRequest) r;
double[] w = new double[] { 0.0, 0.0, 0.0 };
for (int i = 0; i < cr.getCourses().size(); i++) {
Config cfg = new Config(0l, -1, "", cr.getCourses().get(i).getOffering());
Set<SctAssignment> sections = new HashSet<SctAssignment>();
Subpart x = new Subpart(0, "Lec", "Lec", cfg, null);
Section a = new Section(0, 10, "x", x, p, null);
new Section(1, 10, "y", x, p, null);
sections.add(a);
a.assigned(assignment, new Enrollment(s.getRequests().get(0), i, cfg, sections, assignment));
a.assigned(assignment, new Enrollment(s.getRequests().get(0), i, cfg, sections, assignment));
cfg.getContext(assignment).assigned(assignment, new Enrollment(s.getRequests().get(0), i, cfg, sections, assignment));
cfg.getContext(assignment).assigned(assignment, new Enrollment(s.getRequests().get(0), i, cfg, sections, assignment));
Enrollment e = new Enrollment(cr, i, cfg, sections, assignment);
w[i] = pw.getWeight(assignment, e, null, null);
}
System.out.println(cr + ": " + df.format(w[0]) + " " + df.format(w[1]) + " " + df.format(w[2]));
}
System.out.println("Same sections:");
pw.iMPP = true;
for (Request r : s.getRequests()) {
CourseRequest cr = (CourseRequest) r;
double[] w = new double[] { 0.0, 0.0, 0.0 };
double dif = 0;
for (int i = 0; i < cr.getCourses().size(); i++) {
Config cfg = new Config(0l, -1, "", cr.getCourses().get(i).getOffering());
Set<SctAssignment> sections = new HashSet<SctAssignment>();
sections.add(new Section(0, 1, "x", new Subpart(0, "Lec", "Lec", cfg, null), p, null));
Enrollment e = new Enrollment(cr, i, cfg, sections, assignment);
cr.setInitialAssignment(new Enrollment(cr, i, cfg, sections, assignment));
w[i] = pw.getWeight(assignment, e, null, null);
dif = pw.getDifference(e);
}
System.out.println(cr + ": " + df.format(w[0]) + " " + df.format(w[1]) + " " + df.format(w[2]) + " (" + df.format(dif) + ")");
}
System.out.println("Same choice sections:");
pw.iMPP = true;
for (Request r : s.getRequests()) {
CourseRequest cr = (CourseRequest) r;
double[] w = new double[] { 0.0, 0.0, 0.0 };
double dif = 0;
for (int i = 0; i < cr.getCourses().size(); i++) {
Config cfg = new Config(0l, -1, "", cr.getCourses().get(i).getOffering());
Set<SctAssignment> sections = new HashSet<SctAssignment>();
sections.add(new Section(0, 1, "x", new Subpart(0, "Lec", "Lec", cfg, null), p, null));
Enrollment e = new Enrollment(cr, i, cfg, sections, assignment);
Set<SctAssignment> other = new HashSet<SctAssignment>();
other.add(new Section(1, 1, "x", new Subpart(0, "Lec", "Lec", cfg, null), p, null));
cr.setInitialAssignment(new Enrollment(cr, i, cfg, other, assignment));
w[i] = pw.getWeight(assignment, e, null, null);
dif = pw.getDifference(e);
}
System.out.println(cr + ": " + df.format(w[0]) + " " + df.format(w[1]) + " " + df.format(w[2]) + " (" + df.format(dif) + ")");
}
System.out.println("Same time sections:");
for (Request r : s.getRequests()) {
CourseRequest cr = (CourseRequest) r;
double dif = 0;
double[] w = new double[] { 0.0, 0.0, 0.0 };
for (int i = 0; i < cr.getCourses().size(); i++) {
Config cfg = new Config(0l, -1, "", cr.getCourses().get(i).getOffering());
Set<SctAssignment> sections = new HashSet<SctAssignment>();
sections.add(new Section(0, 1, "x", new Subpart(0, "Lec", "Lec", cfg, null), p, null));
Enrollment e = new Enrollment(cr, i, cfg, sections, assignment);
Set<SctAssignment> other = new HashSet<SctAssignment>();
other.add(new Section(1, 1, "x", new Subpart(0, "Lec", "Lec", cfg, null), p, null, new Instructor(1, null, "Josef Novak", null)));
cr.setInitialAssignment(new Enrollment(cr, i, cfg, other, assignment));
w[i] = pw.getWeight(assignment, e, null, null);
dif = pw.getDifference(e);
}
System.out.println(cr + ": " + df.format(w[0]) + " " + df.format(w[1]) + " " + df.format(w[2]) + " (" + df.format(dif) + ")");
}
System.out.println("Same configuration sections:");
for (Request r : s.getRequests()) {
CourseRequest cr = (CourseRequest) r;
double[] w = new double[] { 0.0, 0.0, 0.0 };
double dif = 0;
for (int i = 0; i < cr.getCourses().size(); i++) {
Config cfg = new Config(0l, -1, "", cr.getCourses().get(i).getOffering());
Set<SctAssignment> sections = new HashSet<SctAssignment>();
sections.add(new Section(0, 1, "x", new Subpart(0, "Lec", "Lec", cfg, null), p, null));
Enrollment e = new Enrollment(cr, i, cfg, sections, assignment);
cr.getSelectedChoices().add(new Choice(cfg));
cr.setInitialAssignment(null);
w[i] = pw.getWeight(assignment, e, null, null);
dif = pw.getDifference(e);
}
System.out.println(cr + ": " + df.format(w[0]) + " " + df.format(w[1]) + " " + df.format(w[2]) + " (" + df.format(dif) + ")");
}
System.out.println("Different time sections:");
Placement q = new Placement(null, new TimeLocation(1, 102, 12, 0, 0, null, null, new BitSet(), 10), new ArrayList<RoomLocation>());
for (Request r : s.getRequests()) {
CourseRequest cr = (CourseRequest) r;
double[] w = new double[] { 0.0, 0.0, 0.0 };
double dif = 0;
for (int i = 0; i < cr.getCourses().size(); i++) {
Config cfg = new Config(0l, -1, "", cr.getCourses().get(i).getOffering());
Set<SctAssignment> sections = new HashSet<SctAssignment>();
sections.add(new Section(0, 1, "x", new Subpart(0, "Lec", "Lec", cfg, null), p, null));
Enrollment e = new Enrollment(cr, i, cfg, sections, assignment);
Set<SctAssignment> other = new HashSet<SctAssignment>();
other.add(new Section(1, 1, "x", new Subpart(0, "Lec", "Lec", cfg, null), q, null));
cr.setInitialAssignment(new Enrollment(cr, i, cfg, other, assignment));
w[i] = pw.getWeight(assignment, e, null, null);
dif = pw.getDifference(e);
}
System.out.println(cr + ": " + df.format(w[0]) + " " + df.format(w[1]) + " " + df.format(w[2]) + " (" + df.format(dif) + ")");
}
System.out.println("Two sections, one same choice, one same time:");
for (Request r : s.getRequests()) {
CourseRequest cr = (CourseRequest) r;
double[] w = new double[] { 0.0, 0.0, 0.0 };
double dif = 0;
for (int i = 0; i < cr.getCourses().size(); i++) {
Config cfg = new Config(0l, -1, "", cr.getCourses().get(i).getOffering());
Set<SctAssignment> sections = new HashSet<SctAssignment>();
sections.add(new Section(0, 1, "x", new Subpart(0, "Lec", "Lec", cfg, null), p, null));
sections.add(new Section(1, 1, "y", new Subpart(1, "Rec", "Rec", cfg, null), p, null));
Enrollment e = new Enrollment(cr, i, cfg, sections, assignment);
Set<SctAssignment> other = new HashSet<SctAssignment>();
other.add(new Section(2, 1, "x", new Subpart(0, "Lec", "Lec", cfg, null), p, null));
other.add(new Section(3, 1, "y", new Subpart(1, "Rec", "Rec", cfg, null), p, null, new Instructor(1, null, "Josef Novak", null)));
cr.setInitialAssignment(new Enrollment(cr, i, cfg, other, assignment));
w[i] = pw.getWeight(assignment, e, null, null);
dif = pw.getDifference(e);
}
System.out.println(cr + ": " + df.format(w[0]) + " " + df.format(w[1]) + " " + df.format(w[2]) + " (" + df.format(dif) + ")");
}
}
use of org.cpsolver.studentsct.model.CourseRequest in project cpsolver by UniTime.
the class PriorityStudentWeights method getWeightMultiplicative.
public double getWeightMultiplicative(Assignment<Request, Enrollment> assignment, Enrollment enrollment) {
double weight = getBaseWeight(assignment, enrollment);
if (enrollment.isCourseRequest() && iNoTimeFactor != 0.0) {
int noTimeSections = 0, total = 0;
for (Section section : enrollment.getSections()) {
if (!section.hasTime())
noTimeSections++;
total++;
}
if (noTimeSections > 0)
weight *= (1.0 - iNoTimeFactor * noTimeSections / total);
}
if (enrollment.isCourseRequest() && iOnlineFactor != 0.0) {
int onlineSections = 0, total = 0;
for (Section section : enrollment.getSections()) {
if (section.isOnline())
onlineSections++;
total++;
}
if (onlineSections > 0)
weight *= (1.0 - iOnlineFactor * onlineSections / total);
}
if (enrollment.isCourseRequest() && iPastFactor != 0.0) {
int pastSections = 0, total = 0;
for (Section section : enrollment.getSections()) {
if (section.isPast())
pastSections++;
total++;
}
if (pastSections > 0)
weight *= (1.0 - iPastFactor * pastSections / total);
}
if (enrollment.getTruePriority() < enrollment.getPriority()) {
weight *= (1.0 - iReservationNotFollowedFactor);
}
if (enrollment.isCourseRequest() && iBalancingFactor != 0.0) {
double configUsed = enrollment.getConfig().getEnrollmentTotalWeight(assignment, enrollment.getRequest()) + enrollment.getRequest().getWeight();
double disbalanced = 0;
double total = 0;
for (Section section : enrollment.getSections()) {
Subpart subpart = section.getSubpart();
if (subpart.getSections().size() <= 1)
continue;
double used = section.getEnrollmentTotalWeight(assignment, enrollment.getRequest()) + enrollment.getRequest().getWeight();
// sections have limits -> desired size is section limit x (total enrollment / total limit)
// unlimited sections -> desired size is total enrollment / number of sections
double desired = (subpart.getLimit() > 0 ? section.getLimit() * (configUsed / subpart.getLimit()) : configUsed / subpart.getSections().size());
if (used > desired)
disbalanced += Math.min(enrollment.getRequest().getWeight(), used - desired) / enrollment.getRequest().getWeight();
else
disbalanced -= Math.min(enrollment.getRequest().getWeight(), desired - used) / enrollment.getRequest().getWeight();
total++;
}
if (disbalanced > 0)
weight *= (1.0 - disbalanced / total * iBalancingFactor);
}
if (iMPP) {
double difference = getDifference(enrollment);
if (difference > 0.0)
weight *= (1.0 - difference * iPerturbationFactor);
}
if (iSelectionFactor != 0.0) {
double selection = getSelection(enrollment);
if (selection > 0.0)
weight *= (1.0 - selection * iSelectionFactor);
}
if (enrollment.isCourseRequest() && iGroupFactor != 0.0) {
double sameGroup = 0.0;
int groupCount = 0;
for (RequestGroup g : ((CourseRequest) enrollment.getRequest()).getRequestGroups()) {
if (g.getCourse().equals(enrollment.getCourse())) {
sameGroup += g.getEnrollmentSpread(assignment, enrollment, iGroupBestRatio, iGroupFillRatio);
groupCount++;
}
}
if (groupCount > 0) {
double difference = 1.0 - sameGroup / groupCount;
weight *= (1.0 - difference * iGroupFactor);
}
}
return round(weight);
}
use of org.cpsolver.studentsct.model.CourseRequest in project cpsolver by UniTime.
the class PriorityStudentWeights method getWeightAdditive.
public double getWeightAdditive(Assignment<Request, Enrollment> assignment, Enrollment enrollment) {
double base = getBaseWeight(assignment, enrollment);
double weight = 0.0;
if (enrollment.isCourseRequest() && iNoTimeFactor != 0.0) {
int noTimeSections = 0, total = 0;
for (Section section : enrollment.getSections()) {
if (!section.hasTime())
noTimeSections++;
total++;
}
if (noTimeSections > 0)
weight += iNoTimeFactor * noTimeSections / total;
}
if (enrollment.isCourseRequest() && iOnlineFactor != 0.0) {
int onlineSections = 0, total = 0;
for (Section section : enrollment.getSections()) {
if (section.isOnline())
onlineSections++;
total++;
}
if (onlineSections > 0)
weight += iOnlineFactor * onlineSections / total;
}
if (enrollment.isCourseRequest() && iPastFactor != 0.0) {
int pastSections = 0, total = 0;
for (Section section : enrollment.getSections()) {
if (section.isPast())
pastSections++;
total++;
}
if (pastSections > 0)
weight += iPastFactor * pastSections / total;
}
if (enrollment.getTruePriority() < enrollment.getPriority()) {
weight += iReservationNotFollowedFactor;
}
if (enrollment.isCourseRequest() && iBalancingFactor != 0.0) {
double configUsed = enrollment.getConfig().getEnrollmentTotalWeight(assignment, enrollment.getRequest()) + enrollment.getRequest().getWeight();
double disbalanced = 0;
double total = 0;
for (Section section : enrollment.getSections()) {
Subpart subpart = section.getSubpart();
if (subpart.getSections().size() <= 1)
continue;
double used = section.getEnrollmentTotalWeight(assignment, enrollment.getRequest()) + enrollment.getRequest().getWeight();
// sections have limits -> desired size is section limit x (total enrollment / total limit)
// unlimited sections -> desired size is total enrollment / number of sections
double desired = (subpart.getLimit() > 0 ? section.getLimit() * (configUsed / subpart.getLimit()) : configUsed / subpart.getSections().size());
if (used > desired)
disbalanced += Math.min(enrollment.getRequest().getWeight(), used - desired) / enrollment.getRequest().getWeight();
else
disbalanced -= Math.min(enrollment.getRequest().getWeight(), desired - used) / enrollment.getRequest().getWeight();
total++;
}
if (disbalanced > 0)
weight += disbalanced / total * iBalancingFactor;
}
if (iMPP) {
double difference = getDifference(enrollment);
if (difference > 0.0)
weight += difference * iPerturbationFactor;
}
if (iSelectionFactor != 0.0) {
double selection = getSelection(enrollment);
if (selection > 0.0)
weight += selection * iSelectionFactor;
}
if (enrollment.isCourseRequest() && iGroupFactor != 0.0) {
double sameGroup = 0.0;
int groupCount = 0;
for (RequestGroup g : ((CourseRequest) enrollment.getRequest()).getRequestGroups()) {
if (g.getCourse().equals(enrollment.getCourse())) {
sameGroup += g.getEnrollmentSpread(assignment, enrollment, iGroupBestRatio, iGroupFillRatio);
groupCount++;
}
}
if (groupCount > 0) {
double difference = 1.0 - sameGroup / groupCount;
weight += difference * iGroupFactor;
}
}
return round(base * (1.0 - weight));
}
use of org.cpsolver.studentsct.model.CourseRequest in project cpsolver by UniTime.
the class CriticalCoursesTable method create.
@Override
public CSVFile create(Assignment<Request, Enrollment> assignment, DataProperties properties) {
RequestPriority rp = RequestPriority.valueOf(properties.getProperty("priority", RequestPriority.Critical.name()));
CSVFile csv = new CSVFile();
csv.setHeader(new CSVFile.CSVField[] { new CSVFile.CSVField("__Student"), new CSVFile.CSVField("Student"), new CSVFile.CSVField("Priority"), new CSVFile.CSVField("Course"), new CSVFile.CSVField("1st Alt"), new CSVFile.CSVField("2nd Alt"), new CSVFile.CSVField("Enrolled"), new CSVFile.CSVField("Choice") });
for (Student student : getModel().getStudents()) {
if (student.isDummy())
continue;
int priority = 0;
for (Request r : student.getRequests()) {
if (r instanceof CourseRequest) {
CourseRequest cr = (CourseRequest) r;
priority++;
if (rp != cr.getRequestPriority() || cr.isAlternative())
continue;
Enrollment e = cr.getAssignment(assignment);
Course course = cr.getCourses().get(0);
Course alt1 = (cr.getCourses().size() < 2 ? null : cr.getCourses().get(1));
Course alt2 = (cr.getCourses().size() < 3 ? null : cr.getCourses().get(2));
Course enrolled = (e == null ? null : e.getCourse());
csv.addLine(new CSVFile.CSVField[] { new CSVFile.CSVField(student.getId()), new CSVFile.CSVField(student.getExternalId()), new CSVFile.CSVField(priority), new CSVFile.CSVField(course.getName()), new CSVFile.CSVField(alt1 == null ? "" : alt1.getName()), new CSVFile.CSVField(alt2 == null ? "" : alt2.getName()), new CSVFile.CSVField(enrolled == null ? "" : enrolled.getName()), new CSVFile.CSVField(enrolled == null ? "" : String.valueOf(cr.getCourses().indexOf(enrolled) + 1)) });
}
}
}
return csv;
}
use of org.cpsolver.studentsct.model.CourseRequest in project cpsolver by UniTime.
the class DistanceConflictTable 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("Room"), new CSVFile.CSVField("Distance\nConflicts"), new CSVFile.CSVField("% of Total\nConflicts"), new CSVFile.CSVField("Conflicting\nClass"), new CSVFile.CSVField("Conflicting\nMeeting Time"), new CSVFile.CSVField("Conflicting\nRoom"), new CSVFile.CSVField("Distance [m]"), new CSVFile.CSVField("Distance [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 CourseRequest))
continue;
confs.addAll(iDC.conflicts(e1));
for (Request r2 : r1.getStudent().getRequests()) {
Enrollment e2 = assignment.getValue(r2);
if (e2 == null || r1.getId() >= r2.getId() || !(r2 instanceof CourseRequest))
continue;
confs.addAll(iDC.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;
Section s1 = conflict.getS1(), s2 = conflict.getS2();
Course c1 = null, c2 = null;
Request r1 = null, r2 = null;
for (Request request : conflict.getStudent().getRequests()) {
Enrollment enrollment = assignment.getValue(request);
if (enrollment == null || !enrollment.isCourseRequest())
continue;
if (c1 == null && enrollment.getAssignments().contains(s1)) {
c1 = enrollment.getCourse();
r1 = request;
Set<Long> total = totals.get(enrollment.getCourse());
if (total == null) {
total = new HashSet<Long>();
totals.put(enrollment.getCourse(), total);
}
total.add(enrollment.getStudent().getId());
}
if (c2 == null && enrollment.getAssignments().contains(s2)) {
c2 = enrollment.getCourse();
r2 = request;
Set<Long> total = totals.get(enrollment.getCourse());
if (total == null) {
total = new HashSet<Long>();
totals.put(enrollment.getCourse(), total);
}
total.add(enrollment.getStudent().getId());
}
}
if (c1 == null) {
sLog.error("Unable to find a course for " + s1);
continue;
}
if (c2 == null) {
sLog.error("Unable to find a course for " + s2);
continue;
}
CourseSection a = new CourseSection(c1, s1);
CourseSection b = new CourseSection(c2, s2);
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;
String rooms = "";
if (section.getRooms() != null)
for (RoomLocation r : section.getRooms()) {
if (!rooms.isEmpty())
rooms += "\n";
rooms += r.getName();
}
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 ? rooms : ""));
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)));
String or = "";
if (other.getSection().getRooms() != null)
for (RoomLocation r : other.getSection().getRooms()) {
if (!or.isEmpty())
or += "\n";
or += r.getName();
}
line.add(new CSVFile.CSVField(or));
line.add(new CSVFile.CSVField(sDF2.format(Placement.getDistanceInMeters(iDM, section.getPlacement(), other.getSection().getPlacement()))));
line.add(new CSVFile.CSVField(String.valueOf(Placement.getDistanceInMinutes(iDM, section.getPlacement(), other.getSection().getPlacement()))));
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;
}
Aggregations