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;
}
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;
}
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);
}
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);
}
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;
}
Aggregations