Skip to content

Commit d3827ec

Browse files
committed
Batch Student Scheduling: Free Times
- for students with FT (need free-time) accommodation: added an ability to mark the free-time requests as higher priority - using solver parameter Load.FreeTimeAccRequestPriority set to Normal, Important, Vital, or Critical - added an ability to make sure that low-priority course requests do not overlap with a higher-priority free time request, even when it is not assigned - using solver parameter Sectioning.FreeTimeConflict is set to true; set to false by default - a few changes in the user interface to show free time request priority and free time conflicts
1 parent 10b8b8b commit d3827ec

12 files changed

Lines changed: 92 additions & 56 deletions

File tree

JavaSource/org/unitime/timetable/gwt/client/sectioning/AdvisorCourseRequestsPage.java

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1383,7 +1383,11 @@ protected void fillInStudentRequests() {
13831383
new WebTable.Cell(""),
13841384
new WebTable.NoteCell(note, noteTitle),
13851385
new WebTable.IconCell(RESOURCES.requestSaved(), MESSAGES.requested(free), MESSAGES.reqStatusRegistered()),
1386-
new WebTable.Cell(""),
1386+
(first && request.isCritical() ? new WebTable.IconCell(RESOURCES.requestsCritical(), MESSAGES.descriptionRequestCritical(), "") :
1387+
first && request.isImportant() ? new WebTable.IconCell(RESOURCES.requestsImportant(), MESSAGES.descriptionRequestImportant(), "") :
1388+
first && request.isVital() ? new WebTable.IconCell(RESOURCES.requestsVital(), MESSAGES.descriptionRequestVital(), "") :
1389+
first && request.isLC() ? new WebTable.Cell(MESSAGES.opSetLC(), MESSAGES.descriptionRequestLC()) :
1390+
first && request.isVisitingF2F() ? new WebTable.IconCell(RESOURCES.requestsVisitingF2F(), MESSAGES.descriptionRequestVisitingF2F(), MESSAGES.opSetVisitingF2F()) : new WebTable.Cell("")),
13871391
new WebTable.Cell(""),
13881392
new WebTable.Cell(first && request.hasTimeStamp() ? sDF.format(request.getTimeStamp()) : ""));
13891393
if (priority > 1 && first)
@@ -1505,7 +1509,11 @@ protected void fillInStudentRequests() {
15051509
new WebTable.Cell(""),
15061510
new WebTable.Cell(""),
15071511
new WebTable.IconCell(RESOURCES.requestSaved(), MESSAGES.requested(free), MESSAGES.reqStatusRegistered()),
1508-
new WebTable.Cell(""),
1512+
(first && request.isCritical() ? new WebTable.IconCell(RESOURCES.requestsCritical(), MESSAGES.descriptionRequestCritical(), "") :
1513+
first && request.isImportant() ? new WebTable.IconCell(RESOURCES.requestsImportant(), MESSAGES.descriptionRequestImportant(), "") :
1514+
first && request.isVital() ? new WebTable.IconCell(RESOURCES.requestsVital(), MESSAGES.descriptionRequestVital(), "") :
1515+
first && request.isLC() ? new WebTable.Cell(MESSAGES.opSetLC(), MESSAGES.descriptionRequestLC()) :
1516+
first && request.isVisitingF2F() ? new WebTable.IconCell(RESOURCES.requestsVisitingF2F(), MESSAGES.descriptionRequestVisitingF2F(), MESSAGES.opSetVisitingF2F()) : new WebTable.Cell("")),
15091517
new WebTable.Cell(""),
15101518
new WebTable.Cell(first && request.hasTimeStamp() ? sDF.format(request.getTimeStamp()) : ""));
15111519
if (first)

JavaSource/org/unitime/timetable/gwt/client/sectioning/StudentSchedule.java

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -801,7 +801,12 @@ protected void fillInRequests() {
801801
new WebTable.Cell(""),
802802
new WebTable.NoteCell(note, noteTitle),
803803
new WebTable.IconCell(RESOURCES.requestSaved(), MESSAGES.requested(free), MESSAGES.reqStatusRegistered()),
804-
new WebTable.Cell(""),
804+
first && request.isCritical() ? new WebTable.IconCell(RESOURCES.requestsCritical(), MESSAGES.descriptionRequestCritical(), MESSAGES.opSetCritical()) :
805+
first && request.isImportant() ? new WebTable.IconCell(RESOURCES.requestsImportant(), MESSAGES.descriptionRequestImportant(), MESSAGES.opSetImportant()) :
806+
first && request.isVital() ? new WebTable.IconCell(RESOURCES.requestsVital(), MESSAGES.descriptionRequestVital(), MESSAGES.opSetVital()) :
807+
first && request.isLC() ? new WebTable.IconCell(RESOURCES.requestsLC(), MESSAGES.descriptionRequestLC(), MESSAGES.opSetLC()) :
808+
first && request.isVisitingF2F() ? new WebTable.IconCell(RESOURCES.requestsVisitingF2F(), MESSAGES.descriptionRequestVisitingF2F(), MESSAGES.opSetVisitingF2F()) :
809+
new WebTable.Cell(""),
805810
new WebTable.Cell(""),
806811
new WebTable.Cell(first && request.hasTimeStamp() ? sDF.format(request.getTimeStamp()) : ""));
807812
if (priority > 1 && first)
@@ -924,7 +929,11 @@ protected void fillInRequests() {
924929
new WebTable.Cell(""),
925930
new WebTable.Cell(""),
926931
new WebTable.IconCell(RESOURCES.requestSaved(), MESSAGES.requested(free), MESSAGES.reqStatusRegistered()),
927-
new WebTable.Cell(""),
932+
(first && request.isCritical() ? new WebTable.IconCell(RESOURCES.requestsCritical(), MESSAGES.descriptionRequestCritical(), MESSAGES.opSetCritical()) :
933+
first && request.isImportant() ? new WebTable.IconCell(RESOURCES.requestsImportant(), MESSAGES.descriptionRequestImportant(), MESSAGES.opSetImportant()) :
934+
first && request.isVital() ? new WebTable.IconCell(RESOURCES.requestsVital(), MESSAGES.descriptionRequestVital(), MESSAGES.opSetVital()) :
935+
first && request.isLC() ? new WebTable.IconCell(RESOURCES.requestsLC(), MESSAGES.descriptionRequestLC(), MESSAGES.opSetLC()) :
936+
first && request.isVisitingF2F() ? new WebTable.IconCell(RESOURCES.requestsVisitingF2F(), MESSAGES.descriptionRequestVisitingF2F(), MESSAGES.opSetVisitingF2F()) : new WebTable.Cell("")),
928937
new WebTable.Cell(""),
929938
new WebTable.Cell(first && request.hasTimeStamp() ? sDF.format(request.getTimeStamp()) : ""));
930939
if (first)

JavaSource/org/unitime/timetable/onlinesectioning/OnlineSectioningHelper.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -776,10 +776,10 @@ public static OnlineSectioningLog.Request.Builder toProto(XRequest r) {
776776
request.setWaitlistedTimeStamp(cr.getWaitListedTimeStamp().getTime());
777777
request.setWaitList(cr.isWaitlist());
778778
request.setNoSubs(cr.isNoSub());
779-
request.setCritical(cr.getCritical() == CourseDemand.Critical.CRITICAL.ordinal());
780-
request.setImportant(cr.getCritical() == CourseDemand.Critical.IMPORTANT.ordinal());
781-
request.setVital(cr.getCritical() == CourseDemand.Critical.VITAL.ordinal());
782779
}
780+
request.setCritical(r.getCritical() == CourseDemand.Critical.CRITICAL.ordinal());
781+
request.setImportant(r.getCritical() == CourseDemand.Critical.IMPORTANT.ordinal());
782+
request.setVital(r.getCritical() == CourseDemand.Critical.VITAL.ordinal());
783783
return request;
784784
}
785785

JavaSource/org/unitime/timetable/onlinesectioning/basic/GenerateSectioningReport.java

Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -374,9 +374,10 @@ else if (noSubStates.contains(status))
374374
for (XRequest r: student.getRequests()) {
375375
if (r instanceof XFreeTimeRequest) {
376376
XFreeTimeRequest ft = (XFreeTimeRequest)r;
377-
new FreeTimeRequest(r.getRequestId(), r.getPriority(), r.isAlternative(), clonnedStudent,
377+
FreeTimeRequest ftr = new FreeTimeRequest(r.getRequestId(), r.getPriority(), r.isAlternative(), clonnedStudent,
378378
new TimeLocation(ft.getTime().getDays(), ft.getTime().getSlot(), ft.getTime().getLength(), 0, 0.0,
379379
-1l, "Free Time", server.getAcademicSession().getFreeTimePattern(), 0));
380+
ftr.setRequestPriority(r.getRequestPriority());
380381
} else {
381382
XCourseRequest cr = (XCourseRequest)r;
382383
List<Course> req = new ArrayList<Course>();
@@ -386,18 +387,7 @@ else if (noSubStates.contains(status))
386387
}
387388
if (!req.isEmpty()) {
388389
CourseRequest clonnedRequest = new CourseRequest(r.getRequestId(), r.getPriority(), r.isAlternative(), clonnedStudent, req, cr.isWaitListOrNoSub(wl), cr.getTimeStamp() == null ? null : cr.getTimeStamp().getTime());
389-
if (cr.isCritical()) {
390-
if (cr.getCritical() == CourseDemand.Critical.CRITICAL.ordinal())
391-
clonnedRequest.setRequestPriority(RequestPriority.Critical);
392-
else if (cr.getCritical() == CourseDemand.Critical.IMPORTANT.ordinal())
393-
clonnedRequest.setRequestPriority(RequestPriority.Important);
394-
else if (cr.getCritical() == CourseDemand.Critical.VITAL.ordinal())
395-
clonnedRequest.setRequestPriority(RequestPriority.Vital);
396-
else if (cr.getCritical() == CourseDemand.Critical.LC.ordinal())
397-
clonnedRequest.setRequestPriority(RequestPriority.LC);
398-
else if (cr.getCritical() == CourseDemand.Critical.VISITING_F2F.ordinal())
399-
clonnedRequest.setRequestPriority(RequestPriority.VisitingF2F);
400-
}
390+
clonnedRequest.setRequestPriority(cr.getRequestPriority());
401391
cr.fillChoicesIn(clonnedRequest);
402392
XEnrollment enrollment = cr.getEnrollment();
403393
if (enrollment != null) {

JavaSource/org/unitime/timetable/onlinesectioning/basic/GetAssignment.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -763,6 +763,8 @@ public int compare(Enrollment o1, Enrollment o2) {
763763
for (Request q: enrl.getStudent().getRequests()) {
764764
if (q.equals(enrl.getRequest())) continue;
765765
Enrollment x = assignment.getValue(q);
766+
if (x == null && q instanceof FreeTimeRequest && q.getPriority() < request.getPriority())
767+
x = ((FreeTimeRequest)q).createEnrollment();
766768
if (x == null || x.getAssignments() == null || x.getAssignments().isEmpty()) continue;
767769
for (Iterator<SctAssignment> i = x.getAssignments().iterator(); i.hasNext();) {
768770
SctAssignment a = i.next();
@@ -1169,6 +1171,7 @@ else if (status == org.unitime.timetable.model.CourseRequest.CourseRequestOverri
11691171
lastRequest = r;
11701172
lastRequestPriority = cd.getPriority();
11711173
rc.setStatus(RequestedCourseStatus.SAVED);
1174+
r.setCritical(cd.getCritical());
11721175
}
11731176
} else if (cd instanceof XCourseRequest) {
11741177
r = new CourseRequestInterface.Request();

JavaSource/org/unitime/timetable/onlinesectioning/basic/GetRequest.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,7 @@ else if (status == org.unitime.timetable.model.CourseRequest.CourseRequestOverri
229229
request.getCourses().add(r);
230230
lastRequest = r;
231231
lastRequestPriority = cd.getPriority();
232+
r.setCritical(cd.getCritical());
232233
rc.setStatus(RequestedCourseStatus.SAVED);
233234
}
234235
} else if (cd instanceof XCourseRequest) {

JavaSource/org/unitime/timetable/onlinesectioning/model/XCourseRequest.java

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,6 @@ public class XCourseRequest extends XRequest {
8080
private Map<XCourseId, List<XPreference>> iPreferences = null;
8181
private String iMessage = null;
8282
private Map<XCourseId, XOverride> iOverrides = null;
83-
private int iCritical = 0;
8483
private Date iWaitListedTimeStamp = null;
8584
private XCourseId iWaitListSwapWithCourseOffering = null;
8685

@@ -153,7 +152,6 @@ public int compare(CourseRequest r1, CourseRequest r2) {
153152
}
154153
iWaitlist = (demand.isWaitlist() != null && demand.isWaitlist());
155154
iNoSub = (demand.isNoSub() != null && demand.isNoSub().booleanValue());
156-
iCritical = demand.getEffectiveCritical().ordinal();
157155
iTimeStamp = (demand.getTimestamp() == null ? new Date() : demand.getTimestamp());
158156
iWaitListedTimeStamp = demand.getWaitlistedTimeStamp();
159157
for (CourseRequest cr: crs) {
@@ -186,7 +184,6 @@ public XCourseRequest(Student student, CourseOffering course, int priority, Onli
186184
iCourseIds.add(new XCourseId(course));
187185
iWaitlist = false;
188186
iNoSub = false;
189-
iCritical = 0;
190187
if (classes != null && !classes.isEmpty())
191188
iEnrollment = new XEnrollment(student, course, helper, classes);
192189
if (iEnrollment != null)
@@ -215,7 +212,6 @@ public XCourseRequest(Student student, XCourseId course, int priority, XEnrollme
215212
iCourseIds.add(course);
216213
iWaitlist = false;
217214
iNoSub = false;
218-
iCritical = 0;
219215
iEnrollment = enrollment;
220216
if (iEnrollment != null)
221217
iTimeStamp = iEnrollment.getTimeStamp();
@@ -232,7 +228,6 @@ public XCourseRequest(XStudent student, XCourseId course, RequestedCourse rc) {
232228
iCourseIds.add(course);
233229
iWaitlist = false;
234230
iNoSub = false;
235-
iCritical = 0;
236231
iTimeStamp = new Date();
237232
if (rc != null) {
238233
List<XPreference> prefs = new ArrayList<XPreference>();
@@ -254,7 +249,6 @@ public XCourseRequest(XCourseRequest request, XEnrollment enrollment) {
254249
iCourseIds.addAll(request.getCourseIds());
255250
iWaitlist = request.isWaitlist();
256251
iNoSub = request.isNoSub();
257-
iCritical = request.getCritical();
258252
iTimeStamp = request.getTimeStamp();
259253
iWaitListedTimeStamp = request.getWaitListedTimeStamp();
260254
iEnrollment = enrollment;
@@ -275,7 +269,6 @@ public XCourseRequest(org.cpsolver.studentsct.model.CourseRequest request, Enrol
275269
iCourseIds.add(new XCourseId(course));
276270
iWaitlist = request.isWaitlist();
277271
iNoSub = request.isWaitlist();
278-
iCritical = CourseDemand.Critical.fromRequestPriority(request.getRequestPriority()).ordinal();
279272
iTimeStamp = request.getTimeStamp() == null ? null : new Date(request.getTimeStamp());
280273
iWaitListedTimeStamp = (request.isWaitlist() ? new Date() : null);
281274
iEnrollment = enrollment == null ? null : new XEnrollment(enrollment);
@@ -441,13 +434,6 @@ public boolean isWaitListOrNoSub(WaitListMode mode, Set<Long> advisorWaitListedC
441434
}
442435
return false;
443436
}
444-
445-
public int getCritical() {
446-
return iCritical;
447-
}
448-
public boolean isCritical() {
449-
return iCritical > 0 && iCritical != 5;
450-
}
451437

452438
/**
453439
* Time stamp of the request
@@ -472,8 +458,6 @@ public void setWaitListedTimeStamp(Date ts) {
472458

473459
public void setNoSub(boolean noSub) { iNoSub = noSub; }
474460

475-
public void setCritical(int critical) { iCritical = critical; }
476-
477461
public boolean hasSectionWaitlist(XCourseId courseId) {
478462
List<XWaitListedSection> sections = getSectionWaitlist(courseId);
479463
return sections != null && !sections.isEmpty();
@@ -795,7 +779,6 @@ public void readExternal(ObjectInput in) throws IOException, ClassNotFoundExcept
795779
}
796780
}
797781

798-
iCritical = in.readInt();
799782
iWaitListSwapWithCourseOffering = null;
800783
if (in.readBoolean())
801784
iWaitListSwapWithCourseOffering = new XCourseId(in);
@@ -861,7 +844,6 @@ public void writeExternal(ObjectOutput out) throws IOException {
861844
entry.getValue().writeExternal(out);
862845
}
863846

864-
out.writeInt(iCritical);
865847
out.writeBoolean(iWaitListSwapWithCourseOffering != null);
866848
if (iWaitListSwapWithCourseOffering != null)
867849
iWaitListSwapWithCourseOffering.writeExternal(out);

JavaSource/org/unitime/timetable/onlinesectioning/model/XRequest.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727

2828

2929
import org.cpsolver.studentsct.model.Request;
30+
import org.cpsolver.studentsct.model.Request.RequestPriority;
3031
import org.unitime.timetable.model.CourseDemand;
3132

3233
/**
@@ -38,6 +39,7 @@ public abstract class XRequest implements Serializable, Comparable<XRequest>, Ex
3839
protected int iPriority = 0;
3940
protected boolean iAlternative = false;
4041
protected Long iStudentId;
42+
protected int iCritical = 0;
4143

4244
public XRequest() {}
4345

@@ -46,20 +48,23 @@ public XRequest(CourseDemand demand) {
4648
iPriority = demand.getPriority();
4749
iAlternative = demand.isAlternative();
4850
iStudentId = demand.getStudent().getUniqueId();
51+
iCritical = demand.getEffectiveCritical().ordinal();
4952
}
5053

5154
public XRequest(Request request) {
5255
iRequestId = request.getId();
5356
iPriority = request.getPriority();
5457
iAlternative = request.isAlternative();
5558
iStudentId = request.getStudent().getId();
59+
iCritical = CourseDemand.Critical.fromRequestPriority(request.getRequestPriority()).ordinal();
5660
}
5761

5862
public XRequest(XRequest request) {
5963
iRequestId = request.getRequestId();
6064
iPriority = request.getPriority();
6165
iAlternative = request.isAlternative();
6266
iStudentId = request.getStudentId();
67+
iCritical = request.getCritical();
6368
}
6469

6570
/** Request id */
@@ -83,6 +88,18 @@ public void setAlternative(boolean alt) {
8388
public void setPriority(int priority) {
8489
iPriority = priority;
8590
}
91+
92+
public void setCritical(int critical) { iCritical = critical; }
93+
94+
public int getCritical() {
95+
return iCritical;
96+
}
97+
public boolean isCritical() {
98+
return iCritical > 0 && iCritical != 5;
99+
}
100+
public RequestPriority getRequestPriority() {
101+
return CourseDemand.Critical.values()[iCritical].toRequestPriority();
102+
}
86103

87104
/** Student to which this request belongs */
88105
public Long getStudentId() { return iStudentId; }
@@ -114,6 +131,7 @@ public void readExternal(ObjectInput in) throws IOException, ClassNotFoundExcept
114131
iPriority = in.readInt();
115132
iAlternative = in.readBoolean();
116133
iStudentId = in.readLong();
134+
iCritical = in.readInt();
117135
}
118136

119137
@Override
@@ -122,5 +140,6 @@ public void writeExternal(ObjectOutput out) throws IOException {
122140
out.writeInt(iPriority);
123141
out.writeBoolean(iAlternative);
124142
out.writeLong(iStudentId);
143+
out.writeInt(iCritical);
125144
}
126145
}

JavaSource/org/unitime/timetable/onlinesectioning/solver/SectioningRequest.java

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -125,18 +125,7 @@ public SectioningRequest(XOffering offering, XCourseRequest request, XCourseId c
125125
if (action != null)
126126
action.addOptionBuilder().setKey("Student Priority").setValue(iStudentPriority.name());
127127

128-
if (request.isCritical()) {
129-
if (request.getCritical() == CourseDemand.Critical.CRITICAL.ordinal())
130-
iRequestPriority = RequestPriority.Critical;
131-
else if (request.getCritical() == CourseDemand.Critical.IMPORTANT.ordinal())
132-
iRequestPriority = RequestPriority.Important;
133-
else if (request.getCritical() == CourseDemand.Critical.VITAL.ordinal())
134-
iRequestPriority = RequestPriority.Vital;
135-
else if (request.getCritical() == CourseDemand.Critical.LC.ordinal())
136-
iRequestPriority = RequestPriority.LC;
137-
else if (request.getCritical() == CourseDemand.Critical.VISITING_F2F.ordinal())
138-
iRequestPriority = RequestPriority.VisitingF2F;
139-
}
128+
iRequestPriority = request.getRequestPriority();
140129
if (action != null)
141130
action.addOptionBuilder().setKey("Request Priority").setValue(iRequestPriority.name());
142131

JavaSource/org/unitime/timetable/reports/studentsct/UnasignedCourseRequests.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -526,6 +526,8 @@ public int compare(Enrollment o1, Enrollment o2) {
526526
for (Request q: enrl.getStudent().getRequests()) {
527527
if (q.equals(request)) continue;
528528
Enrollment x = assignment.getValue(q);
529+
if (x == null && q instanceof FreeTimeRequest && q.getPriority() < request.getPriority())
530+
x = ((FreeTimeRequest)q).createEnrollment();
529531
if (x == null || x.getAssignments() == null || x.getAssignments().isEmpty()) continue;
530532
for (Iterator<SctAssignment> i = x.getAssignments().iterator(); i.hasNext();) {
531533
SctAssignment a = i.next();
@@ -603,9 +605,9 @@ public int compare(Enrollment o1, Enrollment o2) {
603605
if (i.hasNext()) ov += ",";
604606
}
605607
ts.add(ov);
606-
if (cr.getRequestPriority() != null && (conflictPriority == null || conflictPriority.ordinal() > cr.getRequestPriority().ordinal()))
607-
conflictPriority = cr.getRequestPriority();
608608
}
609+
if (q.getRequest().getRequestPriority() != null && (conflictPriority == null || conflictPriority.ordinal() > q.getRequest().getRequestPriority().ordinal()))
610+
conflictPriority = q.getRequest().getRequestPriority();
609611
}
610612
String message = "";
611613
for (Iterator<String> i = ts.iterator(); i.hasNext();) {

0 commit comments

Comments
 (0)