use of org.cpsolver.coursett.model.TimetableModel in project cpsolver by UniTime.
the class RoomSwap method selectNeighbour.
@Override
public Neighbour<Lecture, Placement> selectNeighbour(Solution<Lecture, Placement> solution) {
TimetableModel model = (TimetableModel) solution.getModel();
Assignment<Lecture, Placement> assignment = solution.getAssignment();
double total = model.getTotalValue(assignment);
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;
Lock lock = solution.getLock().writeLock();
lock.lock();
try {
int attempts = 0;
int valIdx = ToolBox.random(values.size());
long startTime = JProf.currentTimeMillis();
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())
continue;
Set<Placement> conflicts = model.conflictValues(assignment, placement);
if (conflicts.contains(placement))
continue;
if (conflicts.isEmpty()) {
SimpleNeighbour<Lecture, Placement> n = new SimpleNeighbour<Lecture, Placement>(lecture, placement);
if (!iHC || n.value(assignment) <= 0)
return n;
else
continue;
}
Map<Lecture, Placement> assignments = new HashMap<Lecture, Placement>();
assignments.put(lecture, placement);
for (Placement conflict : conflicts) assignment.unassign(solution.getIteration(), conflict.variable());
assignment.assign(solution.getIteration(), placement);
Double v = resolve(solution, total, startTime, assignments, new ArrayList<Placement>(conflicts), 0);
if (!conflicts.isEmpty())
attempts++;
assignment.unassign(solution.getIteration(), lecture);
for (Placement conflict : conflicts) assignment.assign(solution.getIteration(), conflict);
assignment.assign(solution.getIteration(), old);
if (v != null)
return new SwapNeighbour(assignments.values(), v);
if (attempts >= iMaxAttempts)
break;
}
} finally {
lock.unlock();
}
}
return null;
}
use of org.cpsolver.coursett.model.TimetableModel in project cpsolver by UniTime.
the class TimeSwap method selectNeighbour.
@Override
public Neighbour<Lecture, Placement> selectNeighbour(Solution<Lecture, Placement> solution) {
TimetableModel model = (TimetableModel) solution.getModel();
Assignment<Lecture, Placement> assignment = solution.getAssignment();
double total = model.getTotalValue(assignment);
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 = lecture.getAssignment(assignment);
if (old == null)
continue;
List<TimeLocation> values = lecture.timeLocations();
if (values.isEmpty())
continue;
Lock lock = solution.getLock().writeLock();
lock.lock();
try {
int attempts = 0;
long startTime = JProf.currentTimeMillis();
int valIdx = ToolBox.random(values.size());
for (int j = 0; j < values.size(); j++) {
TimeLocation time = values.get((j + valIdx) % values.size());
if (time.getPreference() > 50)
continue;
if (time.equals(old.getTimeLocation()))
continue;
Placement placement = null;
if (lecture.getNrRooms() == 0)
placement = new Placement(lecture, time, (RoomLocation) null);
else if (lecture.getNrRooms() == 1)
placement = new Placement(lecture, time, old.getRoomLocation());
else
placement = new Placement(lecture, time, old.getRoomLocations());
if (!placement.isValid())
continue;
Set<Placement> conflicts = model.conflictValues(assignment, placement);
if (conflicts.contains(placement))
continue;
if (conflicts.isEmpty()) {
SimpleNeighbour<Lecture, Placement> n = new SimpleNeighbour<Lecture, Placement>(lecture, placement);
if (!iHC || n.value(assignment) <= 0)
return n;
else
continue;
}
Map<Lecture, Placement> assignments = new HashMap<Lecture, Placement>();
assignments.put(lecture, placement);
for (Placement conflict : conflicts) assignment.unassign(solution.getIteration(), conflict.variable());
assignment.assign(solution.getIteration(), placement);
Double v = resolve(solution, total, startTime, assignments, new ArrayList<Placement>(conflicts), 0);
if (!conflicts.isEmpty())
attempts++;
assignment.unassign(solution.getIteration(), lecture);
for (Placement conflict : conflicts) assignment.assign(solution.getIteration(), conflict);
assignment.assign(solution.getIteration(), old);
if (v != null)
return new SwapNeighbour(assignments.values(), v);
if (attempts >= iMaxAttempts)
break;
}
} finally {
lock.unlock();
}
}
return null;
}
use of org.cpsolver.coursett.model.TimetableModel in project cpsolver by UniTime.
the class StudentSwapSectioning method switchStudents.
@Override
public void switchStudents(Solution<Lecture, Placement> solution, TerminationCondition<Lecture, Placement> termination) {
long it = 0, lastImp = 0;
double t0 = JProf.currentTimeMillis();
DataProperties cfg = ((TimetableModel) solution.getModel()).getProperties();
long maxIdle = cfg.getPropertyInt("StudentSwaps.MaxIdle", 100000);
getProgress().setStatus("Student Sectioning...");
getProgress().info("Student Conflicts: " + sDF2.format(objective(solution)) + " (group: " + sDF2.format(gp(solution)) + "%)");
getProgress().setPhase("Swapping students [HC]...", 1000);
StudentSwapGenerator g = new StudentSwapGenerator();
while ((it - lastImp) < maxIdle && (termination == null || termination.canContinue(solution))) {
it++;
if ((it % 1000) == 0) {
long prg = Math.round(1000.0 * (it - lastImp) / maxIdle);
if (getProgress().getProgress() < prg)
getProgress().setProgress(prg);
if ((it % 10000) == 0)
getProgress().info("Iter=" + (it / 1000) + "k, Idle=" + sDF2.format((it - lastImp) / 1000.0) + "k, Speed=" + sDF2.format(1000.0 * it / (JProf.currentTimeMillis() - t0)) + " it/s" + ", Value=" + sDF2.format(value(solution)) + ", Objective=" + sDF2.format(objective(solution)) + ", Group=" + sDF2.format(gp(solution)) + "%");
}
Neighbour<Lecture, Placement> n = g.selectNeighbour(solution);
if (n == null)
continue;
double v = value(n, solution.getAssignment());
if (v < -sEps) {
lastImp = it;
}
if (v <= 0) {
n.assign(solution.getAssignment(), it);
}
}
getProgress().info("Student Conflicts: " + sDF2.format(objective(solution)) + " (group: " + sDF2.format(gp(solution)) + "%)");
double f = cfg.getPropertyDouble("StudentSwaps.Deluge.Factor", 0.9999999);
double ub = cfg.getPropertyDouble("StudentSwaps.Deluge.UpperBound", 1.10);
double lb = cfg.getPropertyDouble("StudentSwaps.Deluge.LowerBound", 0.90);
double total = value(solution);
double bound = ub * total;
double best = total;
it = 0;
lastImp = 0;
t0 = JProf.currentTimeMillis();
getProgress().setPhase("Swapping students [GD]...", 1000);
while (bound > lb * total && total > 0 && (termination == null || termination.canContinue(solution))) {
Neighbour<Lecture, Placement> n = g.selectNeighbour(solution);
if (n != null) {
double value = value(n, solution.getAssignment());
if (value < 0) {
lastImp = it;
}
if (value <= 0.0 || total + value < bound) {
n.assign(solution.getAssignment(), it);
if (total + value < best) {
best = total + value;
}
total += value;
}
}
bound *= f;
it++;
if ((it % 1000) == 0) {
long prg = 1000 - Math.round(1000.0 * (bound - lb * best) / (ub * best - lb * best));
if (getProgress().getProgress() < prg)
getProgress().setProgress(prg);
if ((it % 10000) == 0) {
getProgress().info("Iter=" + (it / 1000) + "k, Idle=" + sDF2.format((it - lastImp) / 1000.0) + "k, Speed=" + sDF2.format(1000.0 * it / (JProf.currentTimeMillis() - t0)) + " it/s" + ", Value=" + sDF2.format(value(solution)) + ", Objective=" + sDF2.format(objective(solution)) + ", Group=" + sDF2.format(gp(solution)) + "%");
getProgress().info("Bound is " + sDF2.format(bound) + ", " + "best value is " + sDF2.format(best) + " (" + sDF2.format(100.0 * bound / best) + "%), " + "current value is " + sDF2.format(total) + " (" + sDF2.format(100.0 * bound / total) + "%)");
}
}
}
getProgress().info("Student Conflicts: " + sDF2.format(objective(solution)) + " (group: " + sDF2.format(gp(solution)) + "%)");
}
use of org.cpsolver.coursett.model.TimetableModel in project cpsolver by UniTime.
the class GroupConstraint method computeConflicts.
public void computeConflicts(Assignment<Lecture, Placement> assignment, Placement value, Set<Placement> conflicts, boolean fwdCheck) {
if (!isHard())
return;
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))
conflicts.add(p);
}
if (getType().is(Flag.BACK_TO_BACK)) {
HashMap<Lecture, Placement> assignments = new HashMap<Lecture, Placement>();
assignments.put(value.variable(), value);
if (!isSatisfiedSeq(assignment, assignments, conflicts))
conflicts.add(value);
}
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, conflicts) > getType().getMax()) {
List<Placement> adepts = new ArrayList<Placement>();
for (Lecture l : variables()) {
if (l.equals(value.variable()) || l.isConstant())
continue;
Placement p = assignment.getValue(l);
if (p == null || conflicts.contains(p) || p.getTimeLocation() == null)
continue;
if ((p.getTimeLocation().getDayCode() & dayCode) == 0 || !p.getTimeLocation().shareWeeks(week))
continue;
adepts.add(p);
}
do {
if (adepts.isEmpty()) {
conflicts.add(value);
break;
}
Placement conflict = ToolBox.random(adepts);
adepts.remove(conflict);
conflicts.add(conflict);
} while (nrSlotsADay(assignment, dayCode, week, assignments, conflicts) > getType().getMax());
}
}
} else {
if (nrSlotsADay(assignment, dayCode, null, assignments, conflicts) > getType().getMax()) {
List<Placement> adepts = new ArrayList<Placement>();
for (Lecture l : variables()) {
if (l.equals(value.variable()) || l.isConstant())
continue;
Placement p = assignment.getValue(l);
if (p == null || conflicts.contains(p) || p.getTimeLocation() == null)
continue;
if ((p.getTimeLocation().getDayCode() & dayCode) == 0)
continue;
adepts.add(p);
}
do {
if (adepts.isEmpty()) {
conflicts.add(value);
break;
}
Placement conflict = ToolBox.random(adepts);
adepts.remove(conflict);
conflicts.add(conflict);
} while (nrSlotsADay(assignment, dayCode, null, assignments, conflicts) > getType().getMax());
}
}
}
}
// Forward checking
if (fwdCheck)
forwardCheck(assignment, value, conflicts, new HashSet<GroupConstraint>(), iForwardCheckMaxDepth - 1);
}
use of org.cpsolver.coursett.model.TimetableModel in project cpsolver by UniTime.
the class GroupConstraint method setModel.
@Override
public void setModel(Model<Lecture, Placement> model) {
super.setModel(model);
if (model != null) {
DataProperties config = ((TimetableModel) model).getProperties();
iDayOfWeekOffset = config.getPropertyInt("DatePattern.DayOfWeekOffset", 0);
iPrecedenceConsiderDatePatterns = config.getPropertyBoolean("Precedence.ConsiderDatePatterns", true);
iForwardCheckMaxDepth = config.getPropertyInt("ForwardCheck.MaxDepth", iForwardCheckMaxDepth);
iForwardCheckMaxDomainSize = config.getPropertyInt("ForwardCheck.MaxDomainSize", iForwardCheckMaxDomainSize);
iMaxNHoursADayConsiderDatePatterns = config.getPropertyBoolean("MaxNHoursADay.ConsiderDatePatterns", iMaxNHoursADayConsiderDatePatterns);
iNrWorkDays = (config.getPropertyInt("General.LastWorkDay", 4) - config.getPropertyInt("General.FirstWorkDay", 0) + 1);
}
}
Aggregations