use of org.cpsolver.exam.neighbours.ExamSimpleNeighbour 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.neighbours.ExamSimpleNeighbour 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