using Core.Entities; namespace Core.Calculation; /// /// Represents a solution to the team scheduling problem. /// Contains team assignments to time slots and information about student scheduling conflicts. /// public class TeamSchedulerSolution( Team[][] timeSlots, Student[] students, string status) { /// /// Gets the solver status (e.g., "Optimal", "Feasible", "Infeasible"). /// public string Status { get; } = status; /// /// Gets the scheduled time slots with team assignments and conflict information. /// public TeamScheduleTimeSlot[] TimeSlots { get; set; } = timeSlots.Select( (teams,i) => new TeamScheduleTimeSlot{ Name = "Time Slot " + (i + 1), Teams = teams, StudentOverlaps = GetStudentTeamOverlaps(teams), UnscheduledStudents = GetStudentsNotInTimSlot(teams, students) } ).ToArray(); /// /// Calculates the total number of student conflicts across all time slots. /// /// The scheduled time slots /// Total count of students with overlapping team meetings public static int GetStudentTeamOverlapCount(Team[][] timeSlots) { return timeSlots.Sum(GetStudentTeamOverlapCount); } /// /// Calculates the number of student conflicts in a single time slot. /// /// The time slot to analyze /// Count of students with multiple team meetings in this slot private static int GetStudentTeamOverlapCount(Team[] timeSlot) { return GetStudentTeamOverlaps(timeSlot).Count(); } /// /// Identifies students who have multiple team meetings in the same time slot. /// /// The time slot to analyze /// Students and their conflicting teams in this time slot public static IEnumerable<(Student student, IEnumerable 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 (gs.First(), gs.Key); } /// /// Identifies students who have no team meetings in the given time slot. /// /// The time slot to analyze /// All students /// Students not scheduled in this time slot public static Student[] GetStudentsNotInTimSlot(Team[] timeSlot, Student[] students) { var studentsInTimeSlot = timeSlot.SelectMany(ts => ts.Students).Distinct().ToHashSet(); return students.Where(s => !studentsInTimeSlot.Contains(s)).ToArray(); } /// /// Gets the teams a student is on that weren't assigned to any time slot. /// /// The student to check /// Teams the student is on that have no scheduled meeting public Team[] StudentUnassignedTeams(Student student) { var meetingTeams = TimeSlots.SelectMany(t => t.Teams); var meetingTeamIds = meetingTeams.Select(t => t.Id).ToHashSet(); return student.Teams.Where(e => !meetingTeamIds.Contains(e.Id)).ToArray(); } }