@Override public void unassigned(long iteration, ExamPlacement value) { super.unassigned(iteration, value); if (!isHard() && iIsSatisfied != isSatisfied()) { iIsSatisfied = !iIsSatisfied; ((ExamModel) value.variable().getModel()) .addDistributionPenalty(iIsSatisfied ? -getWeight() : getWeight()); } }
/** * Compute conflicts -- there is a conflict if the other variable is assigned and {@link * ExamDistributionConstraint#check(ExamPlacement, ExamPlacement)} is false */ @Override public void computeConflicts(ExamPlacement givenPlacement, Set<ExamPlacement> conflicts) { boolean before = true; for (Exam exam : variables()) { if (exam.equals(givenPlacement.variable())) { before = false; continue; } ExamPlacement placement = exam.getAssignment(); if (placement == null) continue; if (!check(before ? placement : givenPlacement, before ? givenPlacement : placement)) conflicts.add(placement); } }
/** * Check for conflict -- there is a conflict if the other variable is assigned and {@link * ExamDistributionConstraint#check(ExamPlacement, ExamPlacement)} is false */ @Override public boolean inConflict(ExamPlacement givenPlacement) { boolean before = true; for (Exam exam : variables()) { if (exam.equals(givenPlacement.variable())) { before = false; continue; } ExamPlacement placement = exam.getAssignment(); if (placement == null) continue; if (!check(before ? placement : givenPlacement, before ? givenPlacement : placement)) return true; } return false; }
/** * Return true if this is hard constraint or this is a soft constraint without any violation * * @param p exam assignment to be made */ public boolean isSatisfied(ExamPlacement p) { if (isHard()) return true; switch (getType()) { case sDistPrecedence: ExamPeriod last = null; for (Exam exam : variables()) { ExamPlacement placement = (p != null && exam.equals(p.variable()) ? p : exam.getAssignment()); if (placement == null) continue; if (last == null || last.getIndex() < placement.getPeriod().getIndex()) last = placement.getPeriod(); else return false; } return true; case sDistPrecedenceRev: last = null; for (Exam exam : variables()) { ExamPlacement placement = (p != null && exam.equals(p.variable()) ? p : exam.getAssignment()); if (placement == null) continue; if (last == null || last.getIndex() > placement.getPeriod().getIndex()) last = placement.getPeriod(); else return false; } return true; case sDistSamePeriod: ExamPeriod period = null; for (Exam exam : variables()) { ExamPlacement placement = (p != null && exam.equals(p.variable()) ? p : exam.getAssignment()); if (placement == null) continue; if (period == null) period = placement.getPeriod(); else if (period.getIndex() != placement.getPeriod().getIndex()) return false; } return true; case sDistDifferentPeriod: HashSet<ExamPeriod> periods = new HashSet<ExamPeriod>(); for (Exam exam : variables()) { ExamPlacement placement = (p != null && exam.equals(p.variable()) ? p : exam.getAssignment()); if (placement == null) continue; if (!periods.add(placement.getPeriod())) return false; } return true; case sDistSameRoom: Set<ExamRoomPlacement> rooms = null; for (Exam exam : variables()) { ExamPlacement placement = (p != null && exam.equals(p.variable()) ? p : exam.getAssignment()); if (placement == null) continue; if (rooms == null) rooms = placement.getRoomPlacements(); else if (!rooms.containsAll(placement.getRoomPlacements()) || !placement.getRoomPlacements().containsAll(rooms)) return false; } return true; case sDistDifferentRoom: HashSet<ExamRoomPlacement> allRooms = new HashSet<ExamRoomPlacement>(); for (Exam exam : variables()) { ExamPlacement placement = (p != null && exam.equals(p.variable()) ? p : exam.getAssignment()); if (placement == null) continue; for (ExamRoomPlacement room : placement.getRoomPlacements()) { if (!allRooms.add(room)) return false; } } return true; default: return false; } }
/** * Check assignments of the given exams * * @param first assignment of the first exam * @param second assignment of the second exam * @return true, if the constraint is satisfied */ public boolean check(ExamPlacement first, ExamPlacement second) { switch (getType()) { case sDistPrecedence: return first.getPeriod().getIndex() < second.getPeriod().getIndex(); case sDistPrecedenceRev: return first.getPeriod().getIndex() > second.getPeriod().getIndex(); case sDistSamePeriod: return first.getPeriod().getIndex() == second.getPeriod().getIndex(); case sDistDifferentPeriod: return first.getPeriod().getIndex() != second.getPeriod().getIndex(); case sDistSameRoom: return first.getRoomPlacements().containsAll(second.getRoomPlacements()) || second.getRoomPlacements().containsAll(first.getRoomPlacements()); case sDistDifferentRoom: for (Iterator<ExamRoomPlacement> i = first.getRoomPlacements().iterator(); i.hasNext(); ) if (second.getRoomPlacements().contains(i.next())) return false; return true; default: return false; } }
/** * Consistency check -- {@link ExamDistributionConstraint#check(ExamPlacement, ExamPlacement)} is * called */ @Override public boolean isConsistent(ExamPlacement first, ExamPlacement second) { boolean before = (variables().indexOf(first.variable()) < variables().indexOf(second.variable())); return check(before ? first : second, before ? second : first); }