Search in sources :

Example 6 with ExamPlacement

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

the class ExamTabuSearch method selectNeighbour.

/**
     * Neighbor selection
     */
@Override
public Neighbour<Exam, ExamPlacement> selectNeighbour(Solution<Exam, ExamPlacement> solution) {
    if (iFirstIteration < 0)
        iFirstIteration = solution.getIteration();
    TabuList tabu = getContext(solution.getAssignment());
    long idle = solution.getIteration() - Math.max(iFirstIteration, solution.getBestIteration());
    if (idle > iMaxIdleIterations) {
        sLog.debug("  [tabu]    max idle iterations reached");
        iFirstIteration = -1;
        if (tabu.size() > 0)
            tabu.clear();
        return null;
    }
    if (tabu.size() > 0 && iTabuMaxSize > iTabuMinSize) {
        if (idle == 0) {
            tabu.resize(iTabuMinSize);
        } else if (idle % (iMaxIdleIterations / (iTabuMaxSize - iTabuMinSize)) == 0) {
            tabu.resize(Math.min(iTabuMaxSize, tabu.size() + 1));
        }
    }
    boolean acceptConflicts = solution.getModel().getBestUnassignedVariables() > 0;
    ExamModel model = (ExamModel) solution.getModel();
    Assignment<Exam, ExamPlacement> assignment = solution.getAssignment();
    double bestEval = 0.0;
    List<ExamPlacement> best = null;
    for (Exam exam : model.variables()) {
        ExamPlacement assigned = assignment.getValue(exam);
        double assignedVal = (assigned == null ? iConflictWeight : iValueWeight * assigned.toDouble(assignment));
        for (ExamPeriodPlacement period : exam.getPeriodPlacements()) {
            Set<ExamRoomPlacement> rooms = exam.findBestAvailableRooms(assignment, period);
            if (rooms == null)
                rooms = exam.findRoomsRandom(assignment, period, false);
            if (rooms == null)
                continue;
            ExamPlacement value = new ExamPlacement(exam, period, rooms);
            if (value.equals(assigned))
                continue;
            double eval = iValueWeight * value.toDouble(assignment) - assignedVal;
            if (acceptConflicts) {
                Set<ExamPlacement> conflicts = model.conflictValues(assignment, value);
                for (ExamPlacement conflict : conflicts) {
                    eval -= iValueWeight * conflict.toDouble(assignment);
                    eval += iConflictWeight * (1.0 + (iStat == null ? 0.0 : iStat.countRemovals(solution.getIteration(), conflict, value)));
                }
            } else {
                if (model.inConflict(assignment, value))
                    continue;
            }
            if (tabu.size() > 0 && tabu.contains(exam.getId() + ":" + value.getPeriod().getIndex())) {
                int un = model.variables().size() - assignment.nrAssignedVariables() - (assigned == null ? 0 : 1);
                if (un > model.getBestUnassignedVariables())
                    continue;
                if (un == model.getBestUnassignedVariables() && model.getTotalValue(assignment) + eval >= solution.getBestValue())
                    continue;
            }
            if (best == null || bestEval > eval) {
                if (best == null)
                    best = new ArrayList<ExamPlacement>();
                else
                    best.clear();
                best.add(value);
                bestEval = eval;
            } else if (bestEval == eval) {
                best.add(value);
            }
        }
    }
    if (best == null) {
        sLog.debug("  [tabu] --none--");
        iFirstIteration = -1;
        if (tabu.size() > 0)
            tabu.clear();
        return null;
    }
    ExamPlacement bestVal = ToolBox.random(best);
    if (sLog.isDebugEnabled()) {
        Set<ExamPlacement> conflicts = model.conflictValues(assignment, bestVal);
        double wconf = (iStat == null ? 0.0 : iStat.countRemovals(solution.getIteration(), conflicts, bestVal));
        sLog.debug("  [tabu] " + bestVal + " (" + (assignment.getValue(bestVal.variable()) == null ? "" : "was=" + assignment.getValue(bestVal.variable()) + ", ") + "val=" + bestEval + (conflicts.isEmpty() ? "" : ", conf=" + (wconf + conflicts.size()) + "/" + conflicts) + ")");
    }
    if (tabu.size() > 0)
        tabu.add(bestVal.variable().getId() + ":" + bestVal.getPeriod().getIndex());
    return new SimpleNeighbour<Exam, ExamPlacement>(bestVal.variable(), bestVal);
}
Also used : ExamModel(org.cpsolver.exam.model.ExamModel) ArrayList(java.util.ArrayList) ExamRoomPlacement(org.cpsolver.exam.model.ExamRoomPlacement) ExamPlacement(org.cpsolver.exam.model.ExamPlacement) SimpleNeighbour(org.cpsolver.ifs.model.SimpleNeighbour) ExamPeriodPlacement(org.cpsolver.exam.model.ExamPeriodPlacement) Exam(org.cpsolver.exam.model.Exam)

Example 7 with ExamPlacement

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

the class ExamConstruction method checkLocalOptimality.

/**
     * Find a new assignment of one of the assigned exams that improves the time
     * cost {@link ExamPlacement#getTimeCost(Assignment)} and for which there is a set of
     * available rooms {@link Exam#findBestAvailableRooms(Assignment, ExamPeriodPlacement)}.
     * Return null, if there is no such assignment (the problem is considered
     * locally optimal).
     * @param assignment current assignment
     * @param model problem model
     * @return a neighbour to assign or null if none was found
     */
public Neighbour<Exam, ExamPlacement> checkLocalOptimality(Assignment<Exam, ExamPlacement> assignment, ExamModel model) {
    if (iCheckLocalOptimality) {
        Context context = getContext(assignment);
        for (Exam exam : assignment.assignedVariables()) {
            ExamPlacement current = assignment.getValue(exam);
            if (current.getTimeCost(assignment) <= 0)
                continue;
            ExamPlacement best = null;
            for (ExamPeriodPlacement period : exam.getPeriodPlacements()) {
                if (exam.countStudentConflicts(assignment, period) > 0) {
                    if (context.assignments().contains(exam.getId() + ":" + period.getIndex()))
                        continue;
                }
                if (!exam.checkDistributionConstraints(assignment, period))
                    continue;
                ExamPlacement placement = new ExamPlacement(exam, period, null);
                if (best == null || best.getTimeCost(assignment) > placement.getTimeCost(assignment)) {
                    Set<ExamRoomPlacement> rooms = exam.findBestAvailableRooms(assignment, period);
                    if (rooms != null)
                        best = new ExamPlacement(exam, period, rooms);
                }
            }
            if (best != null && best.getTimeCost(assignment) < current.getTimeCost(assignment))
                return new ExamSimpleNeighbour(assignment, best);
        }
    }
    iActive = false;
    return null;
}
Also used : AssignmentContext(org.cpsolver.ifs.assignment.context.AssignmentContext) NeighbourSelectionWithContext(org.cpsolver.ifs.assignment.context.NeighbourSelectionWithContext) ExamRoomPlacement(org.cpsolver.exam.model.ExamRoomPlacement) ExamPlacement(org.cpsolver.exam.model.ExamPlacement) ExamPeriodPlacement(org.cpsolver.exam.model.ExamPeriodPlacement) Exam(org.cpsolver.exam.model.Exam) ExamSimpleNeighbour(org.cpsolver.exam.neighbours.ExamSimpleNeighbour)

Example 8 with ExamPlacement

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

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

the class ExamNeighbourSelection method selectNeighbour.

/**
     * Neighbour selection. It consists of the following three phases:
     * <ul>
     * <li>Construction phase ({@link ExamConstruction} until all exams are
     * assigned)
     * <li>Hill-climbing phase ({@link HillClimber} until the given number
     * if idle iterations)
     * <li>Simulated annealing phase ({@link SimulatedAnnealing} until
     * timeout is reached)
     * </ul>
     */
@SuppressWarnings("fallthrough")
@Override
public Neighbour<Exam, ExamPlacement> selectNeighbour(Solution<Exam, ExamPlacement> solution) {
    Neighbour<Exam, ExamPlacement> n = null;
    if (!isFinalPhase() && !iTerm.canContinue(solution))
        setFinalPhase(null);
    Context phase = getContext(solution.getAssignment());
    if (isFinalPhase())
        phase.setPhase(9999);
    switch(phase.getPhase()) {
        case -1:
            phase.setPhase(0);
            sLog.info("***** construction phase *****");
            if (iColor != null) {
                n = iColor.selectNeighbour(solution);
                if (n != null)
                    return n;
            }
        case 0:
            n = iCon.selectNeighbour(solution);
            if (n != null)
                return n;
            if (solution.getAssignment().nrAssignedVariables() > 0)
                iProgress.setPhase("Searching for initial solution...", solution.getModel().variables().size());
            phase.setPhase(1);
            sLog.info("***** cbs/tabu-search phase *****");
        case 1:
            if (iStd != null && solution.getModel().variables().size() > solution.getAssignment().nrAssignedVariables()) {
                iProgress.setProgress(solution.getModel().variables().size() - solution.getModel().getBestUnassignedVariables());
                n = iStd.selectNeighbour(solution);
                if (n != null)
                    return n;
            }
            phase.setPhase(2);
            sLog.info("***** hill climbing phase *****");
        case 2:
            n = iHC.selectNeighbour(solution);
            if (n != null)
                return n;
            phase.setPhase(3);
            sLog.info("***** " + (iUseGD ? "great deluge" : "simulated annealing") + " phase *****");
        case 3:
            if (iUseGD)
                return iGD.selectNeighbour(solution);
            else
                return iSA.selectNeighbour(solution);
        case 9999:
            n = iFin.selectNeighbour(solution);
            if (n != null)
                return n;
            phase.setPhase(-1);
            if (iFinalPhaseFinished != null && iTerm.canContinue(solution))
                iFinalPhaseFinished.execute();
            phase.setCanContinue(false);
        default:
            return null;
    }
}
Also used : AssignmentContext(org.cpsolver.ifs.assignment.context.AssignmentContext) NeighbourSelectionWithContext(org.cpsolver.ifs.assignment.context.NeighbourSelectionWithContext) ExamPlacement(org.cpsolver.exam.model.ExamPlacement) Exam(org.cpsolver.exam.model.Exam)

Example 10 with ExamPlacement

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

the class ExamSimulatedAnnealing method selectNeighbour.

/**
     * Select neighbour -- generate a move
     * {@link ExamSimulatedAnnealing#genMove(Solution)} until an acceptable
     * neighbour is found
     * {@link ExamSimulatedAnnealing#accept(Solution, Neighbour)}, keep
     * increasing iteration {@link ExamSimulatedAnnealing.Context#incIter(Solution)}.
     */
@Override
public Neighbour<Exam, ExamPlacement> selectNeighbour(Solution<Exam, ExamPlacement> solution) {
    Context context = getContext(solution.getAssignment());
    context.activateIfNeeded();
    Neighbour<Exam, ExamPlacement> neighbour = null;
    while ((neighbour = genMove(solution)) != null) {
        context.incMoves(neighbour.value(solution.getAssignment()));
        if (accept(solution, neighbour))
            break;
    }
    if (neighbour == null)
        context.reset();
    return (neighbour == null ? null : neighbour);
}
Also used : AssignmentContext(org.cpsolver.ifs.assignment.context.AssignmentContext) NeighbourSelectionWithContext(org.cpsolver.ifs.assignment.context.NeighbourSelectionWithContext) ExamPlacement(org.cpsolver.exam.model.ExamPlacement) Exam(org.cpsolver.exam.model.Exam)

Aggregations

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