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;
}
use of org.cpsolver.coursett.model.Placement in project cpsolver by UniTime.
the class TimetableSolver method fixCompleteSolution.
/**
* Try to improve existing solution by backtracking search of very limited
* depth. See {@link NeighbourSelectionWithSuggestions} for more details.
* @param solution current solution
* @param startTime start time
*/
protected void fixCompleteSolution(Solution<Lecture, Placement> solution, double startTime) {
Progress progress = Progress.getInstance(solution.getModel());
TimetableModel model = (TimetableModel) solution.getModel();
Assignment<Lecture, Placement> assignment = solution.getAssignment();
solution.saveBest();
progress.save();
double solutionValue = 0.0, newSolutionValue = model.getTotalValue(assignment);
do {
solutionValue = newSolutionValue;
progress.setPhase("Fixing solution", model.variables().size());
for (Lecture variable : model.variables()) {
Placement bestValue = null;
double bestVal = 0.0;
Placement currentValue = assignment.getValue(variable);
if (currentValue == null)
continue;
double currentVal = currentValue.toDouble(assignment);
for (Placement value : variable.values()) {
if (value.equals(currentValue))
continue;
if (model.conflictValues(assignment, value).isEmpty()) {
double val = value.toDouble(assignment);
if (bestValue == null || val < bestVal) {
bestValue = value;
bestVal = val;
}
}
}
if (bestValue != null && bestVal < currentVal)
assignment.assign(0, bestValue);
solution.update(JProf.currentTimeSec() - startTime);
progress.incProgress();
if (iStop)
break;
}
newSolutionValue = model.getTotalValue(assignment);
if (newSolutionValue < solutionValue) {
progress.debug("New solution value is " + newSolutionValue);
}
} while (!iStop && newSolutionValue < solutionValue && getTerminationCondition().canContinue(solution));
progress.restore();
if (!solution.getModel().unassignedVariables(assignment).isEmpty())
return;
progress.save();
try {
progress.setPhase("Fixing solution [2]", model.variables().size());
NeighbourSelectionWithSuggestions ns = new NeighbourSelectionWithSuggestions(this);
for (Lecture lecture : model.variables()) {
Neighbour<Lecture, Placement> n = ns.selectNeighbourWithSuggestions(solution, lecture, 2);
if (n != null && n.value(assignment) <= 0.0)
n.assign(assignment, 0);
solution.update(JProf.currentTimeSec() - startTime);
progress.incProgress();
if (iStop)
break;
}
} catch (Exception e) {
sLogger.debug(e.getMessage(), e);
} finally {
progress.restore();
}
}
Aggregations