Search in sources :

Example 61 with Lecture

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);
    }
}
Also used : Lecture(org.cpsolver.coursett.model.Lecture) Placement(org.cpsolver.coursett.model.Placement) WeakeningConstraint(org.cpsolver.ifs.model.WeakeningConstraint) WeakeningConstraint(org.cpsolver.ifs.model.WeakeningConstraint) Constraint(org.cpsolver.ifs.model.Constraint) GlobalConstraint(org.cpsolver.ifs.model.GlobalConstraint)

Example 62 with Lecture

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;
}
Also used : Lecture(org.cpsolver.coursett.model.Lecture) Placement(org.cpsolver.coursett.model.Placement)

Example 63 with Lecture

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;
}
Also used : Lecture(org.cpsolver.coursett.model.Lecture) Student(org.cpsolver.coursett.model.Student) InstructorConstraint(org.cpsolver.coursett.constraint.InstructorConstraint) InstructorConstraint(org.cpsolver.coursett.constraint.InstructorConstraint)

Example 64 with Lecture

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;
}
Also used : Lecture(org.cpsolver.coursett.model.Lecture) HashMap(java.util.HashMap) Student(org.cpsolver.coursett.model.Student) InstructorConstraint(org.cpsolver.coursett.constraint.InstructorConstraint) InstructorConstraint(org.cpsolver.coursett.constraint.InstructorConstraint) Placement(org.cpsolver.coursett.model.Placement)

Example 65 with Lecture

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;
}
Also used : Lecture(org.cpsolver.coursett.model.Lecture) Placement(org.cpsolver.coursett.model.Placement) RoomLocation(org.cpsolver.coursett.model.RoomLocation) SimpleNeighbour(org.cpsolver.ifs.model.SimpleNeighbour) TimetableModel(org.cpsolver.coursett.model.TimetableModel)

Aggregations

Lecture (org.cpsolver.coursett.model.Lecture)96 Placement (org.cpsolver.coursett.model.Placement)55 HashSet (java.util.HashSet)35 TimetableModel (org.cpsolver.coursett.model.TimetableModel)17 WeakeningConstraint (org.cpsolver.ifs.model.WeakeningConstraint)17 HashMap (java.util.HashMap)16 ArrayList (java.util.ArrayList)14 TimeLocation (org.cpsolver.coursett.model.TimeLocation)14 Constraint (org.cpsolver.ifs.model.Constraint)14 InstructorConstraint (org.cpsolver.coursett.constraint.InstructorConstraint)13 Student (org.cpsolver.coursett.model.Student)13 BitSet (java.util.BitSet)11 JenrlConstraint (org.cpsolver.coursett.constraint.JenrlConstraint)10 GlobalConstraint (org.cpsolver.ifs.model.GlobalConstraint)9 RoomLocation (org.cpsolver.coursett.model.RoomLocation)8 Set (java.util.Set)7 TreeSet (java.util.TreeSet)7 GroupConstraint (org.cpsolver.coursett.constraint.GroupConstraint)7 StudentGroup (org.cpsolver.coursett.model.StudentGroup)7 RoomConstraint (org.cpsolver.coursett.constraint.RoomConstraint)6