use of org.cpsolver.coursett.model.Placement in project cpsolver by UniTime.
the class GroupConstraint method isSatisfiedSeqCheck.
private boolean isSatisfiedSeqCheck(Assignment<Lecture, Placement> assignment, HashMap<Lecture, Placement> assignments, Set<Placement> conflicts) {
if (!getType().is(Flag.BACK_TO_BACK))
return true;
int gapMin = getType().getMin();
int gapMax = getType().getMax();
List<Integer> lengths = new ArrayList<Integer>();
Placement[] res = new Placement[Constants.SLOTS_PER_DAY];
for (int i = 0; i < Constants.SLOTS_PER_DAY; i++) res[i] = null;
int nrLectures = 0;
for (Lecture lecture : variables()) {
Placement placement = null;
if (assignments != null && assignments.containsKey(lecture))
placement = assignments.get(lecture);
else if (assignment != null)
placement = assignment.getValue(lecture);
if (placement == null) {
if (!lecture.timeLocations().isEmpty())
lengths.add(lecture.timeLocations().get(0).getLength());
} else if (conflicts != null && conflicts.contains(placement)) {
if (!lecture.timeLocations().isEmpty())
lengths.add(lecture.timeLocations().get(0).getLength());
} else {
int pos = placement.getTimeLocation().getStartSlot();
int length = placement.getTimeLocation().getLength();
for (int j = pos; j < pos + length; j++) {
if (res[j] != null) {
if (conflicts == null)
return false;
if (!assignments.containsKey(lecture))
conflicts.add(placement);
else if (!assignments.containsKey(res[j].variable()))
conflicts.add(res[j]);
}
}
for (int j = pos; j < pos + length; j++) res[j] = placement;
nrLectures++;
}
}
if (nrLectures <= 1)
return true;
if (iIsRequired || (!iIsProhibited && iPreference < 0)) {
int i = 0;
Placement p = res[i];
while (p == null) p = res[++i];
i = res[i].getTimeLocation().getStartSlot() + res[i].getTimeLocation().getLength();
nrLectures--;
while (nrLectures > 0) {
int gap = 0;
while (i < Constants.SLOTS_PER_DAY && res[i] == null) {
gap++;
i++;
}
if (i == Constants.SLOTS_PER_DAY)
break;
if (!canFill(gap, gapMin, gapMax, lengths))
return false;
p = res[i];
i = res[i].getTimeLocation().getStartSlot() + res[i].getTimeLocation().getLength();
nrLectures--;
}
} else if (iIsProhibited || (!iIsRequired && iPreference > 0)) {
int i = 0;
Placement p = res[i];
while (p == null) p = res[++i];
i = res[i].getTimeLocation().getStartSlot() + res[i].getTimeLocation().getLength();
nrLectures--;
while (nrLectures > 0) {
int gap = 0;
while (i < Constants.SLOTS_PER_DAY && res[i] == null) {
gap++;
i++;
}
if (i == Constants.SLOTS_PER_DAY)
break;
if ((gapMin == 0 || !canFill(gap, 0, gapMin - 1, lengths)) && (gapMax >= Constants.SLOTS_PER_DAY || !canFill(gap, gapMax + 1, Constants.SLOTS_PER_DAY, lengths))) {
return false;
}
p = res[i];
i = res[i].getTimeLocation().getStartSlot() + res[i].getTimeLocation().getLength();
nrLectures--;
}
}
return true;
}
use of org.cpsolver.coursett.model.Placement in project cpsolver by UniTime.
the class GroupConstraint method getCurrentPreference.
/** Current constraint preference change (if given placement is assigned)
* @param assignment current assignment
* @param placement placement that is being considered
* @return change in the current preference, if assigned
**/
public int getCurrentPreference(Assignment<Lecture, Placement> assignment, Placement placement) {
// no preference
if (isHard())
return 0;
// not enough variable
if (countAssignedVariables(assignment) + (assignment.getValue(placement.variable()) == null ? 1 : 0) < 2)
return 0;
if (getType().is(Flag.MAX_HRS_DAY)) {
HashMap<Lecture, Placement> assignments = new HashMap<Lecture, Placement>();
assignments.put(placement.variable(), placement);
HashMap<Lecture, Placement> unassignments = new HashMap<Lecture, Placement>();
unassignments.put(placement.variable(), null);
int after = 0;
int before = 0;
for (int dayCode : Constants.DAY_CODES) {
if (iMaxNHoursADayConsiderDatePatterns) {
for (BitSet week : ((TimetableModel) getModel()).getWeeks()) {
after += Math.max(0, nrSlotsADay(assignment, dayCode, week, assignments, null) - getType().getMax());
before += Math.max(0, nrSlotsADay(assignment, dayCode, week, unassignments, null) - getType().getMax());
}
} else {
after += Math.max(0, nrSlotsADay(assignment, dayCode, null, assignments, null) - getType().getMax());
before += Math.max(0, nrSlotsADay(assignment, dayCode, null, unassignments, null) - getType().getMax());
}
}
return (after > 0 ? Math.abs(iPreference) * after / 12 : -Math.abs(iPreference)) - (before > 0 ? Math.abs(iPreference) * before / 12 : -Math.abs(iPreference));
}
int nrViolatedPairsAfter = 0;
int nrViolatedPairsBefore = 0;
for (Lecture v1 : variables()) {
for (Lecture v2 : variables()) {
if (v1.getId() >= v2.getId())
continue;
Placement p1 = (v1.equals(placement.variable()) ? null : assignment.getValue(v1));
Placement p2 = (v2.equals(placement.variable()) ? null : assignment.getValue(v2));
if (p1 != null && p2 != null && !isSatisfiedPair(assignment, p1, p2))
nrViolatedPairsBefore++;
if (v1.equals(placement.variable()))
p1 = placement;
if (v2.equals(placement.variable()))
p2 = placement;
if (p1 != null && p2 != null && !isSatisfiedPair(assignment, p1, p2))
nrViolatedPairsAfter++;
}
}
if (getType().is(Flag.BACK_TO_BACK)) {
HashMap<Lecture, Placement> assignments = new HashMap<Lecture, Placement>();
assignments.put(placement.variable(), placement);
Set<Placement> conflicts = new HashSet<Placement>();
if (isSatisfiedSeq(assignment, assignments, conflicts))
nrViolatedPairsAfter += conflicts.size();
else
nrViolatedPairsAfter = variables().size();
HashMap<Lecture, Placement> unassignments = new HashMap<Lecture, Placement>();
unassignments.put(placement.variable(), null);
Set<Placement> previous = new HashSet<Placement>();
if (isSatisfiedSeq(assignment, unassignments, previous))
nrViolatedPairsBefore += previous.size();
else
nrViolatedPairsBefore = variables().size();
}
return (nrViolatedPairsAfter > 0 ? Math.abs(iPreference) * nrViolatedPairsAfter : -Math.abs(iPreference)) - (nrViolatedPairsBefore > 0 ? Math.abs(iPreference) * nrViolatedPairsBefore : -Math.abs(iPreference));
}
use of org.cpsolver.coursett.model.Placement in project cpsolver by UniTime.
the class GroupConstraint method isSatisfiedRecursive.
private Set<Placement> isSatisfiedRecursive(Assignment<Lecture, Placement> assignment, int idx, HashMap<Lecture, Placement> assignments, Set<Placement> conflicts, Set<Placement> newConflicts, Set<Placement> bestConflicts) {
if (idx == variables().size() && newConflicts.isEmpty())
return bestConflicts;
if (isSatisfiedSeqCheck(assignment, assignments, conflicts)) {
if (bestConflicts == null) {
return new HashSet<Placement>(newConflicts);
} else {
int b = 0, n = 0;
for (Placement value : assignments.values()) {
if (value != null && bestConflicts.contains(value))
b++;
if (value != null && newConflicts.contains(value))
n++;
}
if (n < b || (n == b && newConflicts.size() < bestConflicts.size()))
return new HashSet<Placement>(newConflicts);
}
return bestConflicts;
}
if (idx == variables().size())
return bestConflicts;
bestConflicts = isSatisfiedRecursive(assignment, idx + 1, assignments, conflicts, newConflicts, bestConflicts);
Lecture lecture = variables().get(idx);
//if (assignments != null && assignments.containsKey(lecture))
// return bestConflicts;
Placement placement = null;
if (assignments != null && assignments.containsKey(lecture))
placement = assignments.get(lecture);
else if (assignment != null)
placement = assignment.getValue(lecture);
if (placement == null)
return bestConflicts;
if (conflicts != null && conflicts.contains(placement))
return bestConflicts;
conflicts.add(placement);
newConflicts.add(placement);
bestConflicts = isSatisfiedRecursive(assignment, idx + 1, assignments, conflicts, newConflicts, bestConflicts);
newConflicts.remove(placement);
conflicts.remove(placement);
return bestConflicts;
}
use of org.cpsolver.coursett.model.Placement in project cpsolver by UniTime.
the class GroupConstraint method isConsistent.
@Override
public boolean isConsistent(Placement value1, Placement value2) {
if (!isHard())
return true;
if (!isSatisfiedPair(null, value1, value2))
return false;
if (getType().is(Flag.BACK_TO_BACK)) {
HashMap<Lecture, Placement> assignments = new HashMap<Lecture, Placement>();
assignments.put(value1.variable(), value1);
assignments.put(value2.variable(), value2);
if (!isSatisfiedSeq(null, assignments, null))
return false;
}
if (getType().is(Flag.MAX_HRS_DAY)) {
HashMap<Lecture, Placement> assignments = new HashMap<Lecture, Placement>();
assignments.put(value1.variable(), value1);
assignments.put(value2.variable(), value2);
for (int dayCode : Constants.DAY_CODES) {
if (iMaxNHoursADayConsiderDatePatterns) {
for (BitSet week : ((TimetableModel) getModel()).getWeeks()) {
if (!value1.getTimeLocation().shareWeeks(week) && !value2.getTimeLocation().shareWeeks(week))
continue;
if (nrSlotsADay(null, dayCode, week, assignments, null) > getType().getMax())
return false;
}
} else {
if (nrSlotsADay(null, dayCode, null, assignments, null) > getType().getMax())
return false;
}
}
}
return true;
}
use of org.cpsolver.coursett.model.Placement in project cpsolver by UniTime.
the class GroupConstraint method inConflict.
@Override
public boolean inConflict(Assignment<Lecture, Placement> assignment, Placement value) {
if (!isHard())
return false;
for (Lecture v : variables()) {
if (v.equals(value.variable()))
// ignore this variable
continue;
Placement p = assignment.getValue(v);
if (p == null)
// there is an unassigned variable -- great, still a chance to get violated
continue;
if (!isSatisfiedPair(assignment, p, value))
return true;
}
if (getType().is(Flag.BACK_TO_BACK)) {
HashMap<Lecture, Placement> assignments = new HashMap<Lecture, Placement>();
assignments.put(value.variable(), value);
if (!isSatisfiedSeq(assignment, assignments, null))
return true;
}
if (getType().is(Flag.MAX_HRS_DAY)) {
HashMap<Lecture, Placement> assignments = new HashMap<Lecture, Placement>();
assignments.put(value.variable(), value);
for (int dayCode : Constants.DAY_CODES) {
if (iMaxNHoursADayConsiderDatePatterns) {
for (BitSet week : ((TimetableModel) getModel()).getWeeks()) {
if (!value.getTimeLocation().shareWeeks(week))
continue;
if (nrSlotsADay(assignment, dayCode, week, assignments, null) > getType().getMax())
return true;
}
} else {
if (nrSlotsADay(assignment, dayCode, null, assignments, null) > getType().getMax())
return true;
}
}
}
if (!forwardCheck(assignment, value, new HashSet<GroupConstraint>(), iForwardCheckMaxDepth - 1))
return true;
return false;
}
Aggregations