Search in sources :

Example 6 with ExamRoomPlacement

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

the class ExamPeriodSwapMove method findBestAvailableRooms.

public Set<ExamRoomPlacement> findBestAvailableRooms(Assignment<Exam, ExamPlacement> assignment, Exam exam, ExamPeriodPlacement period, Set<ExamPlacement> conflictsToIgnore, Map<Exam, ExamPlacement> placements) {
    if (exam.getMaxRooms() == 0)
        return new HashSet<ExamRoomPlacement>();
    double sw = exam.getModel().getCriterion(RoomSizePenalty.class).getWeight();
    double pw = exam.getModel().getCriterion(RoomPenalty.class).getWeight();
    double cw = exam.getModel().getCriterion(DistributionPenalty.class).getWeight();
    ExamRoomSharing sharing = ((ExamModel) exam.getModel()).getRoomSharing();
    loop: for (int nrRooms = 1; nrRooms <= exam.getMaxRooms(); nrRooms++) {
        HashSet<ExamRoomPlacement> rooms = new HashSet<ExamRoomPlacement>();
        int size = 0;
        while (rooms.size() < nrRooms && size < exam.getSize()) {
            int minSize = (exam.getSize() - size) / (nrRooms - rooms.size());
            ExamRoomPlacement best = null;
            double bestWeight = 0;
            int bestSize = 0;
            for (ExamRoomPlacement room : exam.getRoomPlacements()) {
                if (!room.isAvailable(period.getPeriod()))
                    continue;
                if (rooms.contains(room))
                    continue;
                List<ExamPlacement> overlaps = new ArrayList<ExamPlacement>();
                for (ExamPlacement overlap : room.getRoom().getPlacements(assignment, period.getPeriod())) if (!conflictsToIgnore.contains(overlap))
                    overlaps.add(overlap);
                for (ExamPlacement other : placements.values()) if (other.getPeriod().equals(period.getPeriod()))
                    for (ExamRoomPlacement r : other.getRoomPlacements()) if (r.getRoom().equals(room.getRoom())) {
                        overlaps.add(other);
                        continue;
                    }
                if (nrRooms == 1 && sharing != null) {
                    if (sharing.inConflict(exam, overlaps, room.getRoom()))
                        continue;
                } else {
                    if (!overlaps.isEmpty())
                        continue;
                }
                if (iCheckDistributionConstraints && !checkDistributionConstraints(assignment, exam, room, conflictsToIgnore, placements))
                    continue;
                int s = room.getSize(exam.hasAltSeating());
                if (s < minSize)
                    break;
                int p = room.getPenalty(period.getPeriod());
                double w = pw * p + sw * (s - minSize) + cw * getDistributionConstraintPenalty(assignment, exam, room, conflictsToIgnore, placements);
                double d = 0;
                if (!rooms.isEmpty()) {
                    for (ExamRoomPlacement r : rooms) {
                        d += r.getDistanceInMeters(room);
                    }
                    w += d / rooms.size();
                }
                if (best == null || bestWeight > w) {
                    best = room;
                    bestSize = s;
                    bestWeight = w;
                }
            }
            if (best == null)
                continue loop;
            rooms.add(best);
            size += bestSize;
        }
        if (size >= exam.getSize())
            return rooms;
    }
    return null;
}
Also used : ExamRoomSharing(org.cpsolver.exam.model.ExamRoomSharing) ExamRoomPlacement(org.cpsolver.exam.model.ExamRoomPlacement) RoomPenalty(org.cpsolver.exam.criteria.RoomPenalty) ExamPlacement(org.cpsolver.exam.model.ExamPlacement) ExamModel(org.cpsolver.exam.model.ExamModel) ArrayList(java.util.ArrayList) List(java.util.List) RoomSizePenalty(org.cpsolver.exam.criteria.RoomSizePenalty) DistributionPenalty(org.cpsolver.exam.criteria.DistributionPenalty) HashSet(java.util.HashSet)

Example 7 with ExamRoomPlacement

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

the class RoomSizePenalty method getValue.

@Override
public double getValue(Assignment<Exam, ExamPlacement> assignment, ExamPlacement value, Set<ExamPlacement> conflicts) {
    Exam exam = value.variable();
    int size = 0;
    if (value.getRoomPlacements() != null)
        for (ExamRoomPlacement r : value.getRoomPlacements()) {
            size += r.getSize(exam.hasAltSeating());
        }
    int diff = size - exam.getSize();
    return (diff < 0 ? 0 : Math.pow(diff, iRoomSizeFactor));
}
Also used : ExamRoomPlacement(org.cpsolver.exam.model.ExamRoomPlacement) Exam(org.cpsolver.exam.model.Exam)

Example 8 with ExamRoomPlacement

use of org.cpsolver.exam.model.ExamRoomPlacement 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;
}
Also used : ExamRoomPlacement(org.cpsolver.exam.model.ExamRoomPlacement) ExamPlacement(org.cpsolver.exam.model.ExamPlacement) ArrayList(java.util.ArrayList) ExamStudent(org.cpsolver.exam.model.ExamStudent) Exam(org.cpsolver.exam.model.Exam)

Example 9 with ExamRoomPlacement

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

the class ExamSplitter method split.

/**
     * Split an exam
     * @param assignment current assignment
     * @param parent an exam to be split
     * @param iteration solver iteration
     * @param placement placement of the new exam
     * @return new exam assigned to the given placement with students moved into it; null if the given exam cannot be split
     */
public Exam split(Assignment<Exam, ExamPlacement> assignment, Exam parent, long iteration, ExamPlacement placement) {
    if (!canSplit(parent))
        return null;
    // Create the child exam
    Exam child = new Exam(--iLastSplitId, parent.getName(), parent.getLength(), parent.hasAltSeating(), parent.getMaxRooms(), parent.getMinSize(), parent.getPeriodPlacements(), parent.getRoomPlacements());
    child.setSizeOverride(parent.getSizeOverride());
    child.setPrintOffset(parent.getPrintOffset());
    child.setAveragePeriod(parent.getAveragePeriod());
    child.getOwners().addAll(parent.getOwners());
    // Update the parent and children structures
    iParent.put(child, parent);
    List<Exam> children = iChildren.get(parent);
    if (children == null) {
        children = new ArrayList<Exam>();
        iChildren.put(parent, children);
    }
    children.add(child);
    iValue += 1.0;
    // Add into model
    parent.getModel().addVariable(child);
    for (ExamRoomPlacement room : child.getRoomPlacements()) room.getRoom().addVariable(child);
    if (placement != null)
        assignment.assign(iteration, new ExamPlacement(child, placement.getPeriodPlacement(), placement.getRoomPlacements()));
    // Shuffle students between parent exam and its children
    shuffle(assignment, parent, iteration);
    // Return the new exam
    return child;
}
Also used : ExamRoomPlacement(org.cpsolver.exam.model.ExamRoomPlacement) ExamPlacement(org.cpsolver.exam.model.ExamPlacement) Exam(org.cpsolver.exam.model.Exam)

Example 10 with ExamRoomPlacement

use of org.cpsolver.exam.model.ExamRoomPlacement 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

ExamRoomPlacement (org.cpsolver.exam.model.ExamRoomPlacement)25 Exam (org.cpsolver.exam.model.Exam)21 ExamPlacement (org.cpsolver.exam.model.ExamPlacement)21 ExamPeriodPlacement (org.cpsolver.exam.model.ExamPeriodPlacement)11 ArrayList (java.util.ArrayList)9 ExamModel (org.cpsolver.exam.model.ExamModel)9 CSVFile (org.cpsolver.ifs.util.CSVFile)6 CSVField (org.cpsolver.ifs.util.CSVFile.CSVField)6 HashSet (java.util.HashSet)4 ExamOwner (org.cpsolver.exam.model.ExamOwner)4 ExamStudent (org.cpsolver.exam.model.ExamStudent)4 TreeSet (java.util.TreeSet)3 ExamPeriod (org.cpsolver.exam.model.ExamPeriod)3 HashMap (java.util.HashMap)2 StudentBackToBackConflicts (org.cpsolver.exam.criteria.StudentBackToBackConflicts)2 StudentDistanceBackToBackConflicts (org.cpsolver.exam.criteria.StudentDistanceBackToBackConflicts)2 ExamInstructor (org.cpsolver.exam.model.ExamInstructor)2 ExamRoomSharing (org.cpsolver.exam.model.ExamRoomSharing)2 ExamSimpleNeighbour (org.cpsolver.exam.neighbours.ExamSimpleNeighbour)2 AssignmentContext (org.cpsolver.ifs.assignment.context.AssignmentContext)2