use of org.cpsolver.coursett.model.Placement in project cpsolver by UniTime.
the class LectureSelection method selectVariable.
@Override
public Lecture selectVariable(Solution<Lecture, Placement> solution) {
TimetableModel model = (TimetableModel) solution.getModel();
Assignment<Lecture, Placement> assignment = solution.getAssignment();
Collection<Lecture> unassignedVariables = model.unassignedVariables(assignment);
if (iInteractiveMode) {
// remove variables that have no values
unassignedVariables = new ArrayList<Lecture>(unassignedVariables.size());
for (Lecture variable : model.unassignedVariables(assignment)) {
if (!variable.values(solution.getAssignment()).isEmpty())
unassignedVariables.add(variable);
}
}
if (unassignedVariables.isEmpty()) {
Collection<Lecture> variables = model.perturbVariables(assignment);
if (variables.isEmpty())
variables = model.assignedVariables(assignment);
if (iRW && ToolBox.random() <= iRandomWalkProb)
return ToolBox.random(variables);
List<Lecture> selectionVariables = new ArrayList<Lecture>();
double worstValue = 0.0;
for (Iterator<Lecture> i1 = (iSubSetSelection ? ToolBox.subSet(variables, iSelectionSubSetPart, iSelectionSubSetMinSize) : variables).iterator(); i1.hasNext(); ) {
Lecture selectedVariable = i1.next();
if (iTabu != null && iTabu.contains(selectedVariable))
continue;
double value = assignment.getValue(selectedVariable).toDouble(assignment);
if (selectionVariables.isEmpty() || value > worstValue) {
selectionVariables.clear();
selectionVariables.add(selectedVariable);
worstValue = value;
} else if (worstValue == value) {
selectionVariables.add(selectedVariable);
}
}
Lecture selectedVariable = ToolBox.random(selectionVariables);
if (selectedVariable == null)
selectedVariable = ToolBox.random(variables);
if (selectedVariable != null && iTabu != null) {
if (iTabu.size() == iTabuPos)
iTabu.add(selectedVariable);
else
iTabu.set(iTabuPos, selectedVariable);
iTabuPos = (iTabuPos + 1) % iTabuSize;
}
return selectedVariable;
} else {
if (ToolBox.random() <= iRandomWalkProb)
return ToolBox.random(unassignedVariables);
if (iProp != null && iUnassignWhenNotGood) {
List<Lecture> noGoodVariables = new ArrayList<Lecture>();
for (Iterator<Lecture> i1 = ToolBox.subSet(unassignedVariables, iSelectionSubSetPart, iSelectionSubSetMinSize).iterator(); i1.hasNext(); ) {
Lecture variable = i1.next();
if (iProp.goodValues(assignment, variable).isEmpty())
noGoodVariables.add(variable);
}
if (!noGoodVariables.isEmpty()) {
if (ToolBox.random() < 0.02)
return ToolBox.random(assignment.assignedVariables());
for (int attempt = 0; attempt < 10; attempt++) {
Lecture noGoodVariable = ToolBox.random(noGoodVariables);
Placement noGoodValue = ToolBox.random(noGoodVariable.values(solution.getAssignment()));
if (!iProp.noGood(assignment, noGoodValue).isEmpty())
return ToolBox.random(iProp.noGood(assignment, noGoodValue)).variable();
}
}
}
if (iRouletteWheelSelection) {
int iMaxDomainSize = 0;
int iMaxGoodDomainSize = 0;
int iMaxConstraints = 0;
Collection<Lecture> variables = (iSubSetSelection ? ToolBox.subSet(unassignedVariables, iSelectionSubSetPart, iSelectionSubSetMinSize) : unassignedVariables);
for (Lecture variable : variables) {
if (iTabu != null && iTabu.contains(variable))
continue;
iMaxDomainSize = Math.max(iMaxDomainSize, variable.values(solution.getAssignment()).size());
iMaxGoodDomainSize = (iProp == null ? 0 : Math.max(iMaxGoodDomainSize, iProp.goodValues(assignment, variable).size()));
iMaxConstraints = Math.max(iMaxConstraints, variable.constraints().size());
}
List<Integer> points = new ArrayList<Integer>();
int totalPoints = 0;
for (Lecture variable : variables) {
long pointsThisVariable = Math.round(iDomainSizeWeight * (((double) (iMaxDomainSize - variable.values(solution.getAssignment()).size())) / ((double) iMaxDomainSize)) + (iProp == null ? 0.0 : iGoodValuesWeight * (((double) (iMaxGoodDomainSize - iProp.goodValues(assignment, variable).size())) / ((double) iMaxGoodDomainSize))) + iConstraintsWeight * (((double) (iMaxConstraints - variable.constraints().size())) / ((double) iMaxConstraints)) + iInitialAssignmentWeight * (variable.getInitialAssignment() != null ? model.conflictValues(assignment, variable.getInitialAssignment()).size() : 0.0));
if (pointsThisVariable > 0) {
totalPoints += pointsThisVariable;
points.add(totalPoints);
}
}
if (totalPoints > 0) {
int rndPoints = ToolBox.random(totalPoints);
Iterator<Lecture> x = variables.iterator();
for (int i = 0; x.hasNext() && i < points.size(); i++) {
Lecture variable = x.next();
int tp = points.get(i);
if (tp > rndPoints) {
if (variable != null && iTabu != null) {
if (iTabu.size() == iTabuPos)
iTabu.add(variable);
else
iTabu.set(iTabuPos, variable);
iTabuPos = (iTabuPos + 1) % iTabuSize;
}
return variable;
}
}
}
} else {
List<Lecture> selectionVariables = null;
long bestGood = 0;
for (Iterator<Lecture> i = ToolBox.subSet(unassignedVariables, iSelectionSubSetPart, iSelectionSubSetMinSize).iterator(); i.hasNext(); ) {
Lecture variable = i.next();
if (iTabu != null && iTabu.contains(variable))
continue;
long good = (long) (iDomainSizeWeight * variable.values(solution.getAssignment()).size() + iGoodValuesWeight * (iProp == null ? 0 : iProp.goodValues(assignment, variable).size()) + iConstraintsWeight * variable.constraints().size() + iInitialAssignmentWeight * (variable.getInitialAssignment() != null ? model.conflictValues(assignment, variable.getInitialAssignment()).size() : 0.0));
if (selectionVariables == null || bestGood > good) {
if (selectionVariables == null)
selectionVariables = new ArrayList<Lecture>();
else
selectionVariables.clear();
bestGood = good;
selectionVariables.add(variable);
} else if (good == bestGood) {
selectionVariables.add(variable);
}
}
if (!selectionVariables.isEmpty()) {
Lecture selectedVariable = ToolBox.random(selectionVariables);
if (selectedVariable != null && iTabu != null) {
if (iTabu.size() == iTabuPos)
iTabu.add(selectedVariable);
else
iTabu.set(iTabuPos, selectedVariable);
iTabuPos = (iTabuPos + 1) % iTabuSize;
}
return selectedVariable;
}
}
Lecture selectedVariable = ToolBox.random(unassignedVariables);
if (selectedVariable != null && iTabu != null) {
if (iTabu.size() == iTabuPos)
iTabu.add(selectedVariable);
else
iTabu.set(iTabuPos, selectedVariable);
iTabuPos = (iTabuPos + 1) % iTabuSize;
}
return selectedVariable;
}
}
use of org.cpsolver.coursett.model.Placement in project cpsolver by UniTime.
the class NeighbourSelectionWithSuggestions method backtrack.
private void backtrack(NeighbourSelectionWithSuggestionsContext context, List<Lecture> initialLectures, Map<Lecture, Placement> resolvedLectures, HashMap<Lecture, Placement> conflictsToResolve, int depth) {
int nrUnassigned = conflictsToResolve.size();
if ((initialLectures == null || initialLectures.isEmpty()) && nrUnassigned == 0) {
context.setSuggestionNeighbourIfImproving(resolvedLectures);
return;
}
if (depth <= 0 || context.checkTimeoutReached())
return;
Assignment<Lecture, Placement> assignment = context.getAssignment();
for (Lecture lecture : initialLectures != null && !initialLectures.isEmpty() ? initialLectures : new ArrayList<Lecture>(conflictsToResolve.keySet())) {
if (context.isTimeoutReached())
break;
if (resolvedLectures.containsKey(lecture))
continue;
placements: for (Placement placement : lecture.values(assignment)) {
if (context.isTimeoutReached())
break;
Placement cur = assignment.getValue(lecture);
if (placement.equals(cur))
continue;
if (placement.isHard(assignment))
continue;
Set<Placement> conflicts = context.getModel().conflictValues(assignment, placement);
if (nrUnassigned + conflicts.size() > depth)
continue;
if (conflicts.contains(placement))
continue;
if (containsCommited(context, conflicts))
continue;
for (Iterator<Placement> i = conflicts.iterator(); i.hasNext(); ) {
Placement c = i.next();
if (resolvedLectures.containsKey(c.variable()))
continue placements;
}
for (Iterator<Placement> i = conflicts.iterator(); i.hasNext(); ) {
Placement c = i.next();
assignment.unassign(0, c.variable());
}
assignment.assign(0, placement);
for (Iterator<Placement> i = conflicts.iterator(); i.hasNext(); ) {
Placement c = i.next();
conflictsToResolve.put(c.variable(), c);
}
Placement resolvedConf = conflictsToResolve.remove(lecture);
resolvedLectures.put(lecture, placement);
backtrack(context, null, resolvedLectures, conflictsToResolve, depth - 1);
resolvedLectures.remove(lecture);
if (cur == null)
assignment.unassign(0, lecture);
else
assignment.assign(0, cur);
for (Iterator<Placement> i = conflicts.iterator(); i.hasNext(); ) {
Placement p = i.next();
assignment.assign(0, p);
conflictsToResolve.remove(p.variable());
}
if (resolvedConf != null)
conflictsToResolve.put(lecture, resolvedConf);
}
}
}
use of org.cpsolver.coursett.model.Placement in project cpsolver by UniTime.
the class MinimizeNumberOfUsedRoomsConstraint method computeConflicts.
@Override
public void computeConflicts(Assignment<Lecture, Placement> assignment, Placement placement, Set<Placement> conflicts) {
MinimizeNumberOfUsedRoomsConstraintContext context = getContext(assignment);
int overLimit = context.getOverLimit(assignment, placement);
if (overLimit > 0) {
List<List<Placement>> adepts = new ArrayList<List<Placement>>();
for (Set<Lecture> lects : context.getUsedRooms().values()) {
List<Placement> placementsToUnassign = new ArrayList<Placement>();
boolean canUnassign = true;
for (Lecture l : lects) {
if (l.isCommitted()) {
canUnassign = false;
break;
}
Placement p = assignment.getValue(l);
if (!conflicts.contains(p))
placementsToUnassign.add(p);
}
if (!canUnassign)
continue;
adepts.add(placementsToUnassign);
}
if (adepts.size() < overLimit) {
conflicts.add(placement);
} else {
Collections.sort(adepts, new Comparator<List<Placement>>() {
@Override
public int compare(List<Placement> c1, List<Placement> c2) {
return Double.compare(c1.size(), c2.size());
}
});
for (int i = 0; i < overLimit; i++) {
conflicts.addAll(adepts.get(i));
}
}
}
}
use of org.cpsolver.coursett.model.Placement in project cpsolver by UniTime.
the class MinimizeNumberOfUsedRoomsConstraint method estimateLimit.
public int estimateLimit() {
HashSet<RoomLocation> mandatoryRooms = new HashSet<RoomLocation>();
for (Lecture lecture : variables()) {
if (lecture.getNrRooms() == 0)
continue;
if (lecture.isCommitted() || lecture.roomLocations().size() == 1)
mandatoryRooms.addAll(lecture.roomLocations());
}
double[][] histogram = new double[iLastDaySlot - iFirstDaySlot + 1][iLastWorkDay - iFirstWorkDay + 1];
for (int i = 0; i < iLastDaySlot - iFirstDaySlot + 1; i++) for (int j = 0; j < iLastWorkDay - iFirstWorkDay + 1; j++) histogram[i][j] = 0.0;
for (Lecture lecture : variables()) {
if (lecture.getNrRooms() == 0)
continue;
List<Placement> values = lecture.values(null);
for (Placement p : lecture.values(null)) {
int firstSlot = p.getTimeLocation().getStartSlot();
if (firstSlot > iLastDaySlot)
continue;
int endSlot = firstSlot + p.getTimeLocation().getNrSlotsPerMeeting() - 1;
if (endSlot < iFirstDaySlot)
continue;
for (int i = Math.max(firstSlot, iFirstDaySlot); i <= Math.min(endSlot, iLastDaySlot); i++) {
int dayCode = p.getTimeLocation().getDayCode();
for (int j = iFirstWorkDay; j <= iLastWorkDay; j++) {
if ((dayCode & Constants.DAY_CODES[j]) != 0) {
histogram[i - iFirstDaySlot][j - iFirstWorkDay] += ((double) lecture.getNrRooms()) / values.size();
}
}
}
}
}
int maxAverageRooms = 0;
for (int i = 0; i < iLastDaySlot - iFirstDaySlot + 1; i++) for (int j = 0; j < iLastWorkDay - iFirstWorkDay + 1; j++) maxAverageRooms = Math.max(maxAverageRooms, (int) Math.ceil(histogram[i][j]));
return Math.max(1, Math.max(mandatoryRooms.size(), maxAverageRooms));
}
use of org.cpsolver.coursett.model.Placement in project cpsolver by UniTime.
the class RoomConstraint method inConflict.
@Override
public boolean inConflict(Assignment<Lecture, Placement> assignment, Placement placement) {
if (!getConstraint())
return false;
if (!placement.hasRoomLocation(getResourceId()))
return false;
Lecture lecture = placement.variable();
Placement current = assignment.getValue(lecture);
int size = lecture.maxRoomUse();
HashSet<Placement> skipPlacements = null;
BitSet weekCode = placement.getTimeLocation().getWeekCode();
RoomConstraintContext context = getContext(assignment);
for (Enumeration<Integer> e = placement.getTimeLocation().getSlots(); e.hasMoreElements(); ) {
int slot = e.nextElement();
for (Placement confPlacement : context.getPlacements(slot)) {
if (!confPlacement.getTimeLocation().shareWeeks(weekCode))
continue;
if (confPlacement.equals(current))
continue;
Lecture confLecture = confPlacement.variable();
if (skipPlacements != null && skipPlacements.contains(confPlacement))
continue;
if (confPlacement.canShareRooms(placement) && confLecture.maxRoomUse() + size <= getCapacity()) {
size += confLecture.maxRoomUse();
if (skipPlacements == null)
skipPlacements = new HashSet<Placement>();
skipPlacements.add(confPlacement);
continue;
}
return true;
}
}
return false;
}
Aggregations