use of org.cpsolver.coursett.model.Lecture in project cpsolver by UniTime.
the class GroupConstraint method forwardCheck.
public void forwardCheck(Assignment<Lecture, Placement> assignment, Placement value, Set<Placement> conflicts, Set<GroupConstraint> ignore, int depth) {
try {
if (depth < 0)
return;
ignore.add(this);
int neededSize = value.variable().maxRoomUse();
for (Lecture lecture : variables()) {
// already conflicting
if (conflicts.contains(value))
break;
// Skip this lecture
if (lecture.equals(value.variable()))
continue;
Placement current = assignment.getValue(lecture);
if (current != null) {
// Has assignment, check whether it is conflicting
if (isSatisfiedPair(assignment, value, current)) {
// Increase needed size if the assignment is of the same room and overlapping in time
if (canShareRoom() && sameRoomAndOverlaps(value, current)) {
neededSize += lecture.maxRoomUse();
}
continue;
}
conflicts.add(current);
}
// Look for supporting assignments assignment
boolean shareRoomAndOverlaps = canShareRoom();
Placement support = null;
int nrSupports = 0;
if (lecture.nrValues() >= iForwardCheckMaxDomainSize) {
// ignore variables with large domains
return;
}
List<Placement> values = lecture.values(assignment);
if (values.isEmpty()) {
// ignore variables with empty domain
return;
}
for (Placement other : values) {
if (nrSupports < 2) {
if (isSatisfiedPair(assignment, value, other)) {
if (support == null)
support = other;
nrSupports++;
if (shareRoomAndOverlaps && !sameRoomAndOverlaps(value, other))
shareRoomAndOverlaps = false;
}
} else if (shareRoomAndOverlaps && !sameRoomAndOverlaps(value, other) && isSatisfiedPair(assignment, value, other)) {
shareRoomAndOverlaps = false;
}
if (nrSupports > 1 && !shareRoomAndOverlaps)
break;
}
// No supporting assignment -> fail
if (nrSupports == 0) {
// other class cannot be assigned with this value
conflicts.add(value);
return;
}
// Increase needed size if all supporters are of the same room and in overlapping times
if (shareRoomAndOverlaps) {
neededSize += lecture.maxRoomUse();
}
// Only one supporter -> propagate the new assignment over other hard constraints of the lecture
if (nrSupports == 1) {
for (Constraint<Lecture, Placement> other : lecture.hardConstraints()) {
if (other instanceof WeakeningConstraint)
continue;
if (other instanceof GroupConstraint) {
GroupConstraint gc = (GroupConstraint) other;
if (depth > 0 && !ignore.contains(gc))
gc.forwardCheck(assignment, support, conflicts, ignore, depth - 1);
} else {
other.computeConflicts(assignment, support, conflicts);
}
}
for (GlobalConstraint<Lecture, Placement> other : getModel().globalConstraints()) {
if (other instanceof WeakeningConstraint)
continue;
other.computeConflicts(assignment, support, conflicts);
}
if (conflicts.contains(support))
conflicts.add(value);
}
}
if (canShareRoom() && neededSize > value.getRoomSize()) {
// room is too small to fit all meet with classes
conflicts.add(value);
}
} finally {
ignore.remove(this);
}
}
use of org.cpsolver.coursett.model.Lecture in project cpsolver by UniTime.
the class GroupConstraint method isChildrenNotOverlap.
public boolean isChildrenNotOverlap(Assignment<Lecture, Placement> assignment, Lecture lec1, Placement plc1, Lecture lec2, Placement plc2) {
if (lec1.getSchedulingSubpartId().equals(lec2.getSchedulingSubpartId())) {
// same subpart
boolean overlap = plc1.getTimeLocation().hasIntersection(plc2.getTimeLocation());
if (overlap && lec1.getParent() != null && variables().contains(lec1.getParent()) && lec2.getParent() != null && variables().contains(lec2.getParent())) {
// children overlaps
Placement p1 = assignment.getValue(lec1.getParent());
Placement p2 = assignment.getValue(lec2.getParent());
// parents not overlap, but children do
if (p1 != null && p2 != null && !p1.getTimeLocation().hasIntersection(p2.getTimeLocation()))
return false;
}
if (!overlap && lec1.getChildrenSubpartIds() != null && lec2.getChildrenSubpartIds() != null) {
// parents not overlap
for (Long subpartId : lec1.getChildrenSubpartIds()) {
for (Lecture c1 : lec1.getChildren(subpartId)) {
Placement p1 = assignment.getValue(c1);
if (p1 == null)
continue;
for (Lecture c2 : lec2.getChildren(subpartId)) {
Placement p2 = assignment.getValue(c2);
if (p2 == null)
continue;
if (!c1.getSchedulingSubpartId().equals(c2.getSchedulingSubpartId()))
continue;
// parents not overlap, but children do
if (p1.getTimeLocation().hasIntersection(p2.getTimeLocation()))
return false;
}
}
}
}
} else {
// different subpart
}
return true;
}
use of org.cpsolver.coursett.model.Lecture in project cpsolver by UniTime.
the class UniversalPerturbationsCounter method getPenalty.
@Override
protected double getPenalty(Assignment<Lecture, Placement> assignment, Placement assignedPlacement, Placement initialPlacement) {
// assigned and initial value of the same lecture
// assigned might be null
Lecture lecture = initialPlacement.variable();
double penalty = 0.0;
if (iDifferentPlacement != 0.0)
penalty += iDifferentPlacement;
if (iAffectedStudentWeight != 0.0)
penalty += iAffectedStudentWeight * lecture.classLimit(assignment);
if (iAffectedInstructorWeight != 0.0)
penalty += iAffectedInstructorWeight * lecture.getInstructorConstraints().size();
if (assignedPlacement != null) {
if ((iDifferentRoomWeight != 0.0 || iAffectedInstructorByRoomWeight != 0.0 || iAffectedStudentByRoomWeight != 0.0)) {
int nrDiff = initialPlacement.nrDifferentRooms(assignedPlacement);
penalty += nrDiff * iDifferentRoomWeight;
penalty += nrDiff * iAffectedInstructorByRoomWeight * lecture.getInstructorConstraints().size();
penalty += nrDiff * iAffectedStudentByRoomWeight * lecture.classLimit(assignment);
}
if ((iDifferentBuildingWeight != 0.0 || iAffectedInstructorByBldgWeight != 0.0 || iAffectedStudentByBldgWeight != 0.0)) {
int nrDiff = initialPlacement.nrDifferentBuildings(assignedPlacement);
penalty += nrDiff * iDifferentBuildingWeight;
penalty += nrDiff * iAffectedInstructorByBldgWeight * lecture.getInstructorConstraints().size();
penalty += nrDiff * iAffectedStudentByBldgWeight * lecture.classLimit(assignment);
}
if ((iDifferentTimeWeight != 0.0 || iAffectedInstructorByTimeWeight != 0.0 || iAffectedStudentByTimeWeight != 0.0) && !initialPlacement.getTimeLocation().equals(assignedPlacement.getTimeLocation())) {
penalty += iDifferentTimeWeight;
penalty += iAffectedInstructorByTimeWeight * lecture.getInstructorConstraints().size();
penalty += iAffectedStudentByTimeWeight * lecture.classLimit(assignment);
}
if (iDifferentDayWeight != 0.0 && initialPlacement.getTimeLocation().getDayCode() != assignedPlacement.getTimeLocation().getDayCode())
penalty += iDifferentDayWeight;
if (iDifferentHourWeight != 0.0 && initialPlacement.getTimeLocation().getStartSlot() != assignedPlacement.getTimeLocation().getStartSlot())
penalty += iDifferentHourWeight;
if ((iTooFarForInstructorsWeight != 0.0 || iTooFarForStudentsWeight != 0.0) && !initialPlacement.getTimeLocation().equals(assignedPlacement.getTimeLocation())) {
double distance = Placement.getDistanceInMeters(iDistanceMetric, initialPlacement, assignedPlacement);
if (!lecture.getInstructorConstraints().isEmpty() && iTooFarForInstructorsWeight != 0.0) {
if (distance > iDistanceMetric.getInstructorNoPreferenceLimit() && distance <= iDistanceMetric.getInstructorDiscouragedLimit()) {
penalty += Constants.sPreferenceLevelDiscouraged * iTooFarForInstructorsWeight * lecture.getInstructorConstraints().size();
} else if (distance > iDistanceMetric.getInstructorDiscouragedLimit() && distance <= iDistanceMetric.getInstructorProhibitedLimit()) {
penalty += Constants.sPreferenceLevelStronglyDiscouraged * iTooFarForInstructorsWeight * lecture.getInstructorConstraints().size();
} else if (distance > iDistanceMetric.getInstructorProhibitedLimit()) {
penalty += Constants.sPreferenceLevelProhibited * iTooFarForInstructorsWeight * lecture.getInstructorConstraints().size();
}
}
if (iTooFarForStudentsWeight != 0.0 && distance > iDistanceMetric.minutes2meters(10))
penalty += iTooFarForStudentsWeight * lecture.classLimit(assignment);
}
if (iDeltaStudentConflictsWeight != 0.0) {
int newStudentConflicts = lecture.countStudentConflicts(assignment, assignedPlacement);
int oldStudentConflicts = lecture.countInitialStudentConflicts();
penalty += iDeltaStudentConflictsWeight * (newStudentConflicts - oldStudentConflicts);
}
if (iNewStudentConflictsWeight != 0.0) {
Set<Student> newStudentConflicts = lecture.conflictStudents(assignment, assignedPlacement);
Set<Student> initialStudentConflicts = lecture.initialStudentConflicts();
for (Iterator<Student> i = newStudentConflicts.iterator(); i.hasNext(); ) if (!initialStudentConflicts.contains(i.next()))
penalty += iNewStudentConflictsWeight;
}
if (iDeltaTimePreferenceWeight != 0.0) {
penalty += iDeltaTimePreferenceWeight * (assignedPlacement.getTimeLocation().getNormalizedPreference() - initialPlacement.getTimeLocation().getNormalizedPreference());
}
if (iDeltaRoomPreferenceWeight != 0.0) {
penalty += iDeltaRoomPreferenceWeight * (assignedPlacement.sumRoomPreference() - initialPlacement.sumRoomPreference());
}
if (iDeltaInstructorDistancePreferenceWeight != 0.0) {
for (InstructorConstraint ic : lecture.getInstructorConstraints()) {
for (Lecture lect : ic.variables()) {
if (lect.equals(lecture))
continue;
int initialPreference = (lect.getInitialAssignment() == null ? Constants.sPreferenceLevelNeutral : ic.getDistancePreference(initialPlacement, lect.getInitialAssignment()));
int assignedPreference = (assignment.getValue(lect) == null ? Constants.sPreferenceLevelNeutral : ic.getDistancePreference(assignedPlacement, assignment.getValue(lect)));
penalty += iDeltaInstructorDistancePreferenceWeight * (assignedPreference - initialPreference);
}
}
}
}
return penalty;
}
use of org.cpsolver.coursett.model.Lecture in project cpsolver by UniTime.
the class UniversalPerturbationsCounter method getCompactInfo.
public Map<String, Double> getCompactInfo(Assignment<Lecture, Placement> assignment, TimetableModel model, Placement assignedPlacement, boolean includeZero, boolean weighted) {
Map<String, Double> info = new HashMap<String, Double>();
if (!iMPP)
return info;
Lecture lecture = assignedPlacement.variable();
Placement initialPlacement = lecture.getInitialAssignment();
if (initialPlacement == null || initialPlacement.equals(assignedPlacement))
return info;
int perts = 1;
long affectedStudents = lecture.classLimit(assignment);
int affectedInstructors = lecture.getInstructorConstraints().size();
long affectedStudentsByTime = (initialPlacement.getTimeLocation().equals(assignedPlacement.getTimeLocation()) ? 0 : lecture.classLimit(assignment));
int affectedInstructorsByTime = (initialPlacement.getTimeLocation().equals(assignedPlacement.getTimeLocation()) ? 0 : lecture.getInstructorConstraints().size());
int differentRoom = initialPlacement.nrDifferentRooms(assignedPlacement);
int affectedInstructorsByRoom = differentRoom * lecture.getInstructorConstraints().size();
long affectedStudentsByRoom = differentRoom * lecture.classLimit(assignment);
int differentBuilding = initialPlacement.nrDifferentBuildings(initialPlacement);
int affectedInstructorsByBldg = differentBuilding * lecture.getInstructorConstraints().size();
long affectedStudentsByBldg = differentBuilding * lecture.classLimit(assignment);
int deltaRoomPreferences = assignedPlacement.sumRoomPreference() - initialPlacement.sumRoomPreference();
int differentTime = (initialPlacement.getTimeLocation().equals(assignedPlacement.getTimeLocation()) ? 0 : 1);
int differentDay = (initialPlacement.getTimeLocation().getDayCode() != assignedPlacement.getTimeLocation().getDayCode() ? 1 : 0);
int differentHour = (initialPlacement.getTimeLocation().getStartSlot() != assignedPlacement.getTimeLocation().getStartSlot() ? 1 : 0);
int tooFarForInstructors = 0;
int tooFarForStudents = 0;
int deltaStudentConflicts = lecture.countStudentConflicts(assignment, assignedPlacement) - lecture.countInitialStudentConflicts();
int newStudentConflicts = 0;
double deltaTimePreferences = (assignedPlacement.getTimeLocation().getNormalizedPreference() - initialPlacement.getTimeLocation().getNormalizedPreference());
int deltaInstructorDistancePreferences = 0;
double distance = Placement.getDistanceInMeters(iDistanceMetric, initialPlacement, assignedPlacement);
if (!lecture.getInstructorConstraints().isEmpty()) {
if (distance > iDistanceMetric.getInstructorNoPreferenceLimit() && distance <= iDistanceMetric.getInstructorDiscouragedLimit()) {
tooFarForInstructors += lecture.getInstructorConstraints().size();
} else if (distance > iDistanceMetric.getInstructorDiscouragedLimit() && distance <= iDistanceMetric.getInstructorProhibitedLimit()) {
tooFarForInstructors += 2 * lecture.getInstructorConstraints().size();
} else if (distance > iDistanceMetric.getInstructorProhibitedLimit()) {
tooFarForInstructors += 10 * lecture.getInstructorConstraints().size();
}
}
if (distance > iDistanceMetric.minutes2meters(10))
tooFarForStudents = lecture.classLimit(assignment);
Set<Student> newStudentConflictsVect = lecture.conflictStudents(assignment, assignedPlacement);
Set<Student> initialStudentConflicts = lecture.initialStudentConflicts();
for (Iterator<Student> e = newStudentConflictsVect.iterator(); e.hasNext(); ) if (!initialStudentConflicts.contains(e.next()))
newStudentConflicts++;
for (InstructorConstraint ic : lecture.getInstructorConstraints()) {
for (Lecture lect : ic.variables()) {
if (lect.equals(lecture))
continue;
int initialPreference = (lect.getInitialAssignment() == null ? Constants.sPreferenceLevelNeutral : ic.getDistancePreference(initialPlacement, lect.getInitialAssignment()));
int assignedPreference = (assignment.getValue(lect) == null ? Constants.sPreferenceLevelNeutral : ic.getDistancePreference(assignedPlacement, assignment.getValue(lect)));
deltaInstructorDistancePreferences += (assignedPreference - initialPreference);
}
}
if (includeZero || iDifferentPlacement != 0.0)
info.put("Different placement", new Double(weighted ? iDifferentPlacement * perts : perts));
if (includeZero || iAffectedStudentWeight != 0.0)
info.put("Affected students", new Double(weighted ? iAffectedStudentWeight * affectedStudents : affectedStudents));
if (includeZero || iAffectedInstructorWeight != 0.0)
info.put("Affected instructors", new Double(weighted ? iAffectedInstructorWeight * affectedInstructors : affectedInstructors));
if (includeZero || iAffectedStudentByTimeWeight != 0.0)
info.put("Affected students [time]", new Double(weighted ? iAffectedStudentByTimeWeight * affectedStudentsByTime : affectedStudentsByTime));
if (includeZero || iAffectedInstructorByTimeWeight != 0.0)
info.put("Affected instructors [time]", new Double(weighted ? iAffectedInstructorByTimeWeight * affectedInstructorsByTime : affectedInstructorsByTime));
if (includeZero || iAffectedStudentByRoomWeight != 0.0)
info.put("Affected students [room]", new Double(weighted ? iAffectedStudentByRoomWeight * affectedStudentsByRoom : affectedStudentsByRoom));
if (includeZero || iAffectedInstructorByRoomWeight != 0.0)
info.put("Affected instructors [room]", new Double(weighted ? iAffectedInstructorByRoomWeight * affectedInstructorsByRoom : affectedInstructorsByRoom));
if (includeZero || iAffectedStudentByBldgWeight != 0.0)
info.put("Affected students [bldg]", new Double(weighted ? iAffectedStudentByBldgWeight * affectedStudentsByBldg : affectedStudentsByBldg));
if (includeZero || iAffectedInstructorByBldgWeight != 0.0)
info.put("Affected instructors [bldg]", new Double(weighted ? iAffectedInstructorByBldgWeight * affectedInstructorsByBldg : affectedInstructorsByBldg));
if (includeZero || iDifferentRoomWeight != 0.0)
info.put("Different room", new Double(weighted ? iDifferentRoomWeight * differentRoom : differentRoom));
if (includeZero || iDifferentBuildingWeight != 0.0)
info.put("Different building", new Double(weighted ? iDifferentBuildingWeight * differentBuilding : differentBuilding));
if (includeZero || iDifferentTimeWeight != 0.0)
info.put("Different time", new Double(weighted ? iDifferentTimeWeight * differentTime : differentTime));
if (includeZero || iDifferentDayWeight != 0.0)
info.put("Different day", new Double(weighted ? iDifferentDayWeight * differentDay : differentDay));
if (includeZero || iDifferentHourWeight != 0.0)
info.put("Different hour", new Double(weighted ? iDifferentHourWeight * differentHour : differentHour));
if (includeZero || iTooFarForInstructorsWeight != 0.0)
info.put("New placement too far for initial [instructors]", new Double(weighted ? iTooFarForInstructorsWeight * tooFarForInstructors : tooFarForInstructors));
if (includeZero || iTooFarForStudentsWeight != 0.0)
info.put("New placement too far for initial [students]", new Double(weighted ? iTooFarForStudentsWeight * tooFarForStudents : tooFarForStudents));
if (includeZero || iDeltaStudentConflictsWeight != 0.0)
info.put("Delta student conflicts", new Double(weighted ? iDeltaStudentConflictsWeight * deltaStudentConflicts : deltaStudentConflicts));
if (includeZero || iNewStudentConflictsWeight != 0.0)
info.put("New student conflicts", new Double(weighted ? iNewStudentConflictsWeight * newStudentConflicts : newStudentConflicts));
if (includeZero || iDeltaTimePreferenceWeight != 0.0)
info.put("Delta time preferences", new Double(weighted ? iDeltaTimePreferenceWeight * deltaTimePreferences : deltaTimePreferences));
if (includeZero || iDeltaRoomPreferenceWeight != 0.0)
info.put("Delta room preferences", new Double(weighted ? iDeltaRoomPreferenceWeight * deltaRoomPreferences : deltaRoomPreferences));
if (includeZero || iDeltaInstructorDistancePreferenceWeight != 0.0)
info.put("Delta instructor distance preferences", new Double(weighted ? iDeltaInstructorDistancePreferenceWeight * deltaInstructorDistancePreferences : deltaInstructorDistancePreferences));
return info;
}
use of org.cpsolver.coursett.model.Lecture in project cpsolver by UniTime.
the class RoomChange method selectNeighbour.
@Override
public Neighbour<Lecture, Placement> selectNeighbour(Solution<Lecture, Placement> solution) {
TimetableModel model = (TimetableModel) solution.getModel();
Assignment<Lecture, Placement> assignment = solution.getAssignment();
int varIdx = ToolBox.random(model.variables().size());
for (int i = 0; i < model.variables().size(); i++) {
Lecture lecture = model.variables().get((i + varIdx) % model.variables().size());
Placement old = assignment.getValue(lecture);
if (old == null || old.getNrRooms() != 1)
continue;
List<RoomLocation> values = lecture.roomLocations();
if (values.isEmpty())
continue;
int valIdx = ToolBox.random(values.size());
for (int j = 0; j < values.size(); j++) {
RoomLocation room = values.get((j + valIdx) % values.size());
if (room.getPreference() > 50)
continue;
if (room.equals(old.getRoomLocation()))
continue;
Placement placement = new Placement(lecture, old.getTimeLocation(), room);
if (placement.isValid() && !model.inConflict(assignment, placement)) {
SimpleNeighbour<Lecture, Placement> n = new SimpleNeighbour<Lecture, Placement>(lecture, placement);
if (!iHC || n.value(assignment) <= 0)
return n;
}
}
}
return null;
}
Aggregations