Skip to content

Commit 4b2c5c0

Browse files
Merge pull request #120 from RandomCyberCoder/solver_revision_preschedule
Solver revision preschedule + bug fixes
2 parents 37dd411 + 0a22699 commit 4b2c5c0

18 files changed

Lines changed: 494 additions & 143 deletions
Lines changed: 81 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -1,71 +1,82 @@
11
{
2-
"LastName, FirstName": [
3-
{
4-
"start": "10:00AM",
5-
"day": "MONDAY",
6-
"end": "12:00PM"
7-
},
8-
{
9-
"start": "10:00AM",
10-
"day": "WEDNESDAY",
11-
"end": "12:00PM"
12-
},
13-
{
14-
"start": "10:00AM",
15-
"day": "FRIDAY",
16-
"end": "12:00PM"
17-
},
18-
{
19-
"start": "4:00PM",
20-
"day": "MONDAY",
21-
"end": "6:00PM"
22-
},
23-
{
24-
"start": "4:00PM",
25-
"day": "WEDNESDAY",
26-
"end": "6:00PM"
27-
},
28-
{
29-
"start": "4:00PM",
30-
"day": "FRIDAY",
31-
"end": "6:00PM"
32-
},
33-
{
34-
"start": "12:00PM",
35-
"day": "MONDAY",
36-
"end": "2:00PM"
37-
},
38-
{
39-
"start": "12:00PM",
40-
"day": "WEDNESDAY",
41-
"end": "2:00PM"
42-
},
43-
{
44-
"start": "12:00PM",
45-
"day": "FRIDAY",
46-
"end": "2:00PM"
47-
}
48-
],
49-
"LastName2, FirstName2": [
50-
{
51-
"start": "9:00AM",
52-
"day": "MONDAY",
53-
"end": "10:30AM"
54-
},
55-
{
56-
"start": "9:00AM",
57-
"day": "WEDNESDAY",
58-
"end": "10:30AM"
59-
},
60-
{
61-
"start": "11:00AM",
62-
"day": "MONDAY",
63-
"end": "1:00PM"
64-
},
65-
{
66-
"start": "11:00AM",
67-
"day": "WEDNESDAY",
68-
"end": "1:00PM"
69-
}
70-
]
71-
}
2+
"teachers": {
3+
"LastName, FirstName": [
4+
{
5+
"start": "10:00AM",
6+
"day": "MONDAY",
7+
"end": "12:00PM"
8+
},
9+
{
10+
"start": "10:00AM",
11+
"day": "WEDNESDAY",
12+
"end": "12:00PM"
13+
},
14+
{
15+
"start": "10:00AM",
16+
"day": "FRIDAY",
17+
"end": "12:00PM"
18+
},
19+
{
20+
"start": "4:00PM",
21+
"day": "MONDAY",
22+
"end": "6:00PM"
23+
},
24+
{
25+
"start": "4:00PM",
26+
"day": "WEDNESDAY",
27+
"end": "6:00PM"
28+
},
29+
{
30+
"start": "4:00PM",
31+
"day": "FRIDAY",
32+
"end": "6:00PM"
33+
},
34+
{
35+
"start": "12:00PM",
36+
"day": "MONDAY",
37+
"end": "2:00PM"
38+
},
39+
{
40+
"start": "12:00PM",
41+
"day": "WEDNESDAY",
42+
"end": "2:00PM"
43+
},
44+
{
45+
"start": "12:00PM",
46+
"day": "FRIDAY",
47+
"end": "2:00PM"
48+
}
49+
],
50+
"LastName2, FirstName2": [
51+
{
52+
"start": "9:00AM",
53+
"day": "MONDAY",
54+
"end": "10:30AM"
55+
},
56+
{
57+
"start": "9:00AM",
58+
"day": "WEDNESDAY",
59+
"end": "10:30AM"
60+
},
61+
{
62+
"start": "11:00AM",
63+
"day": "MONDAY",
64+
"end": "1:00PM"
65+
},
66+
{
67+
"start": "11:00AM",
68+
"day": "WEDNESDAY",
69+
"end": "1:00PM"
70+
}
71+
]
72+
},
73+
"rooms": {
74+
"Room 101": [
75+
{
76+
"start": "8:00AM",
77+
"day": "TUESDAY",
78+
"end": "9:30AM"
79+
}
80+
]
81+
}
82+
}

java/hello-world/src/main/java/org/acme/schooltimetabling/DefaultTimes/DefaultTime.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package org.acme.schooltimetabling.DefaultTimes;
1+
package org.acme.schooltimetabling.defaultTimes;
22

33
import java.util.BitSet;
44

java/hello-world/src/main/java/org/acme/schooltimetabling/DefaultTimes/DefaultTimeAll.java

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package org.acme.schooltimetabling.DefaultTimes;
1+
package org.acme.schooltimetabling.defaultTimes;
22

33
import org.acme.schooltimetabling.constants.Constants;
44
import org.acme.schooltimetabling.constants.Days;
@@ -26,18 +26,28 @@ public class DefaultTimeAll implements DefaultTime{
2626
final DateTimeFormatter FORMATTER = Constants.TIME_FORMATTER;
2727
EnumSet<Days> defaultDays = EnumSet.allOf(Days.class);
2828

29-
List<LocalTime> acceptableTimes = List.of(
29+
//I'm trying to set preferred times outside of prime time to help solver push more lectures into this time.
30+
List<LocalTime> preferredTimes = List.of(
3031
LocalTime.parse("7:00AM", FORMATTER),
3132
LocalTime.parse("8:00AM", FORMATTER),
33+
LocalTime.parse("3:00PM", FORMATTER),
34+
LocalTime.parse("4:00PM", FORMATTER),
35+
LocalTime.parse("5:00PM", FORMATTER)
36+
37+
);
38+
39+
for(LocalTime localTime : preferredTimes){
40+
INSTANCE.preference.or(BitSetHelper.timeSlotBitSet(localTime, NUM_BLOCKS_FULL_HOUR, defaultDays));
41+
}
42+
43+
44+
List<LocalTime> acceptableTimes = List.of(
3245
LocalTime.parse("9:00AM", FORMATTER),
3346
LocalTime.parse("10:00AM", FORMATTER),
3447
LocalTime.parse("11:00AM", FORMATTER),
3548
LocalTime.parse("12:00PM", FORMATTER),
3649
LocalTime.parse("1:00PM", FORMATTER),
37-
LocalTime.parse("2:00PM", FORMATTER),
38-
LocalTime.parse("3:00PM", FORMATTER),
39-
LocalTime.parse("4:00PM", FORMATTER),
40-
LocalTime.parse("5:00PM", FORMATTER)
50+
LocalTime.parse("2:00PM", FORMATTER)
4151
);
4252
for(LocalTime localTime : acceptableTimes) {
4353
INSTANCE.acceptable.or(BitSetHelper.timeSlotBitSet(localTime, NUM_BLOCKS_FULL_HOUR, defaultDays));

java/hello-world/src/main/java/org/acme/schooltimetabling/DefaultTimes/DefaultTimeEvening.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package org.acme.schooltimetabling.DefaultTimes;
1+
package org.acme.schooltimetabling.defaultTimes;
22

33
import org.acme.schooltimetabling.constants.Constants;
44
import org.acme.schooltimetabling.constants.Days;

java/hello-world/src/main/java/org/acme/schooltimetabling/DefaultTimes/DefaultTimeMorning.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package org.acme.schooltimetabling.DefaultTimes;
1+
package org.acme.schooltimetabling.defaultTimes;
22

33
import org.acme.schooltimetabling.constants.Constants;
44
import org.acme.schooltimetabling.constants.Days;

java/hello-world/src/main/java/org/acme/schooltimetabling/DefaultTimes/DefaultTimeRegistry.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package org.acme.schooltimetabling.DefaultTimes;
1+
package org.acme.schooltimetabling.defaultTimes;
22

33
import java.util.List;
44
import java.util.Random;

java/hello-world/src/main/java/org/acme/schooltimetabling/domain/Room.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
import ai.timefold.solver.core.api.domain.lookup.PlanningId;
44

5+
import java.util.BitSet;
6+
57
public class Room {
68

79
@PlanningId
@@ -12,18 +14,25 @@ public class Room {
1214
* of what is needed for scheduling. Anything else is for debugging
1315
* but even that could be found in the hashmaps that have been created*/
1416
private int ID;
17+
18+
private BitSet prescheduled;
19+
20+
public static boolean hasPrescheduled = false;
21+
1522
public Room() {
1623
}
1724

1825
public Room(String id, String name) {
1926
this.id = id;
2027
this.name = name;
28+
this.prescheduled = new BitSet();
2129
}
2230

2331
public Room(String id, String name, int ID){
2432
this.id = id;
2533
this.name = name;
2634
this.ID = ID;
35+
this.prescheduled = new BitSet();
2736
}
2837

2938
@Override
@@ -46,4 +55,12 @@ public String getName() {
4655
public int getID() {
4756
return ID;
4857
}
58+
59+
public BitSet getPrescheduled(){
60+
return (BitSet) prescheduled.clone();
61+
}
62+
63+
public void prescheduleUpdate(BitSet addBitset){
64+
if(addBitset != null) this.prescheduled.or(addBitset);
65+
}
4966
}

java/hello-world/src/main/java/org/acme/schooltimetabling/domain/teacher/Faculty.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,14 +35,14 @@ public class Faculty extends Teacher{
3535
final int NUM_BLOCKS_FULL_HOUR = 2;
3636
List<LocalTime> facultyTimes;
3737
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("h:mma");
38-
EnumSet<Days> facultyDays = EnumSet.of(Days.MONDAY, Days.WEDNESDAY, Days.FRIDAY);
38+
EnumSet<Days> facultyDays;
3939

4040
try{
4141
//set special bits for testing
4242
if(Constants.TESTING){
4343
LocalTime localTime = LocalTime.parse("9:00PM", formatter);
4444
BitSet temp = BitSetHelper.timeSlotBitSet(localTime, NUM_BLOCKS_FULL_HOUR,
45-
EnumSet.of(Days.MONDAY, Days.WEDNESDAY, Days.FRIDAY));
45+
EnumSet.of(Days.MONDAY, Days.TUESDAY, Days.WEDNESDAY, Days.THURSDAY));
4646
FACULTY_CONFLICT.or(temp);
4747
}
4848
/*CSC faculty times*/

java/hello-world/src/main/java/org/acme/schooltimetabling/helperClasses/BitSetHelper.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package org.acme.schooltimetabling.helperClasses;
22
import org.acme.schooltimetabling.constants.Constants;
33
import org.acme.schooltimetabling.constants.Days;
4+
import org.acme.schooltimetabling.helperClasses.PrescheduleObject.PrescheduledWindow;
45
import org.slf4j.Logger;
56
import org.slf4j.LoggerFactory;
67

@@ -212,4 +213,18 @@ public static BitSet timeJsonToBs(Map<String, String> time) {
212213
bitSet.set(dayOffset + startBlock, dayOffset + endBlock);
213214
return bitSet;
214215
}
216+
217+
public static BitSet timeJsonToBs(PrescheduledWindow time) {
218+
if (time == null) {
219+
throw new IllegalArgumentException("Time window must not be null");
220+
}
221+
222+
Map<String, String> mappedTime = Map.of(
223+
"day", time.getDay(),
224+
"start", time.getStart(),
225+
"end", time.getEnd()
226+
);
227+
228+
return timeJsonToBs(mappedTime);
229+
}
215230
}

java/hello-world/src/main/java/org/acme/schooltimetabling/helperClasses/Generators/LessonGenerator.java

Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
package org.acme.schooltimetabling.helperClasses.Generators;
22

3-
import org.acme.schooltimetabling.DefaultTimes.DefaultTime;
4-
import org.acme.schooltimetabling.DefaultTimes.DefaultTimeRegistry;
3+
import org.acme.schooltimetabling.defaultTimes.DefaultTime;
4+
import org.acme.schooltimetabling.defaultTimes.DefaultTimeRegistry;
55
import org.acme.schooltimetabling.constants.Constants;
66
import org.acme.schooltimetabling.constants.Preference;
77
import org.acme.schooltimetabling.domain.lesson.Lesson;
88
import org.acme.schooltimetabling.domain.teacher.Faculty;
99
import org.acme.schooltimetabling.helperClasses.ParseInput;
10+
import org.acme.schooltimetabling.helperClasses.PrescheduleObject;
1011
import org.acme.schooltimetabling.helperClasses.ScheduleConfig;
1112
import org.acme.schooltimetabling.helperClasses.ScheduleFormat;
1213
import org.acme.schooltimetabling.domain.teacher.Teacher;
@@ -21,7 +22,8 @@ public class LessonGenerator extends Generator{
2122
public static boolean OLD_studio_detected = false;
2223
public static boolean proper_studio_detected = false;
2324
private static final Logger LOGGER = LoggerFactory.getLogger(LessonGenerator.class);
24-
private static final Map<String, List<Map<String, String>>> PRESCHED_TIMES = ParseInput.readPrescheduledFile();
25+
private static final PrescheduleObject PRESCHED_TIMES = ScheduleConfig.getPrescheduledFileName() != null ?
26+
ParseInput.readPrescheduledFile() : null;
2527
/**
2628
* Keeps track of the next available section number available for a course
2729
*/
@@ -195,12 +197,12 @@ private static Teacher getTeacher(Map<String, Teacher> teacherHashMap, String te
195197
teacher = noSurveyTeacher(teacherName, defaultTime);
196198

197199
//add prescheduled times if possible
198-
if(PRESCHED_TIMES.containsKey(teacherName)){
200+
if(PRESCHED_TIMES != null && PRESCHED_TIMES.getTeachers().containsKey(teacherName)){
199201
LOGGER.info(String.format("Found a prescheduled time for '%s'. Adding the time to their conflict bitset.",
200202
teacherName));
201203

202204
try {
203-
BitSet addConflict = TeacherGenerator.createPreschedBs(PRESCHED_TIMES.get(teacherName));
205+
BitSet addConflict = TeacherGenerator.createPreschedBs(PRESCHED_TIMES.getTeachers().get(teacherName));
204206
teacher.getAcceptable().andNot(addConflict);
205207
teacher.getPreferences().andNot(addConflict);
206208
teacher.getConflict().or(addConflict);
@@ -327,19 +329,24 @@ private static boolean skipCourse(String modifier, String name, String config){
327329
private static Teacher noSurveyTeacher(String name, DefaultTime defaultTime){
328330
final int LAST_NAME_POS = 0;
329331
String[] nameFragments = name.split(",");
332+
boolean isFaculty = Constants.FACULTY_LAST_NAMES.contains(nameFragments[LAST_NAME_POS]);
330333

331-
if(Constants.FACULTY_LAST_NAMES.contains(nameFragments[LAST_NAME_POS])){
332-
LOGGER.info(String.format("Found teacher '%s' to be a faculty member. Promoting Teacher obj to Faculty"
334+
if(isFaculty){
335+
LOGGER.info(String.format("Found teacher '%s' to be a faculty member. Promoting to Faculty"
333336
, name));
334-
return new Faculty(TeacherGenerator.getNextTeacherID(), name, new BitSet(), new BitSet(), new BitSet(),
337+
return new Faculty(TeacherGenerator.getNextTeacherID(), name,
338+
defaultTime.getPreference(),
339+
defaultTime.getAcceptable(),
340+
defaultTime.getConflict(),
341+
Preference.NEUTRAL);
342+
}
343+
else{
344+
return new Teacher(TeacherGenerator.getNextTeacherID(), name,
345+
defaultTime.getPreference(),
346+
defaultTime.getAcceptable(),
347+
defaultTime.getConflict(),
335348
Preference.NEUTRAL);
336349
}
337-
338-
return new Teacher(TeacherGenerator.getNextTeacherID(), name,
339-
defaultTime.getPreference(),
340-
defaultTime.getAcceptable(),
341-
defaultTime.getConflict(),
342-
Preference.NEUTRAL);
343350
}
344351

345352

0 commit comments

Comments
 (0)