Search in sources :

Example 1 with ExamRoomSharing

use of org.cpsolver.exam.model.ExamRoomSharing 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 2 with ExamRoomSharing

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

the class ExamTimeMove method selectNeighbour.

/**
     * Select an exam randomly,
     * select an available period randomly (if it is not assigned), 
     * use rooms if possible, select rooms using {@link Exam#findBestAvailableRooms(Assignment, ExamPeriodPlacement)} if not (exam is unassigned, a room is not available or used).
     */
@Override
public Neighbour<Exam, ExamPlacement> selectNeighbour(Solution<Exam, ExamPlacement> solution) {
    ExamModel model = (ExamModel) solution.getModel();
    Assignment<Exam, ExamPlacement> assignment = solution.getAssignment();
    ExamRoomSharing sharing = model.getRoomSharing();
    Exam exam = ToolBox.random(model.variables());
    ExamPlacement placement = assignment.getValue(exam);
    int px = ToolBox.random(exam.getPeriodPlacements().size());
    for (int p = 0; p < exam.getPeriodPlacements().size(); p++) {
        ExamPeriodPlacement period = exam.getPeriodPlacements().get((p + px) % exam.getPeriodPlacements().size());
        if (placement != null && placement.getPeriod().equals(period))
            continue;
        if (iCheckStudentConflicts && exam.countStudentConflicts(assignment, period) > 0)
            continue;
        if (iCheckDistributionConstraints && !exam.checkDistributionConstraints(assignment, period))
            continue;
        if (placement != null) {
            boolean ok = true;
            if (sharing != null && placement.getRoomPlacements().size() == 1) {
                ExamRoomPlacement room = placement.getRoomPlacements().iterator().next();
                ok = room.isAvailable(period.getPeriod()) && !sharing.inConflict(exam, room.getRoom().getPlacements(assignment, period.getPeriod()), room.getRoom());
            } else {
                for (Iterator<ExamRoomPlacement> i = placement.getRoomPlacements().iterator(); i.hasNext(); ) {
                    ExamRoomPlacement room = i.next();
                    if (!room.isAvailable(period.getPeriod()) || !room.getRoom().getPlacements(assignment, period.getPeriod()).isEmpty()) {
                        ok = false;
                        break;
                    }
                }
            }
            if (ok)
                return new ExamSimpleNeighbour(assignment, new ExamPlacement(exam, period, placement.getRoomPlacements()));
        }
        Set<ExamRoomPlacement> rooms = exam.findBestAvailableRooms(assignment, period);
        if (rooms == null)
            continue;
        return new ExamSimpleNeighbour(assignment, new ExamPlacement(exam, period, rooms));
    }
    return null;
}
Also used : ExamRoomSharing(org.cpsolver.exam.model.ExamRoomSharing) ExamRoomPlacement(org.cpsolver.exam.model.ExamRoomPlacement) ExamPlacement(org.cpsolver.exam.model.ExamPlacement) ExamModel(org.cpsolver.exam.model.ExamModel) ExamPeriodPlacement(org.cpsolver.exam.model.ExamPeriodPlacement) Exam(org.cpsolver.exam.model.Exam)

Aggregations

ExamModel (org.cpsolver.exam.model.ExamModel)2 ExamPlacement (org.cpsolver.exam.model.ExamPlacement)2 ExamRoomPlacement (org.cpsolver.exam.model.ExamRoomPlacement)2 ExamRoomSharing (org.cpsolver.exam.model.ExamRoomSharing)2 ArrayList (java.util.ArrayList)1 HashSet (java.util.HashSet)1 List (java.util.List)1 DistributionPenalty (org.cpsolver.exam.criteria.DistributionPenalty)1 RoomPenalty (org.cpsolver.exam.criteria.RoomPenalty)1 RoomSizePenalty (org.cpsolver.exam.criteria.RoomSizePenalty)1 Exam (org.cpsolver.exam.model.Exam)1 ExamPeriodPlacement (org.cpsolver.exam.model.ExamPeriodPlacement)1