From 26bc66f000661c8f4abdf50abaf3fa21c438689e Mon Sep 17 00:00:00 2001 From: tomas-muller Date: Thu, 26 Feb 2015 10:38:30 +0100 Subject: [PATCH 1/2] Class Limit - simplified computation of the class limit during solution commit (there is no need to use an assignment proxy as the assignment for which the committed event is being generated can be used instead) --- .../unitime/timetable/model/Assignment.java | 4 +- .../org/unitime/timetable/model/Class_.java | 53 +++++++++++-------- 2 files changed, 34 insertions(+), 23 deletions(-) diff --git a/JavaSource/org/unitime/timetable/model/Assignment.java b/JavaSource/org/unitime/timetable/model/Assignment.java index dac8b9da56..633326857c 100644 --- a/JavaSource/org/unitime/timetable/model/Assignment.java +++ b/JavaSource/org/unitime/timetable/model/Assignment.java @@ -335,8 +335,8 @@ public ClassEvent generateCommittedEvent(ClassEvent event, boolean createNoRoomM if (getClazz().getSession().getStatusType().isTestSession()) return null; } event.setEventName(getClassName()); - event.setMinCapacity(clazz.getClassLimit()); - event.setMaxCapacity(clazz.getClassLimit()); + event.setMinCapacity(clazz.getClassLimit(this)); + event.setMaxCapacity(clazz.getClassLimit(this)); boolean changePast = ApplicationProperty.ClassAssignmentChangePastMeetings.isTrue(); Calendar cal = Calendar.getInstance(Locale.US); diff --git a/JavaSource/org/unitime/timetable/model/Class_.java b/JavaSource/org/unitime/timetable/model/Class_.java index ebfce02d8b..042a286275 100644 --- a/JavaSource/org/unitime/timetable/model/Class_.java +++ b/JavaSource/org/unitime/timetable/model/Class_.java @@ -865,43 +865,54 @@ public String getDivSecNumber() { public int getClassLimit() { return getClassLimit(new CommitedClassAssignmentProxy()); } + + public int getClassLimit(Assignment assignment) { + int minLimit = getExpectedCapacity(); + int maxLimit = getMaxExpectedCapacity(); + int limit = maxLimit; + if (minLimit < maxLimit && assignment != null) { + int roomLimit = (int) Math.floor(assignment.getPlacement().getRoomSize() / (getRoomRatio() == null ? 1.0f : getRoomRatio())); + limit = Math.min(Math.max(minLimit, roomLimit), maxLimit); + } + + return limit; + } public int getClassLimit(ClassAssignmentProxy proxy) { - // MinClassLimit == MaxClassLimit == ClassLimit - if (getExpectedCapacity().equals(getMaxExpectedCapacity())) return getExpectedCapacity().intValue(); + // min and max limits + int minLimit = getExpectedCapacity(); + int maxLimit = getMaxExpectedCapacity(); - // No assignment -> take MaxClassLimit - int maxClassLimit = getMaxExpectedCapacity().intValue(); + // is there a twiggle room? + if (minLimit == maxLimit) return maxLimit; + + // get assignment Assignment assignment = null; try { - assignment = (proxy==null?null:proxy.getAssignment(this)); + assignment = (proxy == null ? null : proxy.getAssignment(this)); } catch (Exception e) { Debug.error(e); } - if (assignment!=null) { - // Assignment -> take smaller from MaxClassLimit and RoomSize / RoomRatio - maxClassLimit = Math.min( - getMaxExpectedCapacity().intValue(), - (int)Math.floor(assignment.getPlacement().getRoomSize()/getRoomRatio().floatValue())); + + // if there is an assignment, check the room limit + if (assignment != null) { + int roomLimit = (int) Math.floor(assignment.getPlacement().getRoomSize() / (getRoomRatio() == null ? 1.0f : getRoomRatio())); + if (roomLimit < maxLimit) maxLimit = roomLimit; } - if (getChildClasses().isEmpty()) return maxClassLimit; - // if there are children classes ... - for (Iterator i=getSchedulingSubpart().getChildSubparts().iterator();i.hasNext();) { - SchedulingSubpart childSubpart = (SchedulingSubpart)i.next(); + for (SchedulingSubpart childSubpart: getSchedulingSubpart().getChildSubparts()) { // take all children classes of the same subpart, sum their class limit - int maxChildrenLimit = 0; - for (Iterator j=getChildClasses().iterator();j.hasNext();) { - Class_ childClass = (Class_)j.next(); + int childrenLimit = 0; + for (Class_ childClass: getChildClasses()) { if (!childClass.getSchedulingSubpart().equals(childSubpart)) continue; - maxChildrenLimit += childClass.getClassLimit(proxy); + childrenLimit += childClass.getClassLimit(proxy); } // children class limit cannot be exceeded - maxClassLimit = Math.min(maxClassLimit, maxChildrenLimit); + if (childrenLimit < maxLimit) maxLimit = childrenLimit; } - - return maxClassLimit; + + return Math.max(minLimit, maxLimit); } public int getClassLimit(CourseOffering offering) { From e7ffaf478b1b00df2aea4f19e7621f4e98283a36 Mon Sep 17 00:00:00 2001 From: tomas-muller Date: Thu, 26 Feb 2015 10:38:50 +0100 Subject: [PATCH 2/2] Student Class Enrollment Import / Export - export: include class unique id - import: use the class unique id when provided before using class external id, name, or course / subject / type / suffix combination - this is to make sure that an exported schedule can be imported back into UniTime without any issues --- .../dataexchange/StudentEnrollmentExport.java | 1 + .../dataexchange/StudentEnrollmentImport.java | 29 +++++++++++-------- 2 files changed, 18 insertions(+), 12 deletions(-) diff --git a/JavaSource/org/unitime/timetable/dataexchange/StudentEnrollmentExport.java b/JavaSource/org/unitime/timetable/dataexchange/StudentEnrollmentExport.java index 77e0cc2fcd..7b5cd4dbca 100644 --- a/JavaSource/org/unitime/timetable/dataexchange/StudentEnrollmentExport.java +++ b/JavaSource/org/unitime/timetable/dataexchange/StudentEnrollmentExport.java @@ -60,6 +60,7 @@ public void saveXml(Document document, Session session, Properties parameters) t String extId = (course == null ? clazz.getExternalUniqueId() : clazz.getExternalId(course)); if (extId != null && !extId.isEmpty()) classEl.addAttribute("externalId", extId); + classEl.addAttribute("id", clazz.getUniqueId().toString()); if (course != null) { if (course.getExternalUniqueId() != null && !course.getExternalUniqueId().isEmpty()) classEl.addAttribute("courseId", course.getExternalUniqueId()); diff --git a/JavaSource/org/unitime/timetable/dataexchange/StudentEnrollmentImport.java b/JavaSource/org/unitime/timetable/dataexchange/StudentEnrollmentImport.java index 7688ff75fb..227661a3d5 100644 --- a/JavaSource/org/unitime/timetable/dataexchange/StudentEnrollmentImport.java +++ b/JavaSource/org/unitime/timetable/dataexchange/StudentEnrollmentImport.java @@ -170,8 +170,11 @@ public void loadXml(Element rootElement) throws Exception { Class_ clazz = null; CourseOffering course = null; + if (clazz == null && classElement.attributeValue("id") != null) + clazz = id2class.get(Long.valueOf(classElement.attributeValue("id"))); + String classExternalId = classElement.attributeValue("externalId"); - if (classExternalId != null) { + if (clazz == null && classExternalId != null) { clazz = extId2class.get(classExternalId); course = extId2course.get(classExternalId); if (clazz == null) { @@ -186,14 +189,19 @@ public void loadXml(Element rootElement) throws Exception { course = name2course.get(className); } - String courseName = classElement.attributeValue("course"); - if (courseName != null) { - course = cname2course.get(courseName); - } else { - String subject = classElement.attributeValue("subject"); - String courseNbr = classElement.attributeValue("courseNbr"); - if (subject != null && courseNbr != null) - course = cname2course.get(subject + " " + courseNbr); + if (course == null && classElement.attributeValue("courseId") != null) + course = cextId2course.get(classElement.attributeValue("courseId")); + + if (course == null) { + String courseName = classElement.attributeValue("course"); + if (courseName != null) { + course = cname2course.get(courseName); + } else { + String subject = classElement.attributeValue("subject"); + String courseNbr = classElement.attributeValue("courseNbr"); + if (subject != null && courseNbr != null) + course = cname2course.get(subject + " " + courseNbr); + } } if (course != null && clazz == null) { @@ -203,9 +211,6 @@ public void loadXml(Element rootElement) throws Exception { clazz = name2class.get(course.getCourseName() + " " + type.trim() + " " + suffix); } - if (clazz == null && classElement.attributeValue("id") != null) - clazz = id2class.get(Long.valueOf(classElement.attributeValue("id"))); - if (clazz == null) { warn("Class " + (classExternalId != null ? classExternalId : classElement.attributeValue("name", classElement.attributeValue("course", classElement.attributeValue("subject") + " " + classElement.attributeValue("courseNbr")) + " " +