use of org.cpsolver.exam.model.ExamPlacement in project cpsolver by UniTime.
the class ExamSimulatedAnnealing method accept.
/**
* True if the given neighboir is to be be accepted
*
* @param solution
* current solution
* @param neighbour
* proposed move
* @return true if generated random number is below
* {@link ExamSimulatedAnnealing.Context#prob(double)}
*/
protected boolean accept(Solution<Exam, ExamPlacement> solution, Neighbour<Exam, ExamPlacement> neighbour) {
if (neighbour instanceof LazyNeighbour) {
((LazyNeighbour<Exam, ExamPlacement>) neighbour).setAcceptanceCriterion(this);
return true;
}
Assignment<Exam, ExamPlacement> assignment = solution.getAssignment();
double value = (iRelativeAcceptance ? neighbour.value(assignment) : solution.getModel().getTotalValue(assignment) + neighbour.value(assignment) - solution.getBestValue());
Context context = getContext(solution.getAssignment());
double prob = context.prob(value);
if (prob >= 1.0 || ToolBox.random() < prob) {
context.accepted(neighbour.value(assignment));
return true;
}
return false;
}
use of org.cpsolver.exam.model.ExamPlacement in project cpsolver by UniTime.
the class ExamSplitter method shuffle.
/**
* Shuffle students between the given exam and all the other exams in the split (if there are any).
* Only moves between exams that improve {@link ExamSplitter#delta(Assignment, ExamStudent, ExamPlacement, ExamPlacement)} are
* considered.
* @param assignment current assignment
* @param exam an exam in question
* @param iteration solver iteration
*/
public void shuffle(Assignment<Exam, ExamPlacement> assignment, Exam exam, long iteration) {
// Parent exam (its either the exam itself, or its parent if it has been already split)
Exam parent = (iParent.containsKey(exam) ? iParent.get(exam) : exam);
// Its children (if already split)
List<Exam> children = iChildren.get(parent);
if (children != null && !children.isEmpty()) {
// Unassign all involved exams
Map<Exam, ExamPlacement> assignments = new HashMap<Exam, ExamPlacement>();
if (assignment.getValue(parent) != null) {
assignments.put(parent, assignment.getValue(parent));
assignment.unassign(iteration, parent);
}
for (Exam child : children) {
if (assignment.getValue(child) != null) {
assignments.put(child, assignment.getValue(child));
assignment.unassign(iteration, child);
}
}
// Move away from parent
for (ExamStudent student : new ArrayList<ExamStudent>(parent.getStudents())) {
Exam child = null;
double delta = 0;
for (Exam x : children) {
double d = delta(assignment, student, assignments.get(parent), assignments.get(x));
if (child == null || d < delta) {
delta = d;
child = x;
}
}
if (child != null && delta < 0) {
student.removeVariable(parent);
student.addVariable(child);
}
}
// Move students away from a child
for (Exam child : children) {
for (ExamStudent student : new ArrayList<ExamStudent>(child.getStudents())) {
Exam other = parent;
double delta = delta(assignment, student, assignments.get(child), assignments.get(parent));
for (Exam x : children) {
if (x.equals(child))
continue;
double d = delta(assignment, student, assignments.get(child), assignments.get(x));
if (d < delta) {
delta = d;
other = x;
}
}
if (other != null && delta < 0) {
student.removeVariable(child);
student.addVariable(other);
}
}
}
// Assign everything back
ExamPlacement parentPlacement = assignments.get(parent);
if (parentPlacement != null)
assignment.assign(iteration, parentPlacement);
for (Exam child : children) {
ExamPlacement placement = assignments.get(child);
if (placement != null)
assignment.assign(iteration, placement);
}
}
}
use of org.cpsolver.exam.model.ExamPlacement in project cpsolver by UniTime.
the class ExamSplitter method bestSaved.
/** Best solution was saved, remember the current splits */
@Override
public void bestSaved(Assignment<Exam, ExamPlacement> assignment) {
super.bestSaved(assignment);
if (iBestSplit == null)
iBestSplit = new Hashtable<Exam, List<ExamPlacement>>();
else
iBestSplit.clear();
for (Map.Entry<Exam, List<Exam>> entry : iChildren.entrySet()) {
Exam parent = entry.getKey();
List<ExamPlacement> placements = new ArrayList<ExamPlacement>();
for (Exam child : entry.getValue()) {
if (assignment.getValue(child) != null)
placements.add(assignment.getValue(child));
}
if (!placements.isEmpty())
iBestSplit.put(parent, placements);
}
}
use of org.cpsolver.exam.model.ExamPlacement in project cpsolver by UniTime.
the class ExamSplitter method merge.
/**
* Merge an exam
* @param assignment current assignment
* @param child an exam to be merged
* @param iteration solver iteration
* @return parent exam of the exam that has been deleted; null if the given exam cannot be merged
*/
public Exam merge(Assignment<Exam, ExamPlacement> assignment, Exam child, long iteration) {
if (!canMerge(child))
return null;
// Update the parent and children structures
Exam parent = iParent.get(child);
iParent.remove(child);
List<Exam> children = iChildren.get(parent);
children.remove(child);
iValue -= 1.0;
// Unassign parent and the given exam
ExamPlacement parentPlacement = assignment.getValue(parent);
if (parentPlacement != null)
assignment.unassign(iteration, parent);
if (assignment.getValue(child) != null)
assignment.unassign(iteration, child);
// Move students back from the given exam
for (ExamStudent student : new ArrayList<ExamStudent>(child.getStudents())) {
student.removeVariable(child);
student.addVariable(parent);
}
// Remove the given exam from the model
for (ExamRoomPlacement room : child.getRoomPlacements()) room.getRoom().removeVariable(child);
parent.getModel().removeVariable(child);
// Assign parent exam back
if (parentPlacement != null)
assignment.assign(iteration, parentPlacement);
// Shuffle students between parent exam and its remaining children
shuffle(assignment, parent, iteration);
// Return parent exam
return parent;
}
use of org.cpsolver.exam.model.ExamPlacement in project cpsolver by UniTime.
the class ExamSplitter method split.
/**
* Split an exam
* @param assignment current assignment
* @param parent an exam to be split
* @param iteration solver iteration
* @param placement placement of the new exam
* @return new exam assigned to the given placement with students moved into it; null if the given exam cannot be split
*/
public Exam split(Assignment<Exam, ExamPlacement> assignment, Exam parent, long iteration, ExamPlacement placement) {
if (!canSplit(parent))
return null;
// Create the child exam
Exam child = new Exam(--iLastSplitId, parent.getName(), parent.getLength(), parent.hasAltSeating(), parent.getMaxRooms(), parent.getMinSize(), parent.getPeriodPlacements(), parent.getRoomPlacements());
child.setSizeOverride(parent.getSizeOverride());
child.setPrintOffset(parent.getPrintOffset());
child.setAveragePeriod(parent.getAveragePeriod());
child.getOwners().addAll(parent.getOwners());
// Update the parent and children structures
iParent.put(child, parent);
List<Exam> children = iChildren.get(parent);
if (children == null) {
children = new ArrayList<Exam>();
iChildren.put(parent, children);
}
children.add(child);
iValue += 1.0;
// Add into model
parent.getModel().addVariable(child);
for (ExamRoomPlacement room : child.getRoomPlacements()) room.getRoom().addVariable(child);
if (placement != null)
assignment.assign(iteration, new ExamPlacement(child, placement.getPeriodPlacement(), placement.getRoomPlacements()));
// Shuffle students between parent exam and its children
shuffle(assignment, parent, iteration);
// Return the new exam
return child;
}
Aggregations