Refactor TeamScheduler, easier to read and maintain
This commit is contained in:
@@ -2,57 +2,88 @@
|
||||
|
||||
namespace Core.Calculation;
|
||||
|
||||
/// <summary>
|
||||
/// Represents a solution to the team scheduling problem.
|
||||
/// Contains team assignments to time slots and information about student scheduling conflicts.
|
||||
/// </summary>
|
||||
public class TeamSchedulerSolution(
|
||||
Team[][] timeSlots,
|
||||
Student[] students,
|
||||
string status)
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the solver status (e.g., "Optimal", "Feasible", "Infeasible").
|
||||
/// </summary>
|
||||
public string Status { get; } = status;
|
||||
|
||||
public TeamScheduleTimeSlot[] TimeSlots { get; set; }
|
||||
= timeSlots.Select( (teams,i) =>
|
||||
/// <summary>
|
||||
/// Gets the scheduled time slots with team assignments and conflict information.
|
||||
/// </summary>
|
||||
public TeamScheduleTimeSlot[] TimeSlots { get; set; }
|
||||
= timeSlots.Select( (teams,i) =>
|
||||
new TeamScheduleTimeSlot{
|
||||
Name = "Time Slot " + (i + 1),
|
||||
Name = "Time Slot " + (i + 1),
|
||||
Teams = teams,
|
||||
StudentOverlaps = GetStudentTeamOverlaps(teams),
|
||||
StudentOverlaps = GetStudentTeamOverlaps(teams),
|
||||
UnscheduledStudents = GetStudentsNotInTimSlot(teams, students)
|
||||
}
|
||||
).ToArray();
|
||||
|
||||
/// <summary>
|
||||
/// Calculates the total number of student conflicts across all time slots.
|
||||
/// </summary>
|
||||
/// <param name="timeSlots">The scheduled time slots</param>
|
||||
/// <returns>Total count of students with overlapping team meetings</returns>
|
||||
public static int GetStudentTeamOverlapCount(Team[][] timeSlots)
|
||||
{
|
||||
return timeSlots.Sum(GetStudentTeamOverlapCount);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calculates the number of student conflicts in a single time slot.
|
||||
/// </summary>
|
||||
/// <param name="timeSlot">The time slot to analyze</param>
|
||||
/// <returns>Count of students with multiple team meetings in this slot</returns>
|
||||
private static int GetStudentTeamOverlapCount(Team[] timeSlot)
|
||||
{
|
||||
return GetStudentTeamOverlaps(timeSlot).Count();
|
||||
}
|
||||
|
||||
public static IEnumerable<Tuple<Student, IEnumerable<Team>>> GetStudentTeamOverlaps(Team[] timeSlot)
|
||||
/// <summary>
|
||||
/// Identifies students who have multiple team meetings in the same time slot.
|
||||
/// </summary>
|
||||
/// <param name="timeSlot">The time slot to analyze</param>
|
||||
/// <returns>Students and their conflicting teams in this time slot</returns>
|
||||
public static IEnumerable<(Student student, IEnumerable<Team> teams)> GetStudentTeamOverlaps(Team[] timeSlot)
|
||||
{
|
||||
return
|
||||
from s in timeSlot.SelectMany(ts => ts.Students).Distinct()
|
||||
group s by timeSlot.Where(t => t.Students.Contains(s))
|
||||
into gs
|
||||
where gs.Key.Count() > 1
|
||||
select Tuple.Create(gs.First(), gs.Key);
|
||||
select (gs.First(), gs.Key);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Identifies students who have no team meetings in the given time slot.
|
||||
/// </summary>
|
||||
/// <param name="timeSlot">The time slot to analyze</param>
|
||||
/// <param name="students">All students</param>
|
||||
/// <returns>Students not scheduled in this time slot</returns>
|
||||
public static Student[] GetStudentsNotInTimSlot(Team[] timeSlot, Student[] students)
|
||||
{
|
||||
var studentsInTimeSlot = timeSlot.SelectMany(ts => ts.Students).Distinct();
|
||||
return
|
||||
(from allStudent in students
|
||||
where studentsInTimeSlot.FirstOrDefault(e => e.Equals(allStudent)) == null
|
||||
select allStudent
|
||||
).ToArray();
|
||||
var studentsInTimeSlot = timeSlot.SelectMany(ts => ts.Students).Distinct().ToHashSet();
|
||||
return students.Where(s => !studentsInTimeSlot.Contains(s)).ToArray();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the teams a student is on that weren't assigned to any time slot.
|
||||
/// </summary>
|
||||
/// <param name="student">The student to check</param>
|
||||
/// <returns>Teams the student is on that have no scheduled meeting</returns>
|
||||
public Team[] StudentUnassignedTeams(Student student)
|
||||
{
|
||||
var meetingTeams = TimeSlots.SelectMany(t => t.Teams);
|
||||
return
|
||||
student.Teams.Where(e => !meetingTeams.Contains(e)).ToArray();
|
||||
return student.Teams.Where(e => !meetingTeams.Contains(e)).ToArray();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user