From 8cdb0c98970dfdfe7d1562523764dd35a8203033 Mon Sep 17 00:00:00 2001 From: RandomCyberCoder Date: Tue, 5 May 2026 12:26:48 -0700 Subject: [PATCH 1/2] updated example file and code to line up --- .../helperClasses/ScheduleConfig.java | 44 ++++++++++--------- .../resources/constants/config.example.yaml | 2 +- 2 files changed, 24 insertions(+), 22 deletions(-) diff --git a/java/hello-world/src/main/java/org/acme/schooltimetabling/helperClasses/ScheduleConfig.java b/java/hello-world/src/main/java/org/acme/schooltimetabling/helperClasses/ScheduleConfig.java index 5a49831d..2529cefb 100644 --- a/java/hello-world/src/main/java/org/acme/schooltimetabling/helperClasses/ScheduleConfig.java +++ b/java/hello-world/src/main/java/org/acme/schooltimetabling/helperClasses/ScheduleConfig.java @@ -72,34 +72,36 @@ public static void loadConfig(String yamlPath){ Yaml yaml = new Yaml(); HOLDER.scheduleConfig = yaml.loadAs(inputStream, ScheduleConfig.class); - //BitSet setup for times we want to compress into - EnumSet MTWRF = EnumSet.allOf(Days.class); - DateTimeFormatter formatter = DateTimeFormatter.ofPattern("h:mma"); - LocalTime startTime = LocalTime.parse(HOLDER.scheduleConfig.compressStart, formatter); - LocalTime endTime = LocalTime.parse(HOLDER.scheduleConfig.compressEnd, formatter); - //normalize times - startTime = roundToNearestHalfHour(startTime); - endTime = roundToNearestHalfHour(endTime); - if(startTime.isAfter(endTime)){ - LOGGER.error("The start time for the compressed start is after the end time; Exiting program"); - System.exit(1); + if(HOLDER.scheduleConfig.compressStart != null && HOLDER.scheduleConfig.compressEnd != null) {//BitSet setup for times we want to compress into + EnumSet MTWRF = EnumSet.allOf(Days.class); + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("h:mma"); + LocalTime startTime = LocalTime.parse(HOLDER.scheduleConfig.compressStart, formatter); + LocalTime endTime = LocalTime.parse(HOLDER.scheduleConfig.compressEnd, formatter); + //normalize times + startTime = roundToNearestHalfHour(startTime); + endTime = roundToNearestHalfHour(endTime); + if (startTime.isAfter(endTime)) { + LOGGER.error("The start time for the compressed start is after the end time; Exiting program"); + System.exit(1); + } + //get number of 30 minute blocks + long numBlcks = Duration.between(startTime, endTime).toMinutes() / 30; + final int bsSizeRep = 150; + BitSet buildCmprsIn = new BitSet(bsSizeRep); + buildCmprsIn.or(BitSetHelper.timeSlotBitSet(startTime, (int) numBlcks, MTWRF)); + BitSet buildCmprsOut = (BitSet) buildCmprsIn.clone(); + buildCmprsOut.flip(0, bsSizeRep); + + HOLDER.scheduleConfig.cpmrsInBs = buildCmprsIn; + HOLDER.scheduleConfig.cmprsOutBs = buildCmprsOut; } - //get number of 30 minute blocks - long numBlcks = Duration.between(startTime,endTime).toMinutes() / 30; - final int bsSizeRep = 150; - BitSet buildCmprsIn = new BitSet(bsSizeRep); - buildCmprsIn.or(BitSetHelper.timeSlotBitSet(startTime, (int) numBlcks, MTWRF)); - BitSet buildCmprsOut = (BitSet) buildCmprsIn.clone(); - buildCmprsOut.flip(0, bsSizeRep); - - HOLDER.scheduleConfig.cpmrsInBs = buildCmprsIn; - HOLDER.scheduleConfig.cmprsOutBs = buildCmprsOut; } catch (Exception e){ final int PROGRAM_FAILURE = 1; LOGGER.error("Program is terminating. Couldn't read the yaml file"); LOGGER.error(String.format("Program assumes yaml file is located at '%s' int the resources directory", yamlPath)); LOGGER.error(String.format("Related error: %s", e.getMessage())); + e.printStackTrace(); System.exit(PROGRAM_FAILURE); } } diff --git a/java/hello-world/src/main/resources/constants/config.example.yaml b/java/hello-world/src/main/resources/constants/config.example.yaml index 562a9580..9e353f4d 100644 --- a/java/hello-world/src/main/resources/constants/config.example.yaml +++ b/java/hello-world/src/main/resources/constants/config.example.yaml @@ -4,9 +4,9 @@ prevTerm: "2264" seasonTerm: "fall" testing: false useApi: true +aggressiveChoice: "AGGRESSIVE_PENALTY" # ------- Optional ------- # this setting changes how we model the PrimeTime constraint -aggressiveChoice: "AGGRESSIVE_PENALTY" compressStart: "7:00AM" compressEnd: "6:00PM" prescheduledFileName: "PrescheduledTimes_ExampleFile.example.json" \ No newline at end of file From 1bfbe2c40a1c9d17377cc17c6a16d3b555148908 Mon Sep 17 00:00:00 2001 From: RandomCyberCoder Date: Tue, 5 May 2026 12:31:20 -0700 Subject: [PATCH 2/2] constraint level comments for better code understanding --- .../solver/TimetableConstraintProvider.java | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/java/hello-world/src/main/java/org/acme/schooltimetabling/solver/TimetableConstraintProvider.java b/java/hello-world/src/main/java/org/acme/schooltimetabling/solver/TimetableConstraintProvider.java index ea39a7bb..cc69c2c6 100644 --- a/java/hello-world/src/main/java/org/acme/schooltimetabling/solver/TimetableConstraintProvider.java +++ b/java/hello-world/src/main/java/org/acme/schooltimetabling/solver/TimetableConstraintProvider.java @@ -575,6 +575,11 @@ Constraint inPrimeTime(ConstraintFactory constraintFactory){ .asConstraint("Penalizing for being in prime time"); } + + /** + * This constraint is used when we choose the "Aggressive" version of the solver that aims to compress and REWARD + * time that is in the time interval specified in the configuration file + */ Constraint inBestTime(ConstraintFactory constraintFactory){ return constraintFactory.forEach(Lesson.class) .filter(lesson -> lesson.maskInCmprs().cardinality() > 0) @@ -582,6 +587,11 @@ Constraint inBestTime(ConstraintFactory constraintFactory){ .asConstraint("Reward time in preferred time interval"); } + + /** + * This constraint is used when we choose the "Aggressive" version of the solver that aims to compress and PENALIZE + * time that is in the time interval specified in the configuration file + */ Constraint outBestTime(ConstraintFactory constraintFactory){ return constraintFactory.forEach(Lesson.class) .filter(lesson -> lesson.maskOutCmprs().cardinality() > 0)