Search in sources :

Example 1 with ExamPeriodPlacement

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

the class PeriodSizePenalty 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.getPeriodPlacements().isEmpty()) {
            int minSizePenalty = Integer.MAX_VALUE, maxSizePenalty = Integer.MIN_VALUE;
            for (ExamPeriodPlacement periodPlacement : exam.getPeriodPlacements()) {
                minSizePenalty = Math.min(minSizePenalty, periodPlacement.getPenalty() * (exam.getSize() + 1));
                maxSizePenalty = Math.max(maxSizePenalty, periodPlacement.getPenalty() * (exam.getSize() + 1));
            }
            bounds[0] += minSizePenalty;
            bounds[1] += maxSizePenalty;
        }
    }
    return bounds;
}
Also used : ExamPeriodPlacement(org.cpsolver.exam.model.ExamPeriodPlacement) Exam(org.cpsolver.exam.model.Exam)

Example 2 with ExamPeriodPlacement

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

use of org.cpsolver.exam.model.ExamPeriodPlacement 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.countInstructorConflicts(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 4 with ExamPeriodPlacement

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

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

Aggregations

ExamPeriodPlacement (org.cpsolver.exam.model.ExamPeriodPlacement)13 Exam (org.cpsolver.exam.model.Exam)12 ExamPlacement (org.cpsolver.exam.model.ExamPlacement)11 ExamRoomPlacement (org.cpsolver.exam.model.ExamRoomPlacement)11 ExamModel (org.cpsolver.exam.model.ExamModel)8 ArrayList (java.util.ArrayList)3 HashSet (java.util.HashSet)3 HashMap (java.util.HashMap)2 ExamSimpleNeighbour (org.cpsolver.exam.neighbours.ExamSimpleNeighbour)2 AssignmentContext (org.cpsolver.ifs.assignment.context.AssignmentContext)2 NeighbourSelectionWithContext (org.cpsolver.ifs.assignment.context.NeighbourSelectionWithContext)2 Set (java.util.Set)1 TreeSet (java.util.TreeSet)1 ExamDistributionConstraint (org.cpsolver.exam.model.ExamDistributionConstraint)1 ExamInstructor (org.cpsolver.exam.model.ExamInstructor)1 ExamRoomSharing (org.cpsolver.exam.model.ExamRoomSharing)1 ExamStudent (org.cpsolver.exam.model.ExamStudent)1 Assignment (org.cpsolver.ifs.assignment.Assignment)1 LazySwap (org.cpsolver.ifs.model.LazySwap)1 Neighbour (org.cpsolver.ifs.model.Neighbour)1