Search in sources :

Example 1 with ExamRoomPlacement

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

the class RoomPenalty method getBounds.

@Override
public double[] getBounds(Assignment<Exam, ExamPlacement> assignment, Collection<Exam> variables) {
    double[] bounds = new double[] { 0.0, 0.0 };
    for (Exam exam : variables) {
        if (!exam.getRoomPlacements().isEmpty()) {
            int minPenalty = Integer.MAX_VALUE, maxPenalty = Integer.MIN_VALUE;
            for (ExamRoomPlacement roomPlacement : exam.getRoomPlacements()) {
                if (iSoftRooms != null && iSoftRooms == roomPlacement.getPenalty())
                    continue;
                if (!isAvailable(roomPlacement.getRoom()))
                    continue;
                minPenalty = Math.min(minPenalty, 2 * roomPlacement.getPenalty() + getMinPenalty(roomPlacement.getRoom()));
                maxPenalty = Math.max(maxPenalty, 2 * roomPlacement.getPenalty() + getMaxPenalty(roomPlacement.getRoom()));
            }
            bounds[0] += minPenalty;
            bounds[1] += maxPenalty;
        }
    }
    return bounds;
}
Also used : ExamRoomPlacement(org.cpsolver.exam.model.ExamRoomPlacement) Exam(org.cpsolver.exam.model.Exam)

Example 2 with ExamRoomPlacement

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

the class ExamColoringConstruction method selectNeighbour.

@Override
public Neighbour<Exam, ExamPlacement> selectNeighbour(final Solution<Exam, ExamPlacement> solution) {
    ExamModel model = (ExamModel) solution.getModel();
    // if (!model.assignedVariables().isEmpty()) return null;
    final HashMap<Exam, Vertex> vertices = new HashMap<Exam, Vertex>();
    for (Exam x : model.variables()) {
        vertices.put(x, new Vertex(x));
    }
    for (ExamStudent s : model.getStudents()) {
        for (Exam x : s.variables()) {
            for (Exam y : s.variables()) {
                if (!x.equals(y)) {
                    vertices.get(x).neighbors().add(vertices.get(y));
                    vertices.get(y).neighbors().add(vertices.get(x));
                }
            }
        }
    }
    for (ExamInstructor i : model.getInstructors()) {
        for (Exam x : i.variables()) {
            for (Exam y : i.variables()) {
                if (!x.equals(y)) {
                    vertices.get(x).neighbors().add(vertices.get(y));
                    vertices.get(y).neighbors().add(vertices.get(x));
                }
            }
        }
    }
    iProgress.setPhase("Graph coloring-based construction", vertices.size());
    iProgress.info("Looking for a conflict-free assignment using " + model.getPeriods().size() + " periods.");
    iT0 = JProf.currentTimeSec();
    iTimeLimitReached = false;
    if (iMode.isGreedy()) {
        iProgress.info("Using greedy heuristics only (no backtracking)...");
    } else if (backTrack(solution, 0, (iMode.isRedundant() ? null : new HashSet<Integer>()), vertices.values())) {
        iProgress.info("Success!");
    } else if (iTimeLimitReached) {
        iProgress.info("There was no conflict-free schedule found during the given time.");
    } else if (iSolver.isStop()) {
        iProgress.info("Solver was stopped.");
    } else {
        if (iMode.isRedundant())
            iProgress.info("There is no conflict-free schedule!");
        else
            iProgress.info("Conflict-free schedule not found.");
    }
    if (iMode.isConstraintCheck())
        solution.restoreBest();
    HashSet<Vertex> remaning = new HashSet<Vertex>();
    for (Vertex v : vertices.values()) if (v.color() < 0)
        remaning.add(v);
    remaining: while (!remaning.isEmpty()) {
        Vertex vertex = null;
        for (Vertex v : remaning) if (vertex == null || v.compareTo(vertex) < 0)
            vertex = v;
        remaning.remove(vertex);
        for (int color : vertex.domain()) if (vertex.colorize(solution.getAssignment(), color))
            continue remaining;
    }
    if (!iMode.isConstraintCheck()) {
        return new Neighbour<Exam, ExamPlacement>() {

            @Override
            public void assign(Assignment<Exam, ExamPlacement> assignment, long iteration) {
                iProgress.info("Using graph coloring solution ...");
                for (Vertex vertex : new TreeSet<Vertex>(vertices.values())) {
                    ExamPeriodPlacement period = vertex.period();
                    if (period == null || !vertex.exam().checkDistributionConstraints(assignment, period))
                        continue;
                    Set<ExamRoomPlacement> rooms = findRooms(assignment, vertex.exam(), period);
                    if (rooms == null)
                        continue;
                    assignment.assign(iteration, new ExamPlacement(vertex.exam(), period, rooms));
                }
                HashSet<Vertex> unassigned = new HashSet<Vertex>();
                for (Vertex vertex : vertices.values()) {
                    if (assignment.getValue(vertex.exam()) == null) {
                        unassigned.add(vertex);
                        vertex.colorize(assignment, -1);
                    }
                }
                solution.saveBest();
                iProgress.info("Extending ...");
                unassigned: while (!unassigned.isEmpty()) {
                    Vertex vertex = null;
                    for (Vertex v : unassigned) if (vertex == null || v.compareTo(vertex) < 0)
                        vertex = v;
                    unassigned.remove(vertex);
                    for (int color : vertex.domain()) {
                        if (!vertex.colorize(assignment, color))
                            continue;
                        ExamPeriodPlacement period = vertex.period(color);
                        if (period == null || !vertex.exam().checkDistributionConstraints(assignment, period))
                            continue;
                        Set<ExamRoomPlacement> rooms = findRooms(assignment, vertex.exam(), period);
                        if (rooms == null)
                            continue;
                        assignment.assign(iteration, new ExamPlacement(vertex.exam(), period, rooms));
                        continue unassigned;
                    }
                    vertex.colorize(assignment, -1);
                }
                solution.saveBest();
                iProgress.info("Construction done.");
            }

            @Override
            public double value(Assignment<Exam, ExamPlacement> assignment) {
                return 0;
            }

            @Override
            public Map<Exam, ExamPlacement> assignments() {
                throw new UnsupportedOperationException();
            }
        };
    }
    return null;
}
Also used : ExamInstructor(org.cpsolver.exam.model.ExamInstructor) Set(java.util.Set) TreeSet(java.util.TreeSet) HashSet(java.util.HashSet) HashMap(java.util.HashMap) ExamModel(org.cpsolver.exam.model.ExamModel) ExamStudent(org.cpsolver.exam.model.ExamStudent) Assignment(org.cpsolver.ifs.assignment.Assignment) ExamRoomPlacement(org.cpsolver.exam.model.ExamRoomPlacement) Neighbour(org.cpsolver.ifs.model.Neighbour) ExamPlacement(org.cpsolver.exam.model.ExamPlacement) TreeSet(java.util.TreeSet) ExamPeriodPlacement(org.cpsolver.exam.model.ExamPeriodPlacement) Exam(org.cpsolver.exam.model.Exam) HashSet(java.util.HashSet)

Example 3 with ExamRoomPlacement

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

the class ExamConstruction method selectNeighbour.

/**
     * Select a neighbour. While there are exams that are still not assigned:
     * <ul>
     * <li>The worst unassigned exam is selected (using
     * {@link Exam#compareTo(Exam)})
     * <li>The best period that does not break any hard constraint and for which
     * there is a room assignment available is selected together with the set
     * the best available rooms for the exam in the best period (computed using
     * {@link Exam#findBestAvailableRooms(Assignment, ExamPeriodPlacement)}).
     * </ul>
     * Return null when done (all variables are assigned and the problem is
     * locally optimal).
     */
@Override
public Neighbour<Exam, ExamPlacement> selectNeighbour(Solution<Exam, ExamPlacement> solution) {
    ExamModel model = (ExamModel) solution.getModel();
    Assignment<Exam, ExamPlacement> assignment = solution.getAssignment();
    Context context = getContext(assignment);
    if (!iActive) {
        iActive = true;
        // iProgress.setPhase("Construction ...", model.variables().size());
        iProgress.info("[" + Thread.currentThread().getName() + "] Construction ...");
    }
    // iProgress.setProgress(assignment.nrAssignedVariables());
    if (model.variables().size() - assignment.nrAssignedVariables() <= context.skip().size())
        return checkLocalOptimality(assignment, model);
    Exam bestExam = null;
    for (Exam exam : model.variables()) {
        if (assignment.getValue(exam) != null || context.skip().contains(exam))
            continue;
        if (bestExam == null || exam.compareTo(bestExam) < 0)
            bestExam = exam;
    }
    ExamPlacement best = null;
    for (ExamPeriodPlacement period : bestExam.getPeriodPlacements()) {
        if (bestExam.countStudentConflicts(assignment, period) > 0) {
            if (context.assignments().contains(bestExam.getId() + ":" + period.getIndex()))
                continue;
        }
        if (!bestExam.checkDistributionConstraints(assignment, period))
            continue;
        ExamPlacement placement = new ExamPlacement(bestExam, period, null);
        if (best == null || best.getTimeCost(assignment) > placement.getTimeCost(assignment)) {
            Set<ExamRoomPlacement> rooms = bestExam.findBestAvailableRooms(assignment, period);
            if (rooms != null)
                best = new ExamPlacement(bestExam, period, rooms);
        }
    }
    if (best != null) {
        context.assignments().add(bestExam.getId() + ":" + best.getPeriod().getIndex());
        return new ExamSimpleNeighbour(assignment, best);
    }
    /*
           * else { for (Enumeration
           * e=bestExam.getPeriodPlacements().elements();e.hasMoreElements();) {
           * ExamPeriodPlacement period = (ExamPeriodPlacement)e.nextElement();
           * ExamPlacement placement = new ExamPlacement(bestExam, period,
           * null); if (best==null ||
           * best.getTimeCost()>placement.getTimeCost()) { Set rooms =
           * bestExam.findBestAvailableRooms(period); if (rooms!=null) best =
           * new ExamPlacement(bestExam, period, rooms); } } if (best!=null) {
           * bestExam.allowAllStudentConflicts(best.getPeriod());
           * iAssignments.add(bestExam.getId()+":"+best.getPeriod().getIndex());
           * return new ExamSimpleNeighbour(best); } }
           */
    if (!context.skip().contains(bestExam)) {
        context.skip().add(bestExam);
        return selectNeighbour(solution);
    }
    return checkLocalOptimality(assignment, model);
}
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) ExamModel(org.cpsolver.exam.model.ExamModel) ExamPeriodPlacement(org.cpsolver.exam.model.ExamPeriodPlacement) Exam(org.cpsolver.exam.model.Exam) ExamSimpleNeighbour(org.cpsolver.exam.neighbours.ExamSimpleNeighbour)

Example 4 with ExamRoomPlacement

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

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

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