use of org.cpsolver.studentsct.model.Enrollment in project cpsolver by UniTime.
the class StudentSctBBTest method getMessages.
/**
* Return a list of messages ({@link Message} objects) from the sectioning
* of the given student
* @return enrollment messages
*/
public List<Message> getMessages() {
Assignment<Request, Enrollment> assignment = getSolution().getAssignment();
List<Message> ret = new ArrayList<Message>();
ret.add(new Message(Message.sMsgLevelInfo, null, "<li>Solution found in " + iTime + " ms."));
if (iTimeoutReached)
ret.add(new Message(Message.sMsgLevelInfo, null, "<li>Time out reached, solution optimality can not be guaranteed."));
for (Request request : getStudent().getRequests()) {
if (!request.isAlternative() && assignment.getValue(request) == null) {
ret.add(new Message(Message.sMsgLevelWarn, request, "<li>Unable to enroll to " + request + ", " + (request instanceof CourseRequest ? ((CourseRequest) request).getCourses().size() == 1 ? "course is" : "courses are" : "time is") + " not available."));
Collection<Enrollment> values = (request instanceof CourseRequest ? (Collection<Enrollment>) ((CourseRequest) request).getAvaiableEnrollmentsSkipSameTime(assignment) : request.computeEnrollments(assignment));
for (Iterator<Enrollment> f = values.iterator(); f.hasNext(); ) {
Enrollment enrollment = f.next();
Set<Enrollment> conf = conflictValues(assignment, enrollment);
if (conf != null && !conf.isEmpty()) {
Enrollment conflict = conf.iterator().next();
if (conflict.equals(enrollment))
ret.add(new Message(Message.sMsgLevelInfo, request, "<ul>Assignment of " + enrollment.getName().replaceAll("\n", "<br> ") + "<br> is not available."));
else
ret.add(new Message(Message.sMsgLevelInfo, request, "<ul>Assignment of " + enrollment.getName().replaceAll("\n", "<br> ") + "<br> conflicts with " + conflict.getName().replaceAll("\n", "<br> ") + "</ul>"));
}
}
}
if (request instanceof CourseRequest && assignment.getValue(request) != null) {
CourseRequest courseRequest = (CourseRequest) request;
Enrollment enrollment = assignment.getValue(request);
List<Enrollment> selectedEnrollments = courseRequest.getSelectedEnrollments(assignment, false);
if (selectedEnrollments != null && !selectedEnrollments.isEmpty() && !selectedEnrollments.contains(enrollment)) {
Course course = (courseRequest.getSelectedChoices().iterator().next()).getOffering().getCourse(getStudent());
Enrollment selected = selectedEnrollments.get(0);
Set<Enrollment> conf = conflictValues(assignment, selected);
if (conf != null && !conf.isEmpty()) {
ret.add(new Message(Message.sMsgLevelWarn, request, "<li>Unable to enroll selected enrollment for " + course.getName() + ", seleted " + (courseRequest.getSelectedChoices().size() == 1 ? "class is" : "classes are") + " conflicting with other choices."));
Enrollment conflict = conf.iterator().next();
if (conflict.equals(selected))
ret.add(new Message(Message.sMsgLevelInfo, request, "<ul>Assignment of " + selected.getName().replaceAll("\n", "<br> ") + "<br> is not available."));
else
ret.add(new Message(Message.sMsgLevelInfo, request, "<ul>Assignment of " + selected.getName().replaceAll("\n", "<br> ") + "<br> conflicts with " + conflict.getName().replaceAll("\n", "<br> ") + "</ul>"));
} else {
ret.add(new Message(Message.sMsgLevelWarn, request, "<li>Unable to enroll selected enrollment for " + course.getName() + "."));
}
}
}
}
return ret;
}
use of org.cpsolver.studentsct.model.Enrollment in project cpsolver by UniTime.
the class Solution2Expectations method main.
public static void main(String[] args) {
try {
ToolBox.configureLogging();
DataProperties config = new DataProperties();
String command = args[0];
if ("real2exp".equals(command)) {
StudentSectioningModel model = new StudentSectioningModel(config);
Assignment<Request, Enrollment> assignment = new DefaultSingleAssignment<Request, Enrollment>();
StudentSectioningXMLLoader loader = new StudentSectioningXMLLoader(model, assignment);
loader.setInputFile(new File(args[1]));
loader.load();
sLog.info("Loaded: " + ToolBox.dict2string(model.getExtendedInfo(assignment), 2));
for (Student s : model.getStudents()) s.setDummy(true);
model.computeOnlineSectioningInfos(assignment);
for (Student s : model.getStudents()) s.setDummy(false);
for (Request request : model.variables()) assignment.unassign(0, request);
Solution<Request, Enrollment> solution = new Solution<Request, Enrollment>(model, assignment, 0, 0);
Solver<Request, Enrollment> solver = new Solver<Request, Enrollment>(config);
solver.setInitalSolution(solution);
new StudentSectioningXMLSaver(solver).save(new File(args[2]));
sLog.info("Saved: " + ToolBox.dict2string(model.getExtendedInfo(assignment), 2));
} else if ("ll2exp".equals(command)) {
StudentSectioningModel model = new StudentSectioningModel(config);
Assignment<Request, Enrollment> assignment = new DefaultSingleAssignment<Request, Enrollment>();
StudentSectioningXMLLoader loader = new StudentSectioningXMLLoader(model, assignment);
loader.setInputFile(new File(args[1]));
loader.load();
sLog.info("Loaded: " + ToolBox.dict2string(model.getExtendedInfo(assignment), 2));
model.computeOnlineSectioningInfos(assignment);
for (Request request : model.variables()) assignment.unassign(0, request);
Solution<Request, Enrollment> solution = new Solution<Request, Enrollment>(model, assignment, 0, 0);
Solver<Request, Enrollment> solver = new Solver<Request, Enrollment>(config);
solver.setInitalSolution(solution);
new StudentSectioningXMLSaver(solver).save(new File(args[2]));
sLog.info("Saved: " + ToolBox.dict2string(model.getExtendedInfo(assignment), 2));
} else if ("students".equals(command)) {
StudentSectioningModel model = new StudentSectioningModel(config);
Assignment<Request, Enrollment> assignment = new DefaultSingleAssignment<Request, Enrollment>();
StudentSectioningXMLLoader loader = new StudentSectioningXMLLoader(model, assignment);
loader.setInputFile(new File(args[1]));
loader.setLoadStudents(false);
loader.load();
sLog.info("Loaded [1]: " + ToolBox.dict2string(model.getExtendedInfo(assignment), 2));
StudentSectioningXMLLoader loder2 = new StudentSectioningXMLLoader(model, assignment);
loder2.setInputFile(new File(args[2]));
loder2.setLoadOfferings(false);
loder2.setLoadStudents(true);
loder2.load();
sLog.info("Loaded [2]: " + ToolBox.dict2string(model.getExtendedInfo(assignment), 2));
Solution<Request, Enrollment> solution = new Solution<Request, Enrollment>(model, assignment, 0, 0);
Solver<Request, Enrollment> solver = new Solver<Request, Enrollment>(config);
solver.setInitalSolution(solution);
new StudentSectioningXMLSaver(solver).save(new File(args[3]));
sLog.info("Saved [3]: " + ToolBox.dict2string(model.getExtendedInfo(assignment), 2));
} else {
sLog.error("Unknown command: " + command);
}
} catch (Exception e) {
sLog.error(e.getMessage(), e);
}
}
use of org.cpsolver.studentsct.model.Enrollment in project cpsolver by UniTime.
the class Test method updateSpace.
public static void updateSpace(Assignment<Request, Enrollment> assignment, Enrollment enrollment, boolean increment) {
if (enrollment == null || !enrollment.isCourseRequest())
return;
for (Section section : enrollment.getSections()) section.setSpaceHeld(section.getSpaceHeld() + (increment ? 1.0 : -1.0));
List<Enrollment> feasibleEnrollments = new ArrayList<Enrollment>();
int totalLimit = 0;
for (Enrollment enrl : enrollment.getRequest().values(assignment)) {
if (!enrl.getCourse().equals(enrollment.getCourse()))
continue;
boolean overlaps = false;
for (Request otherRequest : enrollment.getRequest().getStudent().getRequests()) {
if (otherRequest.equals(enrollment.getRequest()) || !(otherRequest instanceof CourseRequest))
continue;
Enrollment otherErollment = assignment.getValue(otherRequest);
if (otherErollment == null)
continue;
if (enrl.isOverlapping(otherErollment)) {
overlaps = true;
break;
}
}
if (!overlaps) {
feasibleEnrollments.add(enrl);
if (totalLimit >= 0) {
int limit = enrl.getLimit();
if (limit < 0)
totalLimit = -1;
else
totalLimit += limit;
}
}
}
double change = enrollment.getRequest().getWeight() / (totalLimit > 0 ? totalLimit : feasibleEnrollments.size());
for (Enrollment feasibleEnrollment : feasibleEnrollments) for (Section section : feasibleEnrollment.getSections()) {
if (totalLimit > 0) {
section.setSpaceExpected(section.getSpaceExpected() + (increment ? +change : -change) * feasibleEnrollment.getLimit());
} else {
section.setSpaceExpected(section.getSpaceExpected() + (increment ? +change : -change));
}
}
}
use of org.cpsolver.studentsct.model.Enrollment in project cpsolver by UniTime.
the class Test method clone.
protected Course clone(Course course, long studentId, Student originalStudent, Map<Long, Section> classTable, StudentSectioningModel model) {
Offering clonedOffering = new Offering(course.getOffering().getId(), course.getOffering().getName());
clonedOffering.setModel(model);
int courseLimit = course.getLimit();
if (courseLimit >= 0) {
courseLimit -= course.getEnrollments(assignment()).size();
if (courseLimit < 0)
courseLimit = 0;
for (Iterator<Enrollment> i = course.getEnrollments(assignment()).iterator(); i.hasNext(); ) {
Enrollment enrollment = i.next();
if (enrollment.getStudent().getId() == studentId) {
courseLimit++;
break;
}
}
}
Course clonedCourse = new Course(course.getId(), course.getSubjectArea(), course.getCourseNumber(), clonedOffering, courseLimit, course.getProjected());
clonedCourse.setNote(course.getNote());
Hashtable<Config, Config> configs = new Hashtable<Config, Config>();
Hashtable<Subpart, Subpart> subparts = new Hashtable<Subpart, Subpart>();
Hashtable<Section, Section> sections = new Hashtable<Section, Section>();
for (Iterator<Config> e = course.getOffering().getConfigs().iterator(); e.hasNext(); ) {
Config config = e.next();
int configLimit = config.getLimit();
int configEnrollment = config.getEnrollments(assignment()).size();
if (configLimit >= 0) {
configLimit -= config.getEnrollments(assignment()).size();
if (configLimit < 0)
configLimit = 0;
for (Iterator<Enrollment> i = config.getEnrollments(assignment()).iterator(); i.hasNext(); ) {
Enrollment enrollment = i.next();
if (enrollment.getStudent().getId() == studentId) {
configLimit++;
configEnrollment--;
break;
}
}
}
OnlineConfig clonedConfig = new OnlineConfig(config.getId(), configLimit, config.getName(), clonedOffering);
clonedConfig.setInstructionalMethodId(config.getInstructionalMethodId());
clonedConfig.setInstructionalMethodName(config.getInstructionalMethodName());
clonedConfig.setEnrollment(configEnrollment);
configs.put(config, clonedConfig);
for (Iterator<Subpart> f = config.getSubparts().iterator(); f.hasNext(); ) {
Subpart subpart = f.next();
Subpart clonedSubpart = new Subpart(subpart.getId(), subpart.getInstructionalType(), subpart.getName(), clonedConfig, (subpart.getParent() == null ? null : subparts.get(subpart.getParent())));
clonedSubpart.setAllowOverlap(subpart.isAllowOverlap());
clonedSubpart.setCredit(subpart.getCredit());
subparts.put(subpart, clonedSubpart);
for (Iterator<Section> g = subpart.getSections().iterator(); g.hasNext(); ) {
Section section = g.next();
int limit = section.getLimit();
int enrl = section.getEnrollments(assignment()).size();
if (limit >= 0) {
// limited section, deduct enrollments
limit -= section.getEnrollments(assignment()).size();
if (limit < 0)
// over-enrolled, but not unlimited
limit = 0;
if (studentId >= 0)
for (Enrollment enrollment : section.getEnrollments(assignment())) if (enrollment.getStudent().getId() == studentId) {
limit++;
enrl--;
break;
}
}
OnlineSection clonedSection = new OnlineSection(section.getId(), limit, section.getName(course.getId()), clonedSubpart, section.getPlacement(), section.getInstructors(), (section.getParent() == null ? null : sections.get(section.getParent())));
clonedSection.setName(-1l, section.getName(-1l));
clonedSection.setNote(section.getNote());
clonedSection.setSpaceExpected(section.getSpaceExpected());
clonedSection.setSpaceHeld(section.getSpaceHeld());
clonedSection.setEnrollment(enrl);
clonedSection.setCancelled(section.isCancelled());
if (section.getIgnoreConflictWithSectionIds() != null)
for (Long id : section.getIgnoreConflictWithSectionIds()) clonedSection.addIgnoreConflictWith(id);
if (limit > 0) {
double available = Math.round(section.getSpaceExpected() - limit);
clonedSection.setPenalty(available / section.getLimit());
}
sections.put(section, clonedSection);
classTable.put(section.getId(), clonedSection);
}
}
}
if (course.getOffering().hasReservations()) {
for (Reservation reservation : course.getOffering().getReservations()) {
int reservationLimit = (int) Math.round(reservation.getLimit());
if (reservationLimit >= 0) {
reservationLimit -= reservation.getEnrollments(assignment()).size();
if (reservationLimit < 0)
reservationLimit = 0;
for (Iterator<Enrollment> i = reservation.getEnrollments(assignment()).iterator(); i.hasNext(); ) {
Enrollment enrollment = i.next();
if (enrollment.getStudent().getId() == studentId) {
reservationLimit++;
break;
}
}
if (reservationLimit <= 0 && !reservation.mustBeUsed())
continue;
}
boolean applicable = originalStudent != null && reservation.isApplicable(originalStudent);
if (reservation instanceof CourseReservation)
applicable = (course.getId() == ((CourseReservation) reservation).getCourse().getId());
if (reservation instanceof org.cpsolver.studentsct.reservation.DummyReservation) {
// the student is already enrolled in the course
for (Enrollment enrollment : course.getEnrollments(assignment())) if (enrollment.getStudent().getId() == studentId) {
applicable = true;
break;
}
}
Reservation clonedReservation = new OnlineReservation(0, reservation.getId(), clonedOffering, reservation.getPriority(), reservation.canAssignOverLimit(), reservationLimit, applicable, reservation.mustBeUsed(), reservation.isAllowOverlap(), reservation.isExpired());
for (Config config : reservation.getConfigs()) clonedReservation.addConfig(configs.get(config));
for (Map.Entry<Subpart, Set<Section>> entry : reservation.getSections().entrySet()) {
Set<Section> clonedSections = new HashSet<Section>();
for (Section section : entry.getValue()) clonedSections.add(sections.get(section));
clonedReservation.getSections().put(subparts.get(entry.getKey()), clonedSections);
}
}
}
return clonedCourse;
}
use of org.cpsolver.studentsct.model.Enrollment in project cpsolver by UniTime.
the class ReservationLimit method computeConflicts.
/**
* A given enrollment is conflicting, if the reservation's remaining available space
* (computed by {@link Reservation#getReservedAvailableSpace(Assignment, Request)})
* is below the requests weight {@link Request#getWeight()}. <br>
* If the limit is breached, one or more existing enrollments are
* selected as conflicting until there is enough space in the reservation.
* Similarly, if the enrollment does not have the reservation, it is checked
* that there is enough unreserved space in the desired configuration.
*
* @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) {
// enrollment's config
Config config = enrollment.getConfig();
// exclude free time requests
if (config == null)
return;
// no reservations
if (!config.getOffering().hasReservations())
return;
// enrollment's reservation
Reservation reservation = enrollment.getReservation();
// check space in the reservation reservation
if (reservation != null) {
// check reservation too
double reserved = reservation.getReservedAvailableSpace(assignment, enrollment.getRequest());
if (reservation.getLimit() >= 0 && reserved < enrollment.getRequest().getWeight()) {
// reservation is not unlimited and there is not enough space in it
// try to free some space in the reservation
List<Enrollment> adepts = new ArrayList<Enrollment>(config.getEnrollments(assignment).size());
for (Enrollment e : config.getEnrollments(assignment)) {
if (e.getRequest().equals(enrollment.getRequest()))
continue;
if (!reservation.equals(e.getReservation()))
continue;
if (conflicts.contains(e))
reserved += e.getRequest().getWeight();
else
adepts.add(e);
}
while (reserved < enrollment.getRequest().getWeight()) {
if (adepts.isEmpty()) {
// no adepts -> enrollment cannot be assigned
conflicts.add(enrollment);
return;
}
// 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);
reserved += conflict.getRequest().getWeight();
conflicts.add(conflict);
}
}
// if not configuration reservation -> check configuration unavailable space
if (!hasConfigReservation(enrollment)) {
// check reservation can assign over the limit
if (reservation.canBatchAssignOverLimit())
return;
// the section for an enrollment w/o configuration reservation
if (config.getTotalUnreservedSpace() < enrollment.getRequest().getWeight()) {
conflicts.add(enrollment);
return;
}
double unreserved = getUnreservedSpace(assignment, config, enrollment.getRequest(), true);
if (unreserved < 0.0) {
// no unreserved space available -> cannot be assigned
// try to unassign some other enrollments that also do not have config reservation
List<Enrollment> adepts = new ArrayList<Enrollment>(config.getEnrollments(assignment).size());
for (Enrollment e : config.getEnrollments(assignment)) {
if (e.getRequest().equals(enrollment.getRequest()))
continue;
if (hasConfigReservation(e))
continue;
if (conflicts.contains(e))
unreserved += e.getRequest().getWeight();
else
adepts.add(e);
}
while (unreserved < 0.0) {
if (adepts.isEmpty()) {
// no adepts -> enrollment cannot be assigned
conflicts.add(enrollment);
return;
}
// 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);
unreserved += conflict.getRequest().getWeight();
conflicts.add(conflict);
}
}
}
} else {
// the section for an enrollment w/o reservation
if (config.getOffering().getTotalUnreservedSpace() < enrollment.getRequest().getWeight() || config.getTotalUnreservedSpace() < enrollment.getRequest().getWeight()) {
conflicts.add(enrollment);
return;
}
// check configuration unavailable space too
double unreserved = getUnreservedSpace(assignment, config, enrollment.getRequest(), false);
if (unreserved < 0.0) {
// no unreserved space available -> cannot be assigned
// try to unassign some other enrollments that also do not have reservation
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)
continue;
if (conflicts.contains(e))
unreserved += e.getRequest().getWeight();
else
adepts.add(e);
}
while (unreserved < 0.0) {
if (adepts.isEmpty()) {
// no adepts -> enrollment cannot be assigned
conflicts.add(enrollment);
return;
}
// 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);
unreserved += conflict.getRequest().getWeight();
conflicts.add(conflict);
}
}
}
}
Aggregations