Search in sources :

Example 16 with Exam

use of org.cpsolver.exam.model.Exam in project cpsolver by UniTime.

the class ExamSplitter method bestRestored.

/** Best solution was restored, change the splits back to what it was in the best solution */
@Override
public void bestRestored(Assignment<Exam, ExamPlacement> assignment) {
    super.bestRestored(assignment);
    // Merge those that are not split
    for (Exam parent : new ArrayList<Exam>(iChildren.keySet())) {
        List<Exam> children = new ArrayList<Exam>(iChildren.get(parent));
        List<ExamPlacement> placements = iBestSplit.get(parent);
        for (int i = (placements == null ? 0 : placements.size()); i < children.size(); i++) merge(assignment, children.get(i), 0);
    }
    // Assign best placements to all children, create children if needed
    iValue = 0;
    for (Exam parent : iBestSplit.keySet()) {
        List<ExamPlacement> placements = iBestSplit.get(parent);
        for (int i = 0; i < placements.size(); i++) {
            List<Exam> children = iChildren.get(parent);
            if (children == null || children.size() <= i) {
                // create a child if needed
                split(assignment, parent, 0, placements.get(i));
            } else {
                // otherwise, just assign the placement
                assignment.assign(0l, new ExamPlacement(children.get(i), placements.get(i).getPeriodPlacement(), placements.get(i).getRoomPlacements()));
            }
        }
        iValue += placements.size();
    }
}
Also used : ExamPlacement(org.cpsolver.exam.model.ExamPlacement) ArrayList(java.util.ArrayList) Exam(org.cpsolver.exam.model.Exam)

Example 17 with Exam

use of org.cpsolver.exam.model.Exam in project cpsolver by UniTime.

the class ExamSplitter method delta.

/**
     * Difference in the total weighted student conflicts (including {@link StudentDirectConflicts},
     * {@link StudentMoreThan2ADayConflicts}, and {@link StudentBackToBackConflicts}) if a student
     * is moved from an exam with one placement into an exam with another placement.
     * @param assignment current assignment
     * @param student a student in question
     * @param oldPlacement placement of the exam in which the student is now
     * @param newPlacement placement of the exam into which the student would be moved
     * @return difference in the student conflict weight
     */
public double delta(Assignment<Exam, ExamPlacement> assignment, ExamStudent student, ExamPlacement oldPlacement, ExamPlacement newPlacement) {
    double delta = 0;
    // Weights of removing student form the old placement 
    if (oldPlacement != null) {
        Exam exam = oldPlacement.variable();
        ExamPeriod period = oldPlacement.getPeriod();
        Set<Exam> examsThisPeriod = student.getExams(assignment, period);
        if (examsThisPeriod.size() > (examsThisPeriod.contains(exam) ? 1 : 0))
            // will remove a direct conflict
            delta -= iStudentDirectConflicts.getWeight();
        ExamPeriod prev = period.prev();
        if (prev != null && (prev.getDay() == period.getDay() || isDayBreakBackToBack())) {
            Set<Exam> examsPrevPeriod = student.getExams(assignment, prev);
            if (examsPrevPeriod.size() > (examsPrevPeriod.contains(exam) ? 1 : 0))
                // will remove a back-to-back conflict
                delta -= iStudentBackToBackConflicts.getWeight();
        }
        ExamPeriod next = period.next();
        if (next != null && (next.getDay() == period.getDay() || isDayBreakBackToBack())) {
            Set<Exam> examsNextPeriod = student.getExams(assignment, next);
            if (examsNextPeriod.size() > (examsNextPeriod.contains(exam) ? 1 : 0))
                // will remove a back-to-back conflict
                delta -= iStudentBackToBackConflicts.getWeight();
        }
        Set<Exam> examsInADay = student.getExamsADay(assignment, period);
        if (examsInADay.size() > (examsInADay.contains(exam) ? 3 : 2))
            // will remove a more than 2 on a day conflict
            delta -= iStudentMoreThan2ADayConflicts.getWeight();
    }
    // Weights of moving student into the new placement
    if (newPlacement != null) {
        Exam exam = newPlacement.variable();
        ExamPeriod period = newPlacement.getPeriod();
        Set<Exam> examsThisPeriod = student.getExams(assignment, period);
        if (examsThisPeriod.size() > (examsThisPeriod.contains(exam) ? 1 : 0))
            // will add a direct conflict
            delta += iStudentDirectConflicts.getWeight();
        ExamPeriod prev = period.prev();
        if (prev != null && (prev.getDay() == period.getDay() || isDayBreakBackToBack())) {
            Set<Exam> examsPrevPeriod = student.getExams(assignment, prev);
            if (examsPrevPeriod.size() > (examsPrevPeriod.contains(exam) ? 1 : 0))
                // will add a back-to-back conflict
                delta += iStudentBackToBackConflicts.getWeight();
        }
        ExamPeriod next = period.next();
        if (next != null && (next.getDay() == period.getDay() || isDayBreakBackToBack())) {
            Set<Exam> examsNextPeriod = student.getExams(assignment, next);
            if (examsNextPeriod.size() > (examsNextPeriod.contains(exam) ? 1 : 0))
                // will add a back-to-back conflict
                delta += iStudentBackToBackConflicts.getWeight();
        }
        Set<Exam> examsInADay = student.getExamsADay(assignment, period);
        if (examsInADay.size() > (examsInADay.contains(exam) ? 3 : 2))
            // will add a more than 2 on a day conflict
            delta += iStudentMoreThan2ADayConflicts.getWeight();
    }
    return delta;
}
Also used : ExamPeriod(org.cpsolver.exam.model.ExamPeriod) Exam(org.cpsolver.exam.model.Exam)

Example 18 with Exam

use of org.cpsolver.exam.model.Exam in project cpsolver by UniTime.

the class ExamStudentConflictsPerExam 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"), new CSVField("Enrl"), new CSVField("Direct"), new CSVField("Direct [%]"), new CSVField("More-2-Day"), new CSVField("More-2-Day [%]"), new CSVField("Back-To-Back"), new CSVField("Back-To-Back [%]"), new CSVField("Dist Back-To-Back"), new CSVField("Dist Back-To-Back [%]") });
    DecimalFormat df = new DecimalFormat("0.0");
    for (Exam exam : iModel.variables()) {
        ExamPlacement placement = assignment.getValue(exam);
        if (placement == null)
            continue;
        int dc = (int) iModel.getCriterion(StudentDirectConflicts.class).getValue(assignment, placement, null) + (int) iModel.getCriterion(StudentNotAvailableConflicts.class).getValue(assignment, placement, null);
        int btb = (int) iModel.getCriterion(StudentBackToBackConflicts.class).getValue(assignment, placement, null);
        int dbtb = (int) iModel.getCriterion(StudentDistanceBackToBackConflicts.class).getValue(assignment, placement, null);
        int m2d = (int) iModel.getCriterion(StudentMoreThan2ADayConflicts.class).getValue(assignment, placement, null);
        if (dc == 0 && m2d == 0 && btb == 0 && dbtb == 0)
            continue;
        /*
             * String section = ""; for (Enumeration
             * f=exam.getCourseSections().elements();f.hasMoreElements();) {
             * ExamCourseSection cs = (ExamCourseSection)f.nextElement(); if
             * (section.length()>0) section+="\n"; section += cs.getName(); }
             */
        csv.addLine(new CSVField[] { new CSVField(exam.getName()), new CSVField(exam.getStudents().size()), new CSVField(dc), new CSVField(df.format(100.0 * dc / exam.getStudents().size())), new CSVField(m2d), new CSVField(df.format(100.0 * m2d / exam.getStudents().size())), new CSVField(btb), new CSVField(df.format(100.0 * btb / exam.getStudents().size())), new CSVField(dbtb), new CSVField(df.format(100.0 * dbtb / exam.getStudents().size())) });
    }
    return csv;
}
Also used : CSVFile(org.cpsolver.ifs.util.CSVFile) CSVField(org.cpsolver.ifs.util.CSVFile.CSVField) StudentNotAvailableConflicts(org.cpsolver.exam.criteria.StudentNotAvailableConflicts) ExamPlacement(org.cpsolver.exam.model.ExamPlacement) DecimalFormat(java.text.DecimalFormat) StudentDirectConflicts(org.cpsolver.exam.criteria.StudentDirectConflicts) Exam(org.cpsolver.exam.model.Exam)

Example 19 with Exam

use of org.cpsolver.exam.model.Exam 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;
}
Also used : CSVFile(org.cpsolver.ifs.util.CSVFile) CSVField(org.cpsolver.ifs.util.CSVFile.CSVField) ExamPlacement(org.cpsolver.exam.model.ExamPlacement) DecimalFormat(java.text.DecimalFormat) ExamStudent(org.cpsolver.exam.model.ExamStudent) Exam(org.cpsolver.exam.model.Exam)

Example 20 with Exam

use of org.cpsolver.exam.model.Exam in project cpsolver by UniTime.

the class ExamInstructorConflicts 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("Instructor"), new CSVField("Type"), new CSVField("Section/Course"), new CSVField("Period"), new CSVField("Day"), new CSVField("Time"), new CSVField("Room"), new CSVField("Distance") });
    boolean isDayBreakBackToBack = ((InstructorBackToBackConflicts) iModel.getCriterion(InstructorBackToBackConflicts.class)).isDayBreakBackToBack();
    double backToBackDistance = ((InstructorDistanceBackToBackConflicts) iModel.getCriterion(InstructorDistanceBackToBackConflicts.class)).getBackToBackDistance();
    for (ExamInstructor instructor : iModel.getInstructors()) {
        for (ExamPeriod period : iModel.getPeriods()) {
            int nrExams = instructor.getExams(assignment, period).size();
            if (nrExams > 1) {
                String sections = "";
                String rooms = "";
                String periods = String.valueOf(period.getIndex() + 1);
                String periodDays = period.getDayStr();
                String periodTimes = period.getTimeStr();
                for (Exam exam : instructor.getExams(assignment, period)) {
                    ExamPlacement placement = assignment.getValue(exam);
                    String roomsThisExam = "";
                    for (ExamRoomPlacement room : placement.getRoomPlacements()) {
                        if (roomsThisExam.length() > 0)
                            roomsThisExam += ", ";
                        roomsThisExam += room.getName();
                    }
                    boolean first = true;
                    for (ExamOwner owner : exam.getOwners(instructor)) {
                        if (sections.length() > 0) {
                            sections += "\n";
                            rooms += "\n";
                            periods += "\n";
                            periodDays += "\n";
                            periodTimes += "\n";
                        }
                        sections += owner.getName();
                        if (first)
                            rooms += roomsThisExam;
                        first = false;
                    }
                    if (exam.getOwners(instructor).isEmpty()) {
                        sections += exam.getName();
                        rooms += roomsThisExam;
                    }
                }
                csv.addLine(new CSVField[] { new CSVField(instructor.getName()), new CSVField("direct"), new CSVField(sections), new CSVField(periods), new CSVField(periodDays), new CSVField(periodTimes), new CSVField(rooms) });
            }
            if (nrExams > 0) {
                if (period.next() != null && !instructor.getExams(assignment, period.next()).isEmpty() && (!isDayBreakBackToBack || period.next().getDay() == period.getDay())) {
                    for (Exam ex1 : instructor.getExams(assignment, period)) {
                        for (Exam ex2 : instructor.getExams(assignment, period.next())) {
                            ExamPlacement placement = assignment.getValue(ex1);
                            String sections = "";
                            String rooms = "";
                            String roomsThisExam = "";
                            String periods = String.valueOf(period.getIndex() + 1);
                            String periodDays = period.getDayStr();
                            String periodTimes = period.getTimeStr();
                            for (ExamRoomPlacement room : placement.getRoomPlacements()) {
                                if (roomsThisExam.length() > 0)
                                    roomsThisExam += ", ";
                                roomsThisExam += room.getName();
                            }
                            boolean first = true;
                            for (ExamOwner owner : ex1.getOwners(instructor)) {
                                if (sections.length() > 0) {
                                    sections += "\n";
                                    rooms += "\n";
                                    periods += "\n";
                                    periodDays += "\n";
                                    periodTimes += "\n";
                                }
                                sections += owner.getName();
                                if (first)
                                    rooms += roomsThisExam;
                                first = false;
                            }
                            if (ex1.getOwners(instructor).isEmpty()) {
                                sections += ex1.getName();
                                rooms += roomsThisExam;
                            }
                            placement = assignment.getValue(ex2);
                            roomsThisExam = "";
                            for (ExamRoomPlacement room : placement.getRoomPlacements()) {
                                if (roomsThisExam.length() > 0)
                                    roomsThisExam += ", ";
                                roomsThisExam += room.getName();
                            }
                            first = true;
                            for (ExamOwner owner : ex2.getOwners(instructor)) {
                                sections += "\n";
                                rooms += "\n";
                                periods += "\n";
                                periodDays += "\n";
                                periodTimes += "\n";
                                sections += owner.getName();
                                if (first) {
                                    rooms += roomsThisExam;
                                    periods += String.valueOf(period.next().getIndex() + 1);
                                    periodDays += period.next().getDayStr();
                                    periodTimes += period.next().getTimeStr();
                                }
                                first = false;
                            }
                            if (ex2.getOwners(instructor).isEmpty()) {
                                sections += "\n";
                                rooms += "\n";
                                periods += "\n";
                                periodDays += "\n";
                                periodTimes += "\n";
                                sections += ex2.getName();
                                rooms += roomsThisExam;
                                periods += String.valueOf(period.next().getIndex() + 1);
                                periodDays += period.next().getDayStr();
                                periodTimes += period.next().getTimeStr();
                            }
                            String distStr = "";
                            if (backToBackDistance >= 0) {
                                double dist = (assignment.getValue(ex1)).getDistanceInMeters(assignment.getValue(ex2));
                                if (dist > 0)
                                    distStr = String.valueOf(dist);
                            }
                            csv.addLine(new CSVField[] { new CSVField(instructor.getName()), new CSVField("back-to-back"), new CSVField(sections), new CSVField(periods), new CSVField(periodDays), new CSVField(periodTimes), new CSVField(rooms), new CSVField(distStr) });
                        }
                    }
                }
            }
            if (period.next() == null || period.next().getDay() != period.getDay()) {
                int nrExamsADay = instructor.getExamsADay(assignment, period.getDay()).size();
                if (nrExamsADay > 2) {
                    String sections = "";
                    String periods = "";
                    String periodDays = "";
                    String periodTimes = "";
                    String rooms = "";
                    for (Exam exam : instructor.getExamsADay(assignment, period.getDay())) {
                        ExamPlacement placement = assignment.getValue(exam);
                        String roomsThisExam = "";
                        for (ExamRoomPlacement room : placement.getRoomPlacements()) {
                            if (roomsThisExam.length() > 0)
                                roomsThisExam += ", ";
                            roomsThisExam += room.getName();
                        }
                        boolean first = true;
                        for (ExamOwner owner : exam.getOwners(instructor)) {
                            if (sections.length() > 0) {
                                sections += "\n";
                                rooms += "\n";
                                periods += "\n";
                                periodDays += "\n";
                                periodTimes += "\n";
                            }
                            sections += owner.getName();
                            if (first) {
                                periods += (placement.getPeriod().getIndex() + 1);
                                periodDays += placement.getPeriod().getDayStr();
                                periodTimes += placement.getPeriod().getTimeStr();
                                rooms += roomsThisExam;
                            }
                            first = false;
                        }
                        if (exam.getOwners(instructor).isEmpty()) {
                            if (sections.length() > 0) {
                                sections += "\n";
                                rooms += "\n";
                                periods += "\n";
                                periodDays += "\n";
                                periodTimes += "\n";
                            }
                            sections += exam.getName();
                            periods += (placement.getPeriod().getIndex() + 1);
                            periodDays += placement.getPeriod().getDayStr();
                            periodTimes += placement.getPeriod().getTimeStr();
                            rooms += roomsThisExam;
                        }
                    }
                    csv.addLine(new CSVField[] { new CSVField(instructor.getName()), new CSVField("more-2-day"), new CSVField(sections), new CSVField(periods), new CSVField(periodDays), new CSVField(periodTimes), new CSVField(rooms) });
                }
            }
        }
    }
    return csv;
}
Also used : ExamInstructor(org.cpsolver.exam.model.ExamInstructor) ExamPeriod(org.cpsolver.exam.model.ExamPeriod) CSVFile(org.cpsolver.ifs.util.CSVFile) InstructorDistanceBackToBackConflicts(org.cpsolver.exam.criteria.InstructorDistanceBackToBackConflicts) InstructorBackToBackConflicts(org.cpsolver.exam.criteria.InstructorBackToBackConflicts) ExamRoomPlacement(org.cpsolver.exam.model.ExamRoomPlacement) CSVField(org.cpsolver.ifs.util.CSVFile.CSVField) ExamPlacement(org.cpsolver.exam.model.ExamPlacement) ExamOwner(org.cpsolver.exam.model.ExamOwner) Exam(org.cpsolver.exam.model.Exam)

Aggregations

Exam (org.cpsolver.exam.model.Exam)56 ExamPlacement (org.cpsolver.exam.model.ExamPlacement)38 ExamRoomPlacement (org.cpsolver.exam.model.ExamRoomPlacement)21 ExamModel (org.cpsolver.exam.model.ExamModel)20 ExamStudent (org.cpsolver.exam.model.ExamStudent)14 ArrayList (java.util.ArrayList)13 ExamPeriod (org.cpsolver.exam.model.ExamPeriod)12 ExamPeriodPlacement (org.cpsolver.exam.model.ExamPeriodPlacement)12 CSVFile (org.cpsolver.ifs.util.CSVFile)12 CSVField (org.cpsolver.ifs.util.CSVFile.CSVField)12 Set (java.util.Set)9 ExamInstructor (org.cpsolver.exam.model.ExamInstructor)8 DecimalFormat (java.text.DecimalFormat)6 AssignmentContext (org.cpsolver.ifs.assignment.context.AssignmentContext)6 NeighbourSelectionWithContext (org.cpsolver.ifs.assignment.context.NeighbourSelectionWithContext)6 HashSet (java.util.HashSet)5 HashMap (java.util.HashMap)4 TreeSet (java.util.TreeSet)4 ExamOwner (org.cpsolver.exam.model.ExamOwner)4 IOException (java.io.IOException)3