use of org.cpsolver.studentsct.model.Enrollment in project cpsolver by UniTime.
the class UnbalancedSectionsTable method createTable.
/**
* Create report
*
* @param assignment current assignment
* @param includeLastLikeStudents
* true, if last-like students should be included (i.e.,
* {@link Student#isDummy()} is true)
* @param includeRealStudents
* true, if real students should be included (i.e.,
* {@link Student#isDummy()} is false)
* @param useAmPm use 12-hour format
* @return report as comma separated text file
*/
public CSVFile createTable(Assignment<Request, Enrollment> assignment, boolean includeLastLikeStudents, boolean includeRealStudents, boolean useAmPm) {
CSVFile csv = new CSVFile();
csv.setHeader(new CSVFile.CSVField[] { new CSVFile.CSVField("Course"), new CSVFile.CSVField("Class"), new CSVFile.CSVField("Meeting Time"), new CSVFile.CSVField("Enrollment"), new CSVFile.CSVField("Target"), new CSVFile.CSVField("Limit"), new CSVFile.CSVField("Disbalance [%]") });
TreeSet<Offering> offerings = new TreeSet<Offering>(new Comparator<Offering>() {
@Override
public int compare(Offering o1, Offering o2) {
int cmp = o1.getName().compareToIgnoreCase(o2.getName());
if (cmp != 0)
return cmp;
return o1.getId() < o2.getId() ? -1 : o2.getId() == o2.getId() ? 0 : 1;
}
});
offerings.addAll(getModel().getOfferings());
Offering last = null;
for (Offering offering : offerings) {
for (Config config : offering.getConfigs()) {
double configEnrl = 0;
for (Enrollment e : config.getEnrollments(assignment)) {
if (e.getStudent().isDummy() && !includeLastLikeStudents)
continue;
if (!e.getStudent().isDummy() && !includeRealStudents)
continue;
configEnrl += e.getRequest().getWeight();
}
for (Subpart subpart : config.getSubparts()) {
if (subpart.getSections().size() <= 1)
continue;
if (subpart.getLimit() > 0) {
// sections have limits -> desired size is section limit x (total enrollment / total limit)
double ratio = configEnrl / subpart.getLimit();
for (Section section : subpart.getSections()) {
double enrl = 0.0;
for (Enrollment e : section.getEnrollments(assignment)) {
if (e.getStudent().isDummy() && !includeLastLikeStudents)
continue;
if (!e.getStudent().isDummy() && !includeRealStudents)
continue;
enrl += e.getRequest().getWeight();
}
double desired = ratio * section.getLimit();
if (Math.abs(desired - enrl) >= Math.max(1.0, 0.1 * section.getLimit())) {
if (last != null && !offering.equals(last))
csv.addLine();
csv.addLine(new CSVFile.CSVField[] { new CSVFile.CSVField(offering.equals(last) ? "" : offering.getName()), new CSVFile.CSVField(section.getSubpart().getName() + " " + section.getName()), new CSVFile.CSVField(section.getTime() == null ? "" : section.getTime().getDayHeader() + " " + section.getTime().getStartTimeHeader(useAmPm) + " - " + section.getTime().getEndTimeHeader(useAmPm)), new CSVFile.CSVField(sDF1.format(enrl)), new CSVFile.CSVField(sDF2.format(desired)), new CSVFile.CSVField(sDF1.format(section.getLimit())), new CSVFile.CSVField(sDF2.format(Math.min(1.0, Math.max(-1.0, (enrl - desired) / section.getLimit())))) });
last = offering;
}
}
} else {
// unlimited sections -> desired size is total enrollment / number of sections
for (Section section : subpart.getSections()) {
double enrl = 0.0;
for (Enrollment e : section.getEnrollments(assignment)) {
if (e.getStudent().isDummy() && !includeLastLikeStudents)
continue;
if (!e.getStudent().isDummy() && !includeRealStudents)
continue;
enrl += e.getRequest().getWeight();
}
double desired = configEnrl / subpart.getSections().size();
if (Math.abs(desired - enrl) >= Math.max(1.0, 0.1 * desired)) {
if (last != null && !offering.equals(last))
csv.addLine();
csv.addLine(new CSVFile.CSVField[] { new CSVFile.CSVField(offering.equals(last) ? "" : offering.getName()), new CSVFile.CSVField(section.getSubpart().getName() + " " + section.getName()), new CSVFile.CSVField(section.getTime() == null ? "" : section.getTime().getDayHeader() + " " + section.getTime().getStartTimeHeader(useAmPm) + " - " + section.getTime().getEndTimeHeader(useAmPm)), new CSVFile.CSVField(sDF1.format(enrl)), new CSVFile.CSVField(sDF2.format(desired)), new CSVFile.CSVField(""), new CSVFile.CSVField(sDF2.format(Math.min(1.0, Math.max(-1.0, (enrl - desired) / desired)))) });
last = offering;
}
}
}
}
}
}
return csv;
}
use of org.cpsolver.studentsct.model.Enrollment in project cpsolver by UniTime.
the class EqualStudentWeights method main.
/**
* Test case -- run to see the weights for a few courses
* @param args program arguments
*/
public static void main(String[] args) {
EqualStudentWeights pw = new EqualStudentWeights(new DataProperties());
DecimalFormat df = new DecimalFormat("0.0000");
Student s = new Student(0l);
new CourseRequest(1l, 0, false, s, ToolBox.toList(new Course(1, "A", "1", new Offering(0, "A")), new Course(1, "A", "2", new Offering(0, "A")), new Course(1, "A", "3", new Offering(0, "A"))), false, null);
new CourseRequest(2l, 1, false, s, ToolBox.toList(new Course(1, "B", "1", new Offering(0, "B")), new Course(1, "B", "2", new Offering(0, "B")), new Course(1, "B", "3", new Offering(0, "B"))), false, null);
new CourseRequest(3l, 2, false, s, ToolBox.toList(new Course(1, "C", "1", new Offering(0, "C")), new Course(1, "C", "2", new Offering(0, "C")), new Course(1, "C", "3", new Offering(0, "C"))), false, null);
new CourseRequest(5l, 4, false, s, ToolBox.toList(new Course(1, "E", "1", new Offering(0, "E")), new Course(1, "E", "2", new Offering(0, "E")), new Course(1, "E", "3", new Offering(0, "E"))), false, null);
new CourseRequest(6l, 5, true, s, ToolBox.toList(new Course(1, "F", "1", new Offering(0, "F")), new Course(1, "F", "2", new Offering(0, "F")), new Course(1, "F", "3", new Offering(0, "F"))), false, null);
new CourseRequest(7l, 6, true, s, ToolBox.toList(new Course(1, "G", "1", new Offering(0, "G")), new Course(1, "G", "2", new Offering(0, "G")), new Course(1, "G", "3", new Offering(0, "G"))), false, null);
Assignment<Request, Enrollment> assignment = new DefaultSingleAssignment<Request, Enrollment>();
Placement p = new Placement(null, new TimeLocation(1, 90, 12, 0, 0, null, null, new BitSet(), 10), new ArrayList<RoomLocation>());
for (Request r : s.getRequests()) {
CourseRequest cr = (CourseRequest) r;
double[] w = new double[] { 0.0, 0.0, 0.0 };
for (int i = 0; i < cr.getCourses().size(); i++) {
Config cfg = new Config(0l, -1, "", cr.getCourses().get(i).getOffering());
Set<SctAssignment> sections = new HashSet<SctAssignment>();
sections.add(new Section(0, 1, "x", new Subpart(0, "Lec", "Lec", cfg, null), p, null));
Enrollment e = new Enrollment(cr, i, cfg, sections, assignment);
w[i] = pw.getWeight(assignment, e, null, null);
}
System.out.println(cr + ": " + df.format(w[0]) + " " + df.format(w[1]) + " " + df.format(w[2]));
}
System.out.println("With one distance conflict:");
for (Request r : s.getRequests()) {
CourseRequest cr = (CourseRequest) r;
double[] w = new double[] { 0.0, 0.0, 0.0 };
for (int i = 0; i < cr.getCourses().size(); i++) {
Config cfg = new Config(0l, -1, "", cr.getCourses().get(i).getOffering());
Set<SctAssignment> sections = new HashSet<SctAssignment>();
sections.add(new Section(0, 1, "x", new Subpart(0, "Lec", "Lec", cfg, null), p, null));
Enrollment e = new Enrollment(cr, i, cfg, sections, assignment);
Set<DistanceConflict.Conflict> dc = new HashSet<DistanceConflict.Conflict>();
dc.add(new DistanceConflict.Conflict(s, e, (Section) sections.iterator().next(), e, (Section) sections.iterator().next()));
w[i] = pw.getWeight(assignment, e, dc, null);
}
System.out.println(cr + ": " + df.format(w[0]) + " " + df.format(w[1]) + " " + df.format(w[2]));
}
System.out.println("With two distance conflicts:");
for (Request r : s.getRequests()) {
CourseRequest cr = (CourseRequest) r;
double[] w = new double[] { 0.0, 0.0, 0.0 };
for (int i = 0; i < cr.getCourses().size(); i++) {
Config cfg = new Config(0l, -1, "", cr.getCourses().get(i).getOffering());
Set<SctAssignment> sections = new HashSet<SctAssignment>();
sections.add(new Section(0, 1, "x", new Subpart(0, "Lec", "Lec", cfg, null), p, null));
Enrollment e = new Enrollment(cr, i, cfg, sections, assignment);
Set<DistanceConflict.Conflict> dc = new HashSet<DistanceConflict.Conflict>();
dc.add(new DistanceConflict.Conflict(s, e, (Section) sections.iterator().next(), e, (Section) sections.iterator().next()));
dc.add(new DistanceConflict.Conflict(s, e, (Section) sections.iterator().next(), e, new Section(1, 1, "x", new Subpart(0, "Lec", "Lec", cfg, null), p, null)));
w[i] = pw.getWeight(assignment, e, dc, null);
}
System.out.println(cr + ": " + df.format(w[0]) + " " + df.format(w[1]) + " " + df.format(w[2]));
}
System.out.println("With 25% time overlapping conflict:");
for (Request r : s.getRequests()) {
CourseRequest cr = (CourseRequest) r;
double[] w = new double[] { 0.0, 0.0, 0.0 };
for (int i = 0; i < cr.getCourses().size(); i++) {
Config cfg = new Config(0l, -1, "", cr.getCourses().get(i).getOffering());
Set<SctAssignment> sections = new HashSet<SctAssignment>();
sections.add(new Section(0, 1, "x", new Subpart(0, "Lec", "Lec", cfg, null), p, null));
Enrollment e = new Enrollment(cr, i, cfg, sections, assignment);
Set<TimeOverlapsCounter.Conflict> toc = new HashSet<TimeOverlapsCounter.Conflict>();
toc.add(new TimeOverlapsCounter.Conflict(s, 3, e, sections.iterator().next(), e, sections.iterator().next()));
w[i] = pw.getWeight(assignment, e, null, toc);
}
System.out.println(cr + ": " + df.format(w[0]) + " " + df.format(w[1]) + " " + df.format(w[2]));
}
System.out.println("Disbalanced sections (by 2 / 10 students):");
for (Request r : s.getRequests()) {
CourseRequest cr = (CourseRequest) r;
double[] w = new double[] { 0.0, 0.0, 0.0 };
for (int i = 0; i < cr.getCourses().size(); i++) {
Config cfg = new Config(0l, -1, "", cr.getCourses().get(i).getOffering());
Set<SctAssignment> sections = new HashSet<SctAssignment>();
Subpart x = new Subpart(0, "Lec", "Lec", cfg, null);
Section a = new Section(0, 10, "x", x, p, null);
new Section(1, 10, "y", x, p, null);
sections.add(a);
a.assigned(assignment, new Enrollment(s.getRequests().get(0), i, cfg, sections, assignment));
a.assigned(assignment, new Enrollment(s.getRequests().get(0), i, cfg, sections, assignment));
cfg.getContext(assignment).assigned(assignment, new Enrollment(s.getRequests().get(0), i, cfg, sections, assignment));
cfg.getContext(assignment).assigned(assignment, new Enrollment(s.getRequests().get(0), i, cfg, sections, assignment));
Enrollment e = new Enrollment(cr, i, cfg, sections, assignment);
w[i] = pw.getWeight(assignment, e, null, null);
}
System.out.println(cr + ": " + df.format(w[0]) + " " + df.format(w[1]) + " " + df.format(w[2]));
}
System.out.println("Same sections:");
pw.iMPP = true;
for (Request r : s.getRequests()) {
CourseRequest cr = (CourseRequest) r;
double[] w = new double[] { 0.0, 0.0, 0.0 };
double dif = 0;
for (int i = 0; i < cr.getCourses().size(); i++) {
Config cfg = new Config(0l, -1, "", cr.getCourses().get(i).getOffering());
Set<SctAssignment> sections = new HashSet<SctAssignment>();
sections.add(new Section(0, 1, "x", new Subpart(0, "Lec", "Lec", cfg, null), p, null));
Enrollment e = new Enrollment(cr, i, cfg, sections, assignment);
cr.setInitialAssignment(new Enrollment(cr, i, cfg, sections, assignment));
w[i] = pw.getWeight(assignment, e, null, null);
dif = pw.getDifference(e);
}
System.out.println(cr + ": " + df.format(w[0]) + " " + df.format(w[1]) + " " + df.format(w[2]) + " (" + df.format(dif) + ")");
}
System.out.println("Same choice sections:");
pw.iMPP = true;
for (Request r : s.getRequests()) {
CourseRequest cr = (CourseRequest) r;
double[] w = new double[] { 0.0, 0.0, 0.0 };
double dif = 0;
for (int i = 0; i < cr.getCourses().size(); i++) {
Config cfg = new Config(0l, -1, "", cr.getCourses().get(i).getOffering());
Set<SctAssignment> sections = new HashSet<SctAssignment>();
sections.add(new Section(0, 1, "x", new Subpart(0, "Lec", "Lec", cfg, null), p, null));
Enrollment e = new Enrollment(cr, i, cfg, sections, assignment);
Set<SctAssignment> other = new HashSet<SctAssignment>();
other.add(new Section(1, 1, "x", new Subpart(0, "Lec", "Lec", cfg, null), p, null));
cr.setInitialAssignment(new Enrollment(cr, i, cfg, other, assignment));
w[i] = pw.getWeight(assignment, e, null, null);
dif = pw.getDifference(e);
}
System.out.println(cr + ": " + df.format(w[0]) + " " + df.format(w[1]) + " " + df.format(w[2]) + " (" + df.format(dif) + ")");
}
System.out.println("Same time sections:");
for (Request r : s.getRequests()) {
CourseRequest cr = (CourseRequest) r;
double dif = 0;
double[] w = new double[] { 0.0, 0.0, 0.0 };
for (int i = 0; i < cr.getCourses().size(); i++) {
Config cfg = new Config(0l, -1, "", cr.getCourses().get(i).getOffering());
Set<SctAssignment> sections = new HashSet<SctAssignment>();
sections.add(new Section(0, 1, "x", new Subpart(0, "Lec", "Lec", cfg, null), p, null));
Enrollment e = new Enrollment(cr, i, cfg, sections, assignment);
Set<SctAssignment> other = new HashSet<SctAssignment>();
other.add(new Section(1, 1, "x", new Subpart(0, "Lec", "Lec", cfg, null), p, null, new Instructor(1, null, "Josef Novak", null)));
cr.setInitialAssignment(new Enrollment(cr, i, cfg, other, assignment));
w[i] = pw.getWeight(assignment, e, null, null);
dif = pw.getDifference(e);
}
System.out.println(cr + ": " + df.format(w[0]) + " " + df.format(w[1]) + " " + df.format(w[2]) + " (" + df.format(dif) + ")");
}
System.out.println("Same configuration sections:");
for (Request r : s.getRequests()) {
CourseRequest cr = (CourseRequest) r;
double[] w = new double[] { 0.0, 0.0, 0.0 };
double dif = 0;
for (int i = 0; i < cr.getCourses().size(); i++) {
Config cfg = new Config(0l, -1, "", cr.getCourses().get(i).getOffering());
Set<SctAssignment> sections = new HashSet<SctAssignment>();
sections.add(new Section(0, 1, "x", new Subpart(0, "Lec", "Lec", cfg, null), p, null));
Enrollment e = new Enrollment(cr, i, cfg, sections, assignment);
cr.getSelectedChoices().add(new Choice(cfg));
cr.setInitialAssignment(null);
w[i] = pw.getWeight(assignment, e, null, null);
dif = pw.getDifference(e);
}
System.out.println(cr + ": " + df.format(w[0]) + " " + df.format(w[1]) + " " + df.format(w[2]) + " (" + df.format(dif) + ")");
}
System.out.println("Different time sections:");
Placement q = new Placement(null, new TimeLocation(1, 102, 12, 0, 0, null, null, new BitSet(), 10), new ArrayList<RoomLocation>());
for (Request r : s.getRequests()) {
CourseRequest cr = (CourseRequest) r;
double[] w = new double[] { 0.0, 0.0, 0.0 };
double dif = 0;
for (int i = 0; i < cr.getCourses().size(); i++) {
Config cfg = new Config(0l, -1, "", cr.getCourses().get(i).getOffering());
Set<SctAssignment> sections = new HashSet<SctAssignment>();
sections.add(new Section(0, 1, "x", new Subpart(0, "Lec", "Lec", cfg, null), p, null));
Enrollment e = new Enrollment(cr, i, cfg, sections, assignment);
Set<SctAssignment> other = new HashSet<SctAssignment>();
other.add(new Section(1, 1, "x", new Subpart(0, "Lec", "Lec", cfg, null), q, null));
cr.setInitialAssignment(new Enrollment(cr, i, cfg, other, assignment));
w[i] = pw.getWeight(assignment, e, null, null);
dif = pw.getDifference(e);
}
System.out.println(cr + ": " + df.format(w[0]) + " " + df.format(w[1]) + " " + df.format(w[2]) + " (" + df.format(dif) + ")");
}
System.out.println("Two sections, one same choice, one same time:");
for (Request r : s.getRequests()) {
CourseRequest cr = (CourseRequest) r;
double[] w = new double[] { 0.0, 0.0, 0.0 };
double dif = 0;
for (int i = 0; i < cr.getCourses().size(); i++) {
Config cfg = new Config(0l, -1, "", cr.getCourses().get(i).getOffering());
Set<SctAssignment> sections = new HashSet<SctAssignment>();
sections.add(new Section(0, 1, "x", new Subpart(0, "Lec", "Lec", cfg, null), p, null));
sections.add(new Section(1, 1, "y", new Subpart(1, "Rec", "Rec", cfg, null), p, null));
Enrollment e = new Enrollment(cr, i, cfg, sections, assignment);
Set<SctAssignment> other = new HashSet<SctAssignment>();
other.add(new Section(2, 1, "x", new Subpart(0, "Lec", "Lec", cfg, null), p, null));
other.add(new Section(3, 1, "y", new Subpart(1, "Rec", "Rec", cfg, null), p, null, new Instructor(1, null, "Josef Novak", null)));
cr.setInitialAssignment(new Enrollment(cr, i, cfg, other, assignment));
w[i] = pw.getWeight(assignment, e, null, null);
dif = pw.getDifference(e);
}
System.out.println(cr + ": " + df.format(w[0]) + " " + df.format(w[1]) + " " + df.format(w[2]) + " (" + df.format(dif) + ")");
}
}
use of org.cpsolver.studentsct.model.Enrollment in project cpsolver by UniTime.
the class ShuffleStudentsSelection method init.
@Override
public void init(Solver<Request, Enrollment> solver) {
StudentSectioningModel model = (StudentSectioningModel) solver.currentSolution().getModel();
iQueue = new LinkedList<Shuffle>();
Assignment<Request, Enrollment> assignment = solver.currentSolution().getAssignment();
// Check all request groups that have a spread < 1.0
RouletteWheelSelection<RequestGroup> groups = new RouletteWheelSelection<RequestGroup>();
for (Offering offering : model.getOfferings()) {
for (Course course : offering.getCourses()) {
for (RequestGroup group : course.getRequestGroups()) {
double spread = group.getAverageSpread(solver.currentSolution().getAssignment());
if (spread >= 1.0)
continue;
groups.add(group, 1.0 - spread);
}
}
}
// If there are some, pick one randomly (using roulette wheel selection)
if (groups.hasMoreElements()) {
RequestGroup group = groups.nextElement();
RouletteWheelSelection<Subpart> subparts = new RouletteWheelSelection<Subpart>();
for (CourseRequest cr : group.getRequests()) {
Enrollment e = assignment.getValue(cr);
if (e != null)
for (Section section : e.getSections()) if (group.getSectionSpread(assignment, section) < 1.0)
subparts.addExisting(section.getSubpart(), 1.0);
}
if (subparts.hasMoreElements()) {
// Pick a subpart that has sections with a section spread < 1.0
Subpart subpart = subparts.nextElement();
RouletteWheelSelection<Section> sections = new RouletteWheelSelection<Section>();
section: for (Section section : subpart.getSections()) {
// Only take sections that all requests can use
for (CourseRequest cr : group.getRequests()) {
boolean match = false;
for (Enrollment e : cr.values(assignment)) if (e.getSections().contains(section)) {
match = true;
break;
}
if (!match)
continue section;
}
// Take sections with conflicts with lower probability
int nrConflicts = 0;
if (!section.isAllowOverlap())
requests: for (CourseRequest cr : group.getRequests()) {
for (Request r : cr.getStudent().getRequests()) {
if (r.equals(cr))
continue;
Enrollment e = assignment.getValue(r);
if (e != null && !e.isAllowOverlap() && section.isOverlapping(e.getSections())) {
nrConflicts++;
continue requests;
}
}
}
sections.add(section, 1 + group.getRequests().size() - nrConflicts);
}
Set<Section> filter = new HashSet<Section>();
double space = 0.0;
// Pick enough sections
while (sections.hasMoreElements()) {
Section section = sections.nextElement();
if (filter.add(section)) {
if (section.getLimit() < 0)
break;
space += section.getLimit();
}
if (space >= group.getTotalWeight())
break;
}
// Add all requests that should be moved into the queue
for (CourseRequest cr : group.getRequests()) {
Shuffle shuffle = new Shuffle(group, cr, filter);
Enrollment e = assignment.getValue(cr);
if (e != null && shuffle.matchFilter(e))
continue;
iQueue.add(shuffle);
}
} else {
// No subpart -> no section filter
for (CourseRequest cr : group.getRequests()) iQueue.add(new Shuffle(group, cr, null));
}
}
// Shuffle the queue
Collections.shuffle((LinkedList<Shuffle>) iQueue);
// Initialize the backtrack selection, if needed
if (iBacktrack == null) {
try {
iBacktrack = new ShuffleBacktrackNeighbourSelection(solver.getProperties());
iBacktrack.init(solver);
} catch (Exception e) {
throw new RuntimeException(e.getMessage(), e);
}
}
// Change progress
Progress.getInstance(solver.currentSolution().getModel()).setPhase("Shuffling students along request groups...", iQueue.size());
}
use of org.cpsolver.studentsct.model.Enrollment in project cpsolver by UniTime.
the class ShuffleStudentsSelection method selectNeighbour.
@Override
public Neighbour<Request, Enrollment> selectNeighbour(Solution<Request, Enrollment> solution) {
Shuffle shuffle = null;
while ((shuffle = iQueue.poll()) != null) {
Progress.getInstance(solution.getModel()).incProgress();
// Take an item from the queue, try backtrack first
Neighbour<Request, Enrollment> n = iBacktrack.selectNeighbour(solution, shuffle);
if (n != null)
return n;
// If fails, just assign the request randomly and hope for the best
List<Enrollment> adepts = new ArrayList<Enrollment>();
for (Enrollment e : shuffle.getRequest().values(solution.getAssignment())) {
if (shuffle.matchFilter(e))
adepts.add(e);
}
if (!adepts.isEmpty()) {
return new SimpleNeighbour<Request, Enrollment>(shuffle.getRequest(), ToolBox.random(adepts));
}
}
return null;
}
use of org.cpsolver.studentsct.model.Enrollment in project cpsolver by UniTime.
the class StandardSelection method selectNeighbour.
/**
* Employ the provided {@link VariableSelection} and {@link ValueSelection}
* and return the selected value as {@link SimpleNeighbour}. The selection
* is stopped (null is returned) after the number of iterations equal to the
* number of variables in the problem or when a complete solution is found.
*/
@Override
public Neighbour<Request, Enrollment> selectNeighbour(Solution<Request, Enrollment> solution) {
if (iNrIterations < 0) {
iNrIterations = solution.getModel().nrUnassignedVariables(solution.getAssignment());
Progress.getInstance(solution.getModel()).setPhase("Ifs...", iNrIterations);
}
if (solution.getModel().unassignedVariables(solution.getAssignment()).isEmpty() || ++iIteration >= iNrIterations)
return null;
Progress.getInstance(solution.getModel()).incProgress();
for (int i = 0; i < 10; i++) {
Request request = iVariableSelection.selectVariable(solution);
if (request == null)
continue;
Enrollment enrollment = iValueSelection.selectValue(solution, request);
if (enrollment == null)
continue;
Set<Enrollment> conflicts = enrollment.variable().getModel().conflictValues(solution.getAssignment(), enrollment);
if (!conflicts.contains(enrollment))
return new SimpleNeighbour<Request, Enrollment>(request, enrollment, conflicts);
}
return null;
}
Aggregations