Search in sources :

Example 56 with Placement

use of org.cpsolver.coursett.model.Placement in project cpsolver by UniTime.

the class InstructorConstraint method getPreferenceCombination.

public int getPreferenceCombination(Assignment<Lecture, Placement> assignment, Placement value) {
    Lecture lecture = value.variable();
    Placement placement = value;
    int pref = 0;
    HashSet<Placement> checked = new HashSet<Placement>();
    InstructorConstraintContext context = getContext(assignment);
    for (Enumeration<Integer> e = placement.getTimeLocation().getStartSlots(); e.hasMoreElements(); ) {
        int startSlot = e.nextElement();
        int prevSlot = startSlot - 1;
        if (prevSlot >= 0 && (prevSlot / Constants.SLOTS_PER_DAY) == (startSlot / Constants.SLOTS_PER_DAY)) {
            for (Placement c : context.getPlacements(prevSlot, placement)) {
                if (lecture.equals(c.variable()) || !checked.add(c))
                    continue;
                double dist = Placement.getDistanceInMeters(getDistanceMetric(), placement, c);
                if (dist > getDistanceMetric().getInstructorNoPreferenceLimit() && dist <= getDistanceMetric().getInstructorDiscouragedLimit())
                    pref = Math.max(pref, Constants.sPreferenceLevelDiscouraged);
                if (dist > getDistanceMetric().getInstructorDiscouragedLimit() && (dist <= getDistanceMetric().getInstructorProhibitedLimit() || iIgnoreDistances))
                    pref = Math.max(pref, Constants.sPreferenceLevelStronglyDiscouraged);
                if (!iIgnoreDistances && dist > getDistanceMetric().getInstructorProhibitedLimit())
                    pref = Math.max(pref, Constants.sPreferenceLevelProhibited);
            }
        }
        int nextSlot = startSlot + placement.getTimeLocation().getLength();
        if ((nextSlot / Constants.SLOTS_PER_DAY) == (startSlot / Constants.SLOTS_PER_DAY)) {
            for (Placement c : context.getPlacements(nextSlot, placement)) {
                if (lecture.equals(c.variable()) || !checked.add(c))
                    continue;
                double dist = Placement.getDistanceInMeters(getDistanceMetric(), placement, c);
                if (dist > getDistanceMetric().getInstructorNoPreferenceLimit() && dist <= getDistanceMetric().getInstructorDiscouragedLimit())
                    pref = Math.max(pref, Constants.sPreferenceLevelDiscouraged);
                if (dist > getDistanceMetric().getInstructorDiscouragedLimit() && (dist <= getDistanceMetric().getInstructorProhibitedLimit() || iIgnoreDistances))
                    pref = Math.max(pref, Constants.sPreferenceLevelStronglyDiscouraged);
                if (!iIgnoreDistances && dist > getDistanceMetric().getInstructorProhibitedLimit())
                    pref = Constants.sPreferenceLevelProhibited;
            }
        }
        if (getDistanceMetric().doComputeDistanceConflictsBetweenNonBTBClasses()) {
            TimeLocation t1 = placement.getTimeLocation();
            Placement before = null, after = null;
            for (Lecture other : variables()) {
                Placement otherPlacement = assignment.getValue(other);
                if (otherPlacement == null || other.equals(placement.variable()))
                    continue;
                TimeLocation t2 = otherPlacement.getTimeLocation();
                if (t1 == null || t2 == null || !t1.shareDays(t2) || !t1.shareWeeks(t2))
                    continue;
                if (t1.getStartSlot() + t1.getLength() < t2.getStartSlot()) {
                    int distanceInMinutes = Placement.getDistanceInMinutes(getDistanceMetric(), placement, otherPlacement);
                    if (distanceInMinutes > t1.getBreakTime() + Constants.SLOT_LENGTH_MIN * (t2.getStartSlot() - t1.getStartSlot() - t1.getLength()))
                        pref = Math.max(pref, (iIgnoreDistances ? Constants.sPreferenceLevelStronglyDiscouraged : Constants.sPreferenceLevelProhibited));
                    else if (distanceInMinutes > Constants.SLOT_LENGTH_MIN * (t2.getStartSlot() - t1.getStartSlot() - t1.getLength()))
                        pref = Math.max(pref, Constants.sPreferenceLevelDiscouraged);
                } else if (t2.getStartSlot() + t2.getLength() < t1.getStartSlot()) {
                    int distanceInMinutes = Placement.getDistanceInMinutes(getDistanceMetric(), placement, otherPlacement);
                    if (distanceInMinutes > t2.getBreakTime() + Constants.SLOT_LENGTH_MIN * (t1.getStartSlot() - t2.getStartSlot() - t2.getLength()))
                        pref = Math.max(pref, (iIgnoreDistances ? Constants.sPreferenceLevelStronglyDiscouraged : Constants.sPreferenceLevelProhibited));
                    else if (distanceInMinutes > Constants.SLOT_LENGTH_MIN * (t1.getStartSlot() - t2.getStartSlot() - t2.getLength()))
                        pref = Math.max(pref, Constants.sPreferenceLevelDiscouraged);
                }
                if (t1.getStartSlot() + t1.getLength() <= t2.getStartSlot()) {
                    if (after == null || t2.getStartSlot() < after.getTimeLocation().getStartSlot())
                        after = otherPlacement;
                } else if (t2.getStartSlot() + t2.getLength() <= t1.getStartSlot()) {
                    if (before == null || before.getTimeLocation().getStartSlot() < t2.getStartSlot())
                        before = otherPlacement;
                }
            }
            if (iUnavailabilities != null) {
                for (Placement c : iUnavailabilities) {
                    TimeLocation t2 = c.getTimeLocation();
                    if (t1 == null || t2 == null || !t1.shareDays(t2) || !t1.shareWeeks(t2))
                        continue;
                    if (t1.getStartSlot() + t1.getLength() <= t2.getStartSlot()) {
                        if (after == null || t2.getStartSlot() < after.getTimeLocation().getStartSlot())
                            after = c;
                    } else if (t2.getStartSlot() + t2.getLength() <= t1.getStartSlot()) {
                        if (before == null || before.getTimeLocation().getStartSlot() < t2.getStartSlot())
                            before = c;
                    }
                }
            }
            int tooLongTravel = 0;
            if (before != null && Placement.getDistanceInMinutes(getDistanceMetric(), before, placement) > getDistanceMetric().getInstructorLongTravelInMinutes())
                tooLongTravel++;
            if (after != null && Placement.getDistanceInMinutes(getDistanceMetric(), after, placement) > getDistanceMetric().getInstructorLongTravelInMinutes())
                tooLongTravel++;
            if (tooLongTravel > 0)
                pref += Math.max(pref, Constants.sPreferenceLevelStronglyDiscouraged);
        }
    }
    return pref;
}
Also used : Lecture(org.cpsolver.coursett.model.Lecture) TimeLocation(org.cpsolver.coursett.model.TimeLocation) Placement(org.cpsolver.coursett.model.Placement) HashSet(java.util.HashSet)

Example 57 with Placement

use of org.cpsolver.coursett.model.Placement in project cpsolver by UniTime.

the class BreakFlexibleConstraint method computeConflicts.

@Override
public void computeConflicts(Assignment<Lecture, Placement> assignment, Placement value, Set<Placement> conflicts) {
    if (!isHard())
        return;
    List<BitSet> weeks = getWeeks();
    // checks only placements in the break time
    if (value.getTimeLocation().getStartSlot() <= iBreakEnd && value.getTimeLocation().getStartSlot() + value.getTimeLocation().getLength() > iBreakStart) {
        for (int dayCode : Constants.DAY_CODES) {
            // checks only days affected by the placement
            if ((value.getTimeLocation().getDayCode() & dayCode) != 0) {
                // constraint is checked for every week in semester (or for the whole semester)
                for (BitSet week : weeks) {
                    boolean isProblem = false;
                    do {
                        Set<Placement> adepts = new HashSet<Placement>();
                        // each blocks contains placements which are BTB
                        // placements are BTB if there is less time between them than the minimal break length
                        List<Block> blocks = getBreakBlocks(assignment, dayCode, conflicts, value, null, week);
                        // determine possible conflicts from blocks' placements
                        getAdeptsLunchBreak(blocks, adepts);
                        if (adepts.isEmpty())
                            isProblem = false;
                        // currently assigned value shouldn't be added to conflicts if possible 
                        if (adepts.size() >= 2)
                            adepts.remove(value);
                        // pick random placement
                        Placement conflict = ToolBox.random(adepts);
                        if (conflict != null) {
                            conflicts.add(conflict);
                        }
                    } while (isProblem);
                }
            }
        }
    }
}
Also used : Placement(org.cpsolver.coursett.model.Placement) BitSet(java.util.BitSet) HashSet(java.util.HashSet)

Example 58 with Placement

use of org.cpsolver.coursett.model.Placement in project cpsolver by UniTime.

the class BreakFlexibleConstraint method getAdeptsLunchBreak.

/**
     * Method adds Placements from blocks to adepts if there is a possibility, that the placement caused constraint violation
     * 
     * @param blocks placements in 
     * @param adepts
     */
private void getAdeptsLunchBreak(List<Block> blocks, Set<Placement> adepts) {
    List<Block> matchingBlocks = new ArrayList<Block>();
    for (Block block : blocks) {
        // if block intersects with break interval, it will be used in conflict selection
        if (block.getStartSlotCurrentBlock() <= iBreakEnd && block.getEndSlotCurrentBlock() >= iBreakStart)
            matchingBlocks.add(block);
    }
    int size = matchingBlocks.size();
    // if there is only one block intersecting with break interval, constraint might not be satisfied
    if (size == 1) {
        Block block = matchingBlocks.get(0);
        // check whether the block leaves enough space for break
        if (block.getStartSlotCurrentBlock() - iBreakStart >= iBreakLength || iBreakEnd - block.getEndSlotCurrentBlock() >= iBreakLength) {
            return;
        // if it doesn't
        } else {
            // every placement intersecting with break interval might be potential conflict
            for (Placement p : block.getPlacements()) {
                if (p.getTimeLocation().getStartSlot() <= iBreakEnd && p.getTimeLocation().getStartSlot() + p.getTimeLocation().getLength() >= iBreakStart) {
                    adepts.add(p);
                }
            }
        }
    }
}
Also used : Placement(org.cpsolver.coursett.model.Placement) ArrayList(java.util.ArrayList)

Example 59 with Placement

use of org.cpsolver.coursett.model.Placement in project cpsolver by UniTime.

the class GroupConstraint method forwardCheck.

public boolean forwardCheck(Assignment<Lecture, Placement> assignment, Placement value, Set<GroupConstraint> ignore, int depth) {
    try {
        if (depth < 0)
            return true;
        ignore.add(this);
        int neededSize = value.variable().maxRoomUse();
        for (Lecture lecture : variables()) {
            // 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;
                }
                return false;
            }
            // Look for supporting assignments assignment
            boolean shareRoomAndOverlaps = canShareRoom();
            Placement support = null;
            int nrSupports = 0;
            if (lecture.nrValues() >= iForwardCheckMaxDomainSize) {
                // ignore variables with large domains
                return true;
            }
            List<Placement> values = lecture.values(assignment);
            if (values.isEmpty()) {
                // ignore variables with empty domain
                return true;
            }
            for (Placement other : lecture.values(assignment)) {
                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
                return false;
            }
            // 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, ignore, depth - 1))
                            return false;
                    } else {
                        if (other.inConflict(assignment, support))
                            return false;
                    }
                }
                for (GlobalConstraint<Lecture, Placement> other : getModel().globalConstraints()) {
                    if (other instanceof WeakeningConstraint)
                        continue;
                    if (other.inConflict(assignment, support))
                        return false;
                }
            }
        }
        if (canShareRoom() && neededSize > value.getRoomSize()) {
            // room is too small to fit all meet with classes
            return false;
        }
        return true;
    } 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 60 with Placement

use of org.cpsolver.coursett.model.Placement 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)

Aggregations

Placement (org.cpsolver.coursett.model.Placement)72 Lecture (org.cpsolver.coursett.model.Lecture)55 HashSet (java.util.HashSet)24 TimetableModel (org.cpsolver.coursett.model.TimetableModel)18 TimeLocation (org.cpsolver.coursett.model.TimeLocation)17 WeakeningConstraint (org.cpsolver.ifs.model.WeakeningConstraint)17 ArrayList (java.util.ArrayList)16 BitSet (java.util.BitSet)16 Constraint (org.cpsolver.ifs.model.Constraint)15 HashMap (java.util.HashMap)14 RoomLocation (org.cpsolver.coursett.model.RoomLocation)13 InstructorConstraint (org.cpsolver.coursett.constraint.InstructorConstraint)9 GlobalConstraint (org.cpsolver.ifs.model.GlobalConstraint)9 Student (org.cpsolver.coursett.model.Student)7 List (java.util.List)6 RoomConstraint (org.cpsolver.coursett.constraint.RoomConstraint)6 DataProperties (org.cpsolver.ifs.util.DataProperties)6 GroupConstraint (org.cpsolver.coursett.constraint.GroupConstraint)5 JenrlConstraint (org.cpsolver.coursett.constraint.JenrlConstraint)5 SpreadConstraint (org.cpsolver.coursett.constraint.SpreadConstraint)5