use of org.cpsolver.exam.model.ExamStudent in project cpsolver by UniTime.
the class ExamSplitter method merge.
/**
* Merge an exam
* @param assignment current assignment
* @param child an exam to be merged
* @param iteration solver iteration
* @return parent exam of the exam that has been deleted; null if the given exam cannot be merged
*/
public Exam merge(Assignment<Exam, ExamPlacement> assignment, Exam child, long iteration) {
if (!canMerge(child))
return null;
// Update the parent and children structures
Exam parent = iParent.get(child);
iParent.remove(child);
List<Exam> children = iChildren.get(parent);
children.remove(child);
iValue -= 1.0;
// Unassign parent and the given exam
ExamPlacement parentPlacement = assignment.getValue(parent);
if (parentPlacement != null)
assignment.unassign(iteration, parent);
if (assignment.getValue(child) != null)
assignment.unassign(iteration, child);
// Move students back from the given exam
for (ExamStudent student : new ArrayList<ExamStudent>(child.getStudents())) {
student.removeVariable(child);
student.addVariable(parent);
}
// Remove the given exam from the model
for (ExamRoomPlacement room : child.getRoomPlacements()) room.getRoom().removeVariable(child);
parent.getModel().removeVariable(child);
// Assign parent exam back
if (parentPlacement != null)
assignment.assign(iteration, parentPlacement);
// Shuffle students between parent exam and its remaining children
shuffle(assignment, parent, iteration);
// Return parent exam
return parent;
}
use of org.cpsolver.exam.model.ExamStudent in project cpsolver by UniTime.
the class ExamStudentMoreTwoADay method report.
/**
* generate report
* @param assignment current assignment
* @return resultant report
*/
public CSVFile report(Assignment<Exam, ExamPlacement> assignment) {
CSVFile csv = new CSVFile();
csv.setHeader(new CSVField[] { new CSVField("Exam 1"), new CSVField("Enrl 1"), new CSVField("Period 1"), new CSVField("Date 1"), new CSVField("Time 1"), new CSVField("Exam 2"), new CSVField("Enrl 2"), new CSVField("Period 2"), new CSVField("Time 2"), new CSVField("Exam 3"), new CSVField("Enrl 3"), new CSVField("Period 3"), new CSVField("Time 3"), new CSVField("More-2-Day"), new CSVField("More-2-Day [%]") });
DecimalFormat df = new DecimalFormat("0.0");
for (Exam ex1 : iModel.variables()) {
ExamPlacement p1 = assignment.getValue(ex1);
if (p1 == null)
continue;
for (Exam ex2 : iModel.variables()) {
if (ex2.equals(ex1))
continue;
ExamPlacement p2 = assignment.getValue(ex2);
if (p2 == null || p2.getPeriod().getDay() != p1.getPeriod().getDay() || p2.getPeriod().getIndex() < p1.getPeriod().getIndex())
continue;
if (p1.getPeriod().equals(p2.getPeriod()) && ex1.getId() >= ex2.getId())
continue;
List<ExamStudent> students = ex1.getJointEnrollments().get(ex2);
if (students == null || students.isEmpty())
continue;
for (Exam ex3 : iModel.variables()) {
if (ex3.equals(ex2) || ex3.equals(ex1))
continue;
ExamPlacement p3 = assignment.getValue(ex3);
if (p3 == null || p3.getPeriod().getDay() != p2.getPeriod().getDay() || p3.getPeriod().getIndex() < p2.getPeriod().getIndex())
continue;
if (p1.getPeriod().equals(p3.getPeriod()) && ex1.getId() >= ex3.getId())
continue;
if (p2.getPeriod().equals(p3.getPeriod()) && ex2.getId() >= ex3.getId())
continue;
int m2d = 0;
for (ExamStudent h : ex3.getStudents()) if (students.contains(h))
m2d++;
if (m2d == 0)
continue;
csv.addLine(new CSVField[] { new CSVField(ex1.getName()), new CSVField(ex1.getStudents().size()), new CSVField(p1.getPeriod().getIndex() + 1), new CSVField(p1.getPeriod().getDayStr()), new CSVField(p1.getPeriod().getTimeStr()), new CSVField(ex2.getName()), new CSVField(ex2.getStudents().size()), new CSVField(p2.getPeriod().getIndex() + 1), new CSVField(p2.getPeriod().getTimeStr()), new CSVField(ex3.getName()), new CSVField(ex3.getStudents().size()), new CSVField(p3.getPeriod().getIndex() + 1), new CSVField(p3.getPeriod().getTimeStr()), new CSVField(m2d), new CSVField(df.format(100.0 * m2d / Math.min(Math.min(ex1.getStudents().size(), ex2.getStudents().size()), ex3.getStudents().size()))) });
}
}
}
return csv;
}
use of org.cpsolver.exam.model.ExamStudent in project cpsolver by UniTime.
the class ExamStudentBackToBackConflicts method report.
/**
* generate report
* @param assignment current assignment
* @return resultant report
*/
public CSVFile report(Assignment<Exam, ExamPlacement> assignment) {
CSVFile csv = new CSVFile();
csv.setHeader(new CSVField[] { new CSVField("Exam 1"), new CSVField("Enrl 1"), new CSVField("Period 1"), new CSVField("Date 1"), new CSVField("Time 1"), new CSVField("Exam 2"), new CSVField("Enrl 2"), new CSVField("Back-To-Back"), new CSVField("Back-To-Back [%]"), new CSVField("Distance") });
DecimalFormat df = new DecimalFormat("0.0");
boolean isDayBreakBackToBack = ((StudentBackToBackConflicts) iModel.getCriterion(StudentBackToBackConflicts.class)).isDayBreakBackToBack();
double backToBackDistance = ((StudentDistanceBackToBackConflicts) iModel.getCriterion(StudentDistanceBackToBackConflicts.class)).getBackToBackDistance();
for (Exam ex1 : iModel.variables()) {
ExamPlacement p1 = assignment.getValue(ex1);
if (p1 == null || p1.getPeriod().next() == null)
continue;
if (!isDayBreakBackToBack && p1.getPeriod().getDay() != p1.getPeriod().next().getDay())
continue;
for (Exam ex2 : iModel.variables()) {
ExamPlacement p2 = assignment.getValue(ex2);
if (p2 == null || !p2.getPeriod().equals(p1.getPeriod().next()))
continue;
List<ExamStudent> students = ex1.getJointEnrollments().get(ex2);
if (students == null || students.isEmpty())
continue;
String distStr = "";
if (backToBackDistance >= 0) {
double dist = p1.getDistanceInMeters(p2);
if (dist > 0)
distStr = String.valueOf(dist);
}
csv.addLine(new CSVField[] { new CSVField(ex1.getName()), new CSVField(ex1.getStudents().size()), new CSVField(p1.getPeriod().getIndex() + 1), new CSVField(p1.getPeriod().getDayStr()), new CSVField(p1.getPeriod().getTimeStr()), new CSVField(ex2.getName()), new CSVField(ex2.getStudents().size()), new CSVField(students.size()), new CSVField(df.format(100.0 * students.size() / Math.min(ex1.getStudents().size(), ex2.getStudents().size()))), new CSVField(distStr) });
}
}
return csv;
}
use of org.cpsolver.exam.model.ExamStudent in project cpsolver by UniTime.
the class Test method addCSVLine.
private static void addCSVLine(File file, String instance, String config, Solution<Exam, ExamPlacement> solution) {
try {
ExamModel model = (ExamModel) solution.getModel();
Assignment<Exam, ExamPlacement> assignment = solution.getAssignment();
boolean ex = file.exists();
PrintWriter pw = new PrintWriter(new FileWriter(file, true));
boolean mpp = ((PerturbationPenalty) model.getCriterion(PerturbationPenalty.class)).isMPP();
int largeSize = ((LargeExamsPenalty) model.getCriterion(LargeExamsPenalty.class)).getLargeSize();
RoomSplitDistancePenalty splitDistance = (RoomSplitDistancePenalty) model.getCriterion(RoomSplitDistancePenalty.class);
ExamSplitter splitter = (ExamSplitter) model.getCriterion(ExamSplitter.class);
PeriodViolation violPer = (PeriodViolation) model.getCriterion(PeriodViolation.class);
RoomViolation violRoom = (RoomViolation) model.getCriterion(RoomViolation.class);
DistributionViolation violDist = (DistributionViolation) model.getCriterion(DistributionViolation.class);
DistanceToStronglyPreferredRoom distStrPref = (DistanceToStronglyPreferredRoom) model.getCriterion(DistanceToStronglyPreferredRoom.class);
ExamRotationPenalty rotation = (ExamRotationPenalty) model.getCriterion(ExamRotationPenalty.class);
DecimalFormat df = new DecimalFormat("0.00");
if (!ex) {
pw.println("SEED" + ",NA,DC,M2D,BTB" + (model.getBackToBackDistance() < 0 ? "" : ",dBTB") + ",iNA,iDC,iM2D,iBTB" + (model.getBackToBackDistance() < 0 ? "" : ",diBTB") + ",PP,RP,DP" + // Period Index, Rotation Penalty, Period Size
",PI,@P,PS" + // Room Size, Room Split, Room Split Distance
",RSz,RSp,RD" + (largeSize >= 0 ? ",LP" : "") + (mpp ? ",IP,IRP" : "") + (distStrPref == null ? "" : ",@D") + (splitter == null ? "" : ",XX") + (violPer == null ? "" : ",!P") + (violRoom == null ? "" : ",!R") + (violDist == null ? "" : ",!D") + ",INSTANCE,CONFIG");
int nrStudentExams = 0;
for (ExamStudent student : model.getStudents()) {
nrStudentExams += student.variables().size();
}
int nrInstructorExams = 0;
for (ExamInstructor instructor : model.getInstructors()) {
nrInstructorExams += instructor.variables().size();
}
pw.println("MIN" + ",#EX,#RM,#PER," + (model.getBackToBackDistance() < 0 ? "" : ",") + ",#STD,#STDX,#INS,#INSX" + (model.getBackToBackDistance() < 0 ? "" : ",") + "," + model.getCriterion(PeriodPenalty.class).getBounds(assignment)[0] + "," + model.getCriterion(RoomPenalty.class).getBounds(assignment)[0] + "," + model.getCriterion(DistributionPenalty.class).getBounds(assignment)[0] + ",," + df.format(rotation.averagePeriod(assignment)) + "," + ",,," + (largeSize >= 0 ? ",0" : "") + (mpp ? ",," : "") + (distStrPref == null ? "" : ",") + (splitter == null ? "" : ",") + (violPer == null ? "" : ",") + (violRoom == null ? "" : ",") + (violDist == null ? "" : ",") + ",,");
pw.println("MAX" + "," + model.variables().size() + "," + model.getRooms().size() + "," + model.getPeriods().size() + "," + (model.getBackToBackDistance() < 0 ? "" : ",") + "," + model.getStudents().size() + "," + nrStudentExams + "," + model.getInstructors().size() + "," + nrInstructorExams + (model.getBackToBackDistance() < 0 ? "" : ",") + "," + model.getCriterion(PeriodPenalty.class).getBounds(assignment)[1] + "," + model.getCriterion(RoomPenalty.class).getBounds(assignment)[1] + "," + model.getCriterion(DistributionPenalty.class).getBounds(assignment)[1] + ",," + rotation.nrAssignedExamsWithAvgPeriod(assignment) + "," + ",,," + (largeSize >= 0 ? "," + model.getCriterion(LargeExamsPenalty.class).getBounds(assignment)[1] : "") + (mpp ? ",," : "") + (distStrPref == null ? "" : ",") + (splitter == null ? "" : ",") + (violPer == null ? "" : "," + model.getCriterion(PeriodViolation.class).getBounds(assignment)[1]) + (violRoom == null ? "" : "," + model.getCriterion(RoomViolation.class).getBounds(assignment)[1]) + (violDist == null ? "" : "," + model.getCriterion(DistributionViolation.class).getBounds(assignment)[1]) + ",,");
}
pw.println(ToolBox.getSeed() + "," + model.getCriterion(StudentNotAvailableConflicts.class).getValue(assignment) + "," + model.getCriterion(StudentDirectConflicts.class).getValue(assignment) + "," + model.getCriterion(StudentMoreThan2ADayConflicts.class).getValue(assignment) + "," + model.getCriterion(StudentBackToBackConflicts.class).getValue(assignment) + (model.getBackToBackDistance() < 0 ? "" : "," + model.getCriterion(StudentDistanceBackToBackConflicts.class).getValue(assignment)) + "," + model.getCriterion(InstructorNotAvailableConflicts.class).getValue(assignment) + "," + model.getCriterion(InstructorDirectConflicts.class).getValue(assignment) + "," + model.getCriterion(InstructorMoreThan2ADayConflicts.class).getValue(assignment) + "," + model.getCriterion(InstructorBackToBackConflicts.class).getValue(assignment) + (model.getBackToBackDistance() < 0 ? "" : "," + model.getCriterion(InstructorDistanceBackToBackConflicts.class).getValue(assignment)) + "," + model.getCriterion(PeriodPenalty.class).getValue(assignment) + "," + model.getCriterion(RoomPenalty.class).getValue(assignment) + "," + model.getCriterion(DistributionPenalty.class).getValue(assignment) + "," + df.format(model.getCriterion(PeriodIndexPenalty.class).getValue(assignment) / assignment.nrAssignedVariables()) + "," + df.format(Math.sqrt(rotation.getValue(assignment) / rotation.nrAssignedExamsWithAvgPeriod(assignment)) - 1) + "," + df.format(model.getCriterion(PeriodSizePenalty.class).getValue(assignment) / assignment.nrAssignedVariables()) + "," + df.format(model.getCriterion(RoomSizePenalty.class).getValue(assignment) / assignment.nrAssignedVariables()) + "," + model.getCriterion(RoomSplitPenalty.class).getValue(assignment) + "," + df.format(splitDistance.nrRoomSplits(assignment) <= 0 ? 0.0 : splitDistance.getValue(assignment) / splitDistance.nrRoomSplits(assignment)) + (largeSize >= 0 ? "," + model.getCriterion(LargeExamsPenalty.class).getValue(assignment) : "") + (mpp ? "," + df.format(model.getCriterion(PerturbationPenalty.class).getValue(assignment) / assignment.nrAssignedVariables()) + "," + df.format(model.getCriterion(RoomPerturbationPenalty.class).getValue(assignment) / assignment.nrAssignedVariables()) : "") + (distStrPref == null ? "" : "," + df.format(distStrPref.getValue(assignment) / assignment.nrAssignedVariables())) + (splitter == null ? "" : "," + df.format(splitter.getValue(assignment))) + (violPer == null ? "" : "," + df.format(violPer.getValue(assignment))) + (violRoom == null ? "" : "," + df.format(violRoom.getValue(assignment))) + (violDist == null ? "" : "," + df.format(violDist.getValue(assignment))) + "," + instance + "," + config);
pw.flush();
pw.close();
} catch (Exception e) {
sLog.error("Unable to add CSV line to " + file, e);
}
}
use of org.cpsolver.exam.model.ExamStudent in project cpsolver by UniTime.
the class StudentDirectConflicts method getValue.
@Override
public double getValue(Assignment<Exam, ExamPlacement> assignment, ExamPlacement value, Set<ExamPlacement> conflicts) {
Exam exam = value.variable();
int penalty = 0;
ExamPeriod period = value.getPeriod();
Map<ExamStudent, Set<Exam>> students = ((ExamModel) getModel()).getStudentsOfPeriod(assignment, period);
for (ExamStudent s : exam.getStudents()) {
Set<Exam> exams = students.get(s);
if (exams == null)
continue;
int nrExams = exams.size() + (exams.contains(exam) ? 0 : 1);
if (nrExams > 1)
penalty++;
}
/*
for (ExamStudent s : exam.getStudents()) {
Set<Exam> exams = s.getExams(assignment, period);
if (exams.isEmpty()) continue;
int nrExams = exams.size() + (exams.contains(exam) ? 0 : 1);
if (nrExams > 1)
penalty++;
}
*/
return penalty;
}
Aggregations