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.
This commit is contained in:
2026-01-13 09:36:46 -05:00
parent 1601610226
commit e2a5767b04
@@ -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<Team> 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];
var nextSlotTeamsList = nextSlot.Teams.ToList();
var nextSlotTeamIds = nextSlotTeamsList.Select(t => t.Id).ToHashSet();
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))
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();
// Recalculate overlaps and unscheduled students for the next slot
nextSlot.StudentOverlaps = TeamSchedulerSolution.GetStudentTeamOverlaps(nextSlot.Teams);
nextSlot.UnscheduledStudents = TeamSchedulerSolution.GetStudentsNotInTimSlot(nextSlot.Teams, allStudents);
foreach (var team in teamsToExtend)
{
if (!previousSlotTeamIds.Contains(team.Id))
{
previousSlotTeamsList.Add(team);
previousSlotTeamIds.Add(team.Id);
}
}
previousSlot.Teams = previousSlotTeamsList.ToArray();
previousSlot.StudentOverlaps = TeamSchedulerSolution.GetStudentTeamOverlaps(previousSlot.Teams);
previousSlot.UnscheduledStudents = TeamSchedulerSolution.GetStudentsNotInTimSlot(previousSlot.Teams, allStudents);
}
}
}