From e2a5767b04cf8943731063bbcfa3d10cba5e05b6 Mon Sep 17 00:00:00 2001 From: James Kolpack Date: Tue, 13 Jan 2026 09:36:46 -0500 Subject: [PATCH] Refactor team extension logic in MeetingSchedule component for improved scheduling This commit introduces a refactor of the ExtendTeamsInSolution method in the Index.razor component to enhance the handling of extended teams within the scheduling solution. The logic now includes extending teams both forward and backward in the time slots, improving the overall scheduling accuracy. Additionally, a TODO comment has been added to indicate the need to move this logic into the Core.Calculation.TeamScheduler for better integration with the constraint programming model. These changes contribute to a more robust and maintainable scheduling system. --- .../Features/MeetingSchedule/Index.razor | 61 ++++++++++++------- 1 file changed, 38 insertions(+), 23 deletions(-) diff --git a/WebApp/Components/Features/MeetingSchedule/Index.razor b/WebApp/Components/Features/MeetingSchedule/Index.razor index 57daf69..fe1ad39 100644 --- a/WebApp/Components/Features/MeetingSchedule/Index.razor +++ b/WebApp/Components/Features/MeetingSchedule/Index.razor @@ -377,6 +377,8 @@ _solutionData.ReloadServerData(); } + // TODO: Move team extension logic into Core.Calculation.TeamScheduler to handle extended teams + // as part of the constraint programming model rather than post-processing private void ExtendTeamsInSolution(TeamSchedulerSolution solution, IEnumerable extendedTeams, Student[] allStudents) { if (solution.TimeSlots == null || !solution.TimeSlots.Any()) @@ -388,7 +390,7 @@ var extendedTeamIds = extendedTeamsList.Select(t => t.Id).ToHashSet(); - // Find which time slot each extended team is in + // Find which time slot each extended team is in and extend both forward and backward for (int slotIndex = 0; slotIndex < solution.TimeSlots.Length; slotIndex++) { var currentSlot = solution.TimeSlots[slotIndex]; @@ -397,34 +399,47 @@ if (!teamsToExtend.Any()) continue; - // Check if there's a next time slot - if (slotIndex + 1 >= solution.TimeSlots.Length) + // Extend forward: add to next time slot (if exists) + if (slotIndex + 1 < solution.TimeSlots.Length) { - // Cannot extend - this is the last time slot - continue; - } - - var nextSlot = solution.TimeSlots[slotIndex + 1]; - - // Add extended teams to the next time slot - var nextSlotTeamsList = nextSlot.Teams.ToList(); - var nextSlotTeamIds = nextSlotTeamsList.Select(t => t.Id).ToHashSet(); - - foreach (var team in teamsToExtend) - { - if (!nextSlotTeamIds.Contains(team.Id)) + var nextSlot = solution.TimeSlots[slotIndex + 1]; + var nextSlotTeamsList = nextSlot.Teams.ToList(); + var nextSlotTeamIds = nextSlotTeamsList.Select(t => t.Id).ToHashSet(); + + foreach (var team in teamsToExtend) { - nextSlotTeamsList.Add(team); - nextSlotTeamIds.Add(team.Id); + if (!nextSlotTeamIds.Contains(team.Id)) + { + nextSlotTeamsList.Add(team); + nextSlotTeamIds.Add(team.Id); + } } + + nextSlot.Teams = nextSlotTeamsList.ToArray(); + nextSlot.StudentOverlaps = TeamSchedulerSolution.GetStudentTeamOverlaps(nextSlot.Teams); + nextSlot.UnscheduledStudents = TeamSchedulerSolution.GetStudentsNotInTimSlot(nextSlot.Teams, allStudents); } - // Update the next slot with the extended teams - nextSlot.Teams = nextSlotTeamsList.ToArray(); + // Extend backward: add to previous time slot (if exists) + if (slotIndex > 0) + { + var previousSlot = solution.TimeSlots[slotIndex - 1]; + var previousSlotTeamsList = previousSlot.Teams.ToList(); + var previousSlotTeamIds = previousSlotTeamsList.Select(t => t.Id).ToHashSet(); + + foreach (var team in teamsToExtend) + { + if (!previousSlotTeamIds.Contains(team.Id)) + { + previousSlotTeamsList.Add(team); + previousSlotTeamIds.Add(team.Id); + } + } - // Recalculate overlaps and unscheduled students for the next slot - nextSlot.StudentOverlaps = TeamSchedulerSolution.GetStudentTeamOverlaps(nextSlot.Teams); - nextSlot.UnscheduledStudents = TeamSchedulerSolution.GetStudentsNotInTimSlot(nextSlot.Teams, allStudents); + previousSlot.Teams = previousSlotTeamsList.ToArray(); + previousSlot.StudentOverlaps = TeamSchedulerSolution.GetStudentTeamOverlaps(previousSlot.Teams); + previousSlot.UnscheduledStudents = TeamSchedulerSolution.GetStudentsNotInTimSlot(previousSlot.Teams, allStudents); + } } }