use of org.cpsolver.studentsct.model.Enrollment in project cpsolver by UniTime.
the class StudentSectioningModel method removeStudent.
/**
* Remove a student from the model
* @param student a student to be removed from the problem
*/
public void removeStudent(Student student) {
iStudents.remove(student);
if (student.isDummy())
iNrDummyStudents--;
StudentConflict conflict = null;
for (Request request : student.getRequests()) {
for (Constraint<Request, Enrollment> c : request.constraints()) {
if (c instanceof StudentConflict) {
conflict = (StudentConflict) c;
break;
}
}
if (conflict != null)
conflict.removeVariable(request);
removeVariable(request);
}
if (conflict != null)
removeConstraint(conflict);
}
use of org.cpsolver.studentsct.model.Enrollment in project cpsolver by UniTime.
the class OverlapCheck method check.
/**
* Check for overlapping sections that are attended by the same student
* @param a current assignment
* @return false, if there is such a case
*/
public boolean check(Assignment<Request, Enrollment> a) {
sLog.info("Checking for overlaps...");
boolean ret = true;
for (Student student : getModel().getStudents()) {
HashMap<TimeLocation, SctAssignment> times = new HashMap<TimeLocation, SctAssignment>();
for (Request request : student.getRequests()) {
Enrollment enrollment = a.getValue(request);
if (enrollment == null)
continue;
for (SctAssignment assignment : enrollment.getAssignments()) {
if (assignment.getTime() == null)
continue;
for (TimeLocation time : times.keySet()) {
if (time.hasIntersection(assignment.getTime())) {
sLog.error("Student " + student + " assignment " + assignment + " overlaps with " + times.get(time));
ret = false;
}
}
times.put(assignment.getTime(), assignment);
}
}
}
return ret;
}
use of org.cpsolver.studentsct.model.Enrollment in project cpsolver by UniTime.
the class ConfigLimit method computeConflicts.
/**
* A given enrollment is conflicting, if the config's enrollment
* (computed by {@link ConfigLimit#getEnrollmentWeight(Assignment, Config, Request)})
* exceeds the limit. <br>
* If the limit is breached, one or more existing enrollments are
* (randomly) selected as conflicting until the overall weight is under the
* limit.
*
* @param enrollment
* {@link Enrollment} that is being considered
* @param conflicts
* all computed conflicting requests are added into this set
*/
@Override
public void computeConflicts(Assignment<Request, Enrollment> assignment, Enrollment enrollment, Set<Enrollment> conflicts) {
// check reservation can assign over the limit
if (enrollment.getReservation() != null && enrollment.getReservation().canBatchAssignOverLimit())
return;
// enrollment's config
Config config = enrollment.getConfig();
// exclude free time requests
if (config == null)
return;
// unlimited config
if (config.getLimit() < 0)
return;
// new enrollment weight
double enrlWeight = getEnrollmentWeight(assignment, config, enrollment.getRequest());
// below limit -> ok
if (enrlWeight <= config.getLimit())
return;
// above limit -> compute adepts (current assignments that are not
// yet conflicting)
// exclude all conflicts as well
List<Enrollment> adepts = new ArrayList<Enrollment>(config.getEnrollments(assignment).size());
for (Enrollment e : config.getEnrollments(assignment)) {
if (e.getRequest().equals(enrollment.getRequest()))
continue;
if (e.getReservation() != null && e.getReservation().canBatchAssignOverLimit())
continue;
if (conflicts.contains(e))
enrlWeight -= e.getRequest().getWeight();
else
adepts.add(e);
}
// while above limit -> pick an adept and make it conflicting
while (enrlWeight > config.getLimit()) {
if (adepts.isEmpty()) {
// no adepts -> enrollment cannot be assigned
conflicts.add(enrollment);
return;
}
// pick adept (prefer dummy students & students w/o reservation), decrease enrollment
// weight, make conflict
List<Enrollment> best = new ArrayList<Enrollment>();
boolean bestDummy = false;
double bestValue = 0;
boolean bestRes = true;
for (Enrollment adept : adepts) {
boolean dummy = adept.getStudent().isDummy();
double value = adept.toDouble(assignment, false);
boolean res = (adept.getReservation() != null);
if (iPreferDummyStudents && dummy != bestDummy) {
if (dummy) {
best.clear();
best.add(adept);
bestDummy = dummy;
bestValue = value;
bestRes = res;
}
continue;
}
if (bestRes != res) {
if (!res) {
best.clear();
best.add(adept);
bestDummy = dummy;
bestValue = value;
bestRes = res;
}
continue;
}
if (best.isEmpty() || value > bestValue) {
if (best.isEmpty())
best.clear();
best.add(adept);
bestDummy = dummy;
bestValue = value;
bestRes = res;
} else if (bestValue == value) {
best.add(adept);
}
}
Enrollment conflict = ToolBox.random(best);
adepts.remove(conflict);
enrlWeight -= conflict.getRequest().getWeight();
conflicts.add(conflict);
}
}
use of org.cpsolver.studentsct.model.Enrollment in project cpsolver by UniTime.
the class CourseLimit method computeConflicts.
/**
* A given enrollment is conflicting, if the course's enrollment
* (computed by {@link CourseLimit#getEnrollmentWeight(Assignment, Course, Request)})
* exceeds the limit. <br>
* If the limit is breached, one or more existing enrollments are
* (randomly) selected as conflicting until the overall weight is under the
* limit.
*
* @param enrollment
* {@link Enrollment} that is being considered
* @param conflicts
* all computed conflicting requests are added into this set
*/
@Override
public void computeConflicts(Assignment<Request, Enrollment> assignment, Enrollment enrollment, Set<Enrollment> conflicts) {
// check reservation can assign over the limit
if (enrollment.getReservation() != null && enrollment.getReservation().canBatchAssignOverLimit())
return;
// enrollment's course
Course course = enrollment.getCourse();
// exclude free time requests
if (course == null)
return;
// unlimited course
if (course.getLimit() < 0)
return;
// new enrollment weight
double enrlWeight = getEnrollmentWeight(assignment, course, enrollment.getRequest());
// below limit -> ok
if (enrlWeight <= course.getLimit())
return;
// above limit -> compute adepts (current assignments that are not
// yet conflicting)
// exclude all conflicts as well
List<Enrollment> adepts = new ArrayList<Enrollment>(course.getEnrollments(assignment).size());
for (Enrollment e : course.getEnrollments(assignment)) {
if (e.getRequest().equals(enrollment.getRequest()))
continue;
if (e.getReservation() != null && e.getReservation().canBatchAssignOverLimit())
continue;
if (conflicts.contains(e))
enrlWeight -= e.getRequest().getWeight();
else
adepts.add(e);
}
// while above limit -> pick an adept and make it conflicting
while (enrlWeight > course.getLimit()) {
if (adepts.isEmpty()) {
// no adepts -> enrollment cannot be assigned
conflicts.add(enrollment);
break;
}
// pick adept (prefer dummy students), decrease unreserved space,
// make conflict
List<Enrollment> best = new ArrayList<Enrollment>();
boolean bestDummy = false;
double bestValue = 0;
for (Enrollment adept : adepts) {
boolean dummy = adept.getStudent().isDummy();
double value = adept.toDouble(assignment, false);
if (iPreferDummyStudents && dummy != bestDummy) {
if (dummy) {
best.clear();
best.add(adept);
bestDummy = dummy;
bestValue = value;
}
continue;
}
if (best.isEmpty() || value > bestValue) {
if (best.isEmpty())
best.clear();
best.add(adept);
bestDummy = dummy;
bestValue = value;
} else if (bestValue == value) {
best.add(adept);
}
}
Enrollment conflict = ToolBox.random(best);
adepts.remove(conflict);
enrlWeight -= conflict.getRequest().getWeight();
conflicts.add(conflict);
}
}
use of org.cpsolver.studentsct.model.Enrollment in project cpsolver by UniTime.
the class StudentPreferencePenalties method getMinMaxAvailableEnrollmentPenalty.
/** Minimal and maximal available enrollment penalty of a request
* @param assignment current assignment
* @param request student course request
* @return minimal and maximal available enrollment penalty
**/
public double[] getMinMaxAvailableEnrollmentPenalty(Assignment<Request, Enrollment> assignment, CourseRequest request) {
List<Enrollment> enrollments = request.getAvaiableEnrollments(assignment);
if (enrollments.isEmpty())
return new double[] { 0, 0 };
double min = Double.MAX_VALUE, max = Double.MIN_VALUE;
for (Enrollment enrollment : enrollments) {
double penalty = getPenalty(enrollment);
min = Math.min(min, penalty);
max = Math.max(max, penalty);
}
return new double[] { min, max };
}
Aggregations