use of org.cpsolver.studentsct.model.Request in project cpsolver by UniTime.
the class InevitableStudentConflicts method check.
/** Check model for inevitable student conflicts
* @param assignment current assignment
* @return true if there are no inevitable student conflicts
**/
public boolean check(Assignment<Request, Enrollment> assignment) {
sLog.info("Checking for inevitable student conflicts...");
HashMap<TreeSet<Object>, Object[]> noGoods = new HashMap<TreeSet<Object>, Object[]>();
long studentWithoutCompleteSchedule = 0;
long inevitableRequests = 0;
double inevitableRequestWeight = 0.0;
long incompleteInevitableRequests = 0;
double incompleteInevitableRequestWeight = 0.0;
long total = 0;
Comparator<Object> simpleCmp = new Comparator<Object>() {
@Override
public int compare(Object o1, Object o2) {
return o1.toString().compareTo(o2.toString());
}
};
HashSet<Request> requests2remove = new HashSet<Request>();
for (Student student : getModel().getStudents()) {
sLog.debug(" Checking " + (++total) + ". student " + student + "...");
if (student.isComplete(assignment)) {
for (Request request : student.getRequests()) {
if (assignment.getValue(request) == null) {
inevitableRequests++;
inevitableRequestWeight += request.getWeight();
}
}
} else {
StudentCheck ch = new StudentCheck(student.getRequests());
ch.check(assignment);
if (!ch.isBestComplete()) {
sLog.info(" Student " + student + " cannot have a complete schedule");
studentWithoutCompleteSchedule++;
}
int idx = 0;
for (Iterator<Request> f = student.getRequests().iterator(); f.hasNext(); idx++) {
Request request = f.next();
Enrollment enrollment = ch.getBestAssignment()[idx];
if (enrollment == null) {
if (!ch.isBestComplete()) {
List<Request> noGood = noGood(assignment, student, ch, idx);
sLog.info(" Request " + request + " cannot be assigned");
for (Request r : noGood) {
sLog.debug(" " + r);
Collection<Enrollment> values = null;
if (r instanceof CourseRequest) {
values = ((CourseRequest) r).getEnrollmentsSkipSameTime(assignment);
} else {
values = request.computeEnrollments(assignment);
}
for (Enrollment en : values) {
sLog.debug(" " + enrollment2string(en));
}
}
if (iDeleteInevitable) {
// noGood.lastElement()
requests2remove.add(request);
sLog.info(" -- request " + request + " picked to be removed from the model");
}
TreeSet<Object> key = new TreeSet<Object>(simpleCmp);
for (Request r : noGood) {
if (r instanceof CourseRequest) {
key.add(((CourseRequest) r).getCourses().get(0));
} else {
key.add("Free " + ((FreeTimeRequest) r).getTime().getLongName(true));
}
}
Object[] counter = noGoods.get(key);
int ir = (counter == null ? 1 : ((Integer) counter[0]).intValue() + 1);
double irw = (counter == null ? 0.0 : ((Double) counter[1]).doubleValue()) + request.getWeight();
noGoods.put(key, new Object[] { new Integer(ir), new Double(irw) });
if (ch.canAssign(request, idx)) {
incompleteInevitableRequests++;
incompleteInevitableRequestWeight += request.getWeight();
}
}
inevitableRequests++;
inevitableRequestWeight += request.getWeight();
}
}
}
}
for (Map.Entry<TreeSet<Object>, Object[]> entry : noGoods.entrySet()) {
TreeSet<Object> noGood = entry.getKey();
Object[] counter = entry.getValue();
List<CSVFile.CSVField> fields = new ArrayList<CSVFile.CSVField>();
String courseStr = "";
for (Iterator<Object> j = noGood.iterator(); j.hasNext(); ) {
Object x = j.next();
if (x instanceof Course) {
Course course = (Course) x;
courseStr += course.getName();
} else
courseStr += x.toString();
if (j.hasNext())
courseStr += ", ";
}
fields.add(new CSVFile.CSVField(courseStr));
fields.add(new CSVFile.CSVField(((Integer) counter[0]).intValue()));
fields.add(new CSVFile.CSVField(((Double) counter[1]).doubleValue()));
for (Iterator<Object> j = noGood.iterator(); j.hasNext(); ) {
Object x = j.next();
if (x instanceof Course) {
Course course = (Course) x;
List<Course> courses = new ArrayList<Course>(1);
courses.add(course);
CourseRequest cr = new CourseRequest(-1, 0, false, new Student(-1), courses, false, null);
String field = course.getName();
int idx = 0;
for (Iterator<Enrollment> k = cr.getEnrollmentsSkipSameTime(assignment).iterator(); k.hasNext(); ) {
if (idx++ > 20) {
field += "\n ...";
break;
} else {
field += "\n " + enrollment2string(k.next());
}
}
fields.add(new CSVFile.CSVField(field));
} else
fields.add(new CSVFile.CSVField(x.toString()));
}
iCSVFile.addLine(fields);
}
if (!requests2remove.isEmpty()) {
for (Request request : requests2remove) {
removeRequest(request);
}
}
sLog.info("Students that can never obtain a complete schedule: " + studentWithoutCompleteSchedule);
sLog.info("Inevitable student requests: " + inevitableRequests);
sLog.info("Inevitable student request weight: " + inevitableRequestWeight);
sLog.info("Inevitable student requests of students without a complete schedule: " + incompleteInevitableRequests);
sLog.info("Inevitable student request weight of students without a complete schedule: " + incompleteInevitableRequestWeight);
if (iCSVFile.getLines() != null)
Collections.sort(iCSVFile.getLines(), new Comparator<CSVFile.CSVLine>() {
@Override
public int compare(CSVFile.CSVLine l1, CSVFile.CSVLine l2) {
int cmp = Double.compare(l2.getField(1).toDouble(), l1.getField(1).toDouble());
if (cmp != 0)
return cmp;
return l1.getField(0).toString().compareTo(l2.getField(0).toString());
}
});
return (inevitableRequests == 0);
}
use of org.cpsolver.studentsct.model.Request in project cpsolver by UniTime.
the class DistanceConflict method computeAllConflicts.
/**
* Compute a set of all distance conflicts ({@link Conflict} objects).
* @param assignment current assignment
* @return computed set of all distance conflicts
*/
public Set<Conflict> computeAllConflicts(Assignment<Request, Enrollment> assignment) {
Set<Conflict> ret = new HashSet<Conflict>();
for (Request r1 : getModel().variables()) {
Enrollment e1 = assignment.getValue(r1);
if (e1 == null || !(r1 instanceof CourseRequest))
continue;
ret.addAll(conflicts(e1));
for (Request r2 : r1.getStudent().getRequests()) {
Enrollment e2 = assignment.getValue(r2);
if (e2 == null || r1.getId() >= r2.getId() || !(r2 instanceof CourseRequest))
continue;
ret.addAll(conflicts(e1, e2));
}
}
return ret;
}
use of org.cpsolver.studentsct.model.Request in project cpsolver by UniTime.
the class TimeOverlapsCounter method allConflicts.
/**
* The set of all conflicts ({@link Conflict} objects) of the given
* enrollment and other enrollments that are assigned to the same student.
* @param assignment current assignment
* @param enrollment given enrollment
* @return all conflicts of the given enrollment
*/
public Set<Conflict> allConflicts(Assignment<Request, Enrollment> assignment, Enrollment enrollment) {
Set<Conflict> ret = new HashSet<Conflict>();
if (enrollment.getRequest() instanceof FreeTimeRequest)
return ret;
for (Request request : enrollment.getStudent().getRequests()) {
if (request.equals(enrollment.getRequest()))
continue;
Enrollment other = assignment.getValue(request);
if (request instanceof FreeTimeRequest) {
FreeTimeRequest ft = (FreeTimeRequest) request;
ret.addAll(conflicts(enrollment, ft.createEnrollment()));
continue;
} else if (other != null) {
ret.addAll(conflicts(enrollment, other));
}
}
for (Unavailability unavailability : enrollment.getStudent().getUnavailabilities()) for (SctAssignment section : enrollment.getAssignments()) if (inConflict(section, unavailability))
ret.add(new Conflict(enrollment.getStudent(), share(section, unavailability), enrollment, section, unavailability.createEnrollment(), unavailability));
return ret;
}
use of org.cpsolver.studentsct.model.Request in project cpsolver by UniTime.
the class EnrollmentSelection method selectValue.
/** Value selection */
@Override
public Enrollment selectValue(Solution<Request, Enrollment> solution, Request selectedVariable) {
Assignment<Request, Enrollment> assignment = solution.getAssignment();
if (iMPP) {
if (selectedVariable.getInitialAssignment() != null) {
if (solution.getModel().unassignedVariables(assignment).isEmpty()) {
if (solution.getModel().perturbVariables(assignment).size() <= iMPPLimit)
iMPPLimit = solution.getModel().perturbVariables(assignment).size() - 1;
}
if (iMPPLimit >= 0 && solution.getModel().perturbVariables(assignment).size() > iMPPLimit) {
if (isAllowed(assignment, selectedVariable.getInitialAssignment()))
return selectedVariable.getInitialAssignment();
}
if (selectedVariable.getInitialAssignment() != null && ToolBox.random() <= iInitialSelectionProb) {
if (isAllowed(assignment, selectedVariable.getInitialAssignment()))
return selectedVariable.getInitialAssignment();
}
}
}
List<Enrollment> values = selectedVariable.values(assignment);
if (ToolBox.random() <= iRandomWalkProb) {
Enrollment value = ToolBox.random(values);
if (isAllowed(assignment, value))
return value;
}
if (iProp != null && assignment.getValue(selectedVariable) == null && ToolBox.random() <= iGoodSelectionProb) {
Set<Enrollment> goodValues = iProp.goodValues(assignment, selectedVariable);
if (!goodValues.isEmpty())
values = new ArrayList<Enrollment>(goodValues);
}
if (values.size() == 1) {
Enrollment value = values.get(0);
if (isAllowed(assignment, value))
return value;
else
return null;
}
List<Enrollment> bestValues = null;
double bestWeightedSum = 0;
for (Enrollment value : values) {
if (iTabu != null && iTabu.contains(value))
continue;
if (assignment.getValue(selectedVariable) != null && assignment.getValue(selectedVariable).equals(value))
continue;
Set<Enrollment> conf = solution.getModel().conflictValues(assignment, value);
if (conf.contains(value))
continue;
if (!isAllowed(assignment, value, conf))
continue;
double weightedConflicts = (iStat == null || iWeightWeightedCoflicts == 0.0 ? 0.0 : iStat.countRemovals(solution.getIteration(), conf, value));
double potentialConflicts = (iStat == null || iWeightPotentialConflicts == 0.0 ? 0.0 : iStat.countPotentialConflicts(assignment, solution.getIteration(), value, 3));
long deltaInitialAssignments = 0;
if (iMPP && iWeightDeltaInitialAssignment != 0.0) {
if (iViolatedInitials != null) {
Set<Enrollment> violations = iViolatedInitials.getViolatedInitials(value);
if (violations != null) {
for (Enrollment aValue : violations) {
if (assignment.getValue(aValue.variable()) == null || assignment.getValue(aValue.variable()).equals(aValue))
deltaInitialAssignments += 2;
}
}
}
for (Enrollment aValue : conf) {
if (aValue.variable().getInitialAssignment() != null)
deltaInitialAssignments--;
}
if (selectedVariable.getInitialAssignment() != null && !selectedVariable.getInitialAssignment().equals(value)) {
deltaInitialAssignments++;
}
if (iMPPLimit >= 0 && (solution.getModel().perturbVariables(assignment).size() + deltaInitialAssignments) > iMPPLimit)
continue;
}
double weightedSum = (iWeightDeltaInitialAssignment * deltaInitialAssignments) + (iWeightPotentialConflicts * potentialConflicts) + (iWeightWeightedCoflicts * weightedConflicts) + (iWeightCoflicts * conf.size()) + (iWeightValue * value.toDouble(assignment));
if (bestValues == null || bestWeightedSum > weightedSum) {
bestWeightedSum = weightedSum;
if (bestValues == null)
bestValues = new ArrayList<Enrollment>();
else
bestValues.clear();
bestValues.add(value);
} else {
if (bestWeightedSum == weightedSum)
bestValues.add(value);
}
}
Enrollment selectedValue = (bestValues == null ? null : ToolBox.random(bestValues));
if (selectedValue == null)
selectedValue = ToolBox.random(values);
if (iTabu != null) {
if (iTabu.size() == iTabuPos)
iTabu.add(selectedValue);
else
iTabu.set(iTabuPos, selectedValue);
iTabuPos = (iTabuPos + 1) % iTabuSize;
}
return (bestValues == null ? null : selectedValue);
}
use of org.cpsolver.studentsct.model.Request in project cpsolver by UniTime.
the class RandomizedBacktrackNeighbourSelection method values.
/**
* List of values of a variable.
* {@link CourseRequest#computeRandomEnrollments(Assignment, int)} with the provided
* limit is used for a {@link CourseRequest}.
*/
@Override
protected Iterator<Enrollment> values(BacktrackNeighbourSelection<Request, Enrollment>.BacktrackNeighbourSelectionContext<Request, Enrollment> context, Request variable) {
if (variable instanceof CourseRequest) {
final CourseRequest request = (CourseRequest) variable;
final StudentSectioningModel model = (StudentSectioningModel) context.getModel();
final Assignment<Request, Enrollment> assignment = context.getAssignment();
List<Enrollment> values = (iMaxValues > 0 ? request.computeRandomEnrollments(assignment, iMaxValues) : request.computeEnrollments(assignment));
Collections.sort(values, new Comparator<Enrollment>() {
private HashMap<Enrollment, Double> iValues = new HashMap<Enrollment, Double>();
private Double value(Enrollment e) {
Double value = iValues.get(e);
if (value == null) {
value = model.getStudentWeights().getWeight(assignment, e, (model.getDistanceConflict() == null ? null : model.getDistanceConflict().conflicts(e)), (model.getTimeOverlaps() == null ? null : model.getTimeOverlaps().conflicts(e)));
iValues.put(e, value);
}
return value;
}
@Override
public int compare(Enrollment e1, Enrollment e2) {
if (e1.equals(assignment.getValue(request)))
return -1;
if (e2.equals(assignment.getValue(request)))
return 1;
Double v1 = value(e1), v2 = value(e2);
return v1.equals(v2) ? e1.compareTo(assignment, e2) : v2.compareTo(v1);
}
});
return values.iterator();
} else {
return variable.computeEnrollments(context.getAssignment()).iterator();
}
}
Aggregations