Add Team functions

This commit is contained in:
2025-09-22 12:53:46 -04:00
parent 3daa3b81b3
commit dc83a18d76
48 changed files with 2364 additions and 633 deletions
+27 -57
View File
@@ -1,41 +1,42 @@
using Core.Entities;
using System.Diagnostics;
using Core.Entities;
using Google.OrTools.Sat;
namespace Core.Calculation;
public class TeamScheduler
{
private readonly IList<Student> _studentObjs;
private readonly IList<Team> _teamObjs;
private readonly IList<Student> _studentObjects;
private readonly IList<Team> _teamObjects;
private readonly int[] _students;
private readonly int[] _teams;
private readonly int[] _timeSlots;
private readonly List<Tuple<int,int>> _scheduleSeparateTeams = new ();
private readonly List<Tuple<int,int>> _scheduleSeparateTeams = [];
public TeamScheduler(IList<Team> teams, int numTimeSlots)
public TeamScheduler(Team[] teams, int numTimeSlots)
{
_teamObjs = teams;
_studentObjs = teams.SelectMany(t => t.Students).Distinct().ToList();
_teamObjects = teams;
_studentObjects = teams.SelectMany(t => t.Students).Distinct().ToList();
_students = Enumerable.Range(0, _studentObjs.Count).ToArray();
_teams = Enumerable.Range(0, _teamObjs.Count).ToArray();
_students = Enumerable.Range(0, _studentObjects.Count).ToArray();
_teams = Enumerable.Range(0, _teamObjects.Count).ToArray();
_timeSlots = Enumerable.Range(0, numTimeSlots).ToArray();
}
public void ScheduleSeparate(Team team1, Team team2)
{
var one = _teamObjs.IndexOf(team1);
var two = _teamObjs.IndexOf(team2);
var one = _teamObjects.IndexOf(team1);
var two = _teamObjects.IndexOf(team2);
_scheduleSeparateTeams.Add(Tuple.Create(one,two));
}
public static TeamScheduler CreateInstance(IList<Team> teams, int numTimeSlots)
public static TeamScheduler CreateInstance(Team[] teams, int numTimeSlots)
{
return new TeamScheduler(teams, numTimeSlots);
}
public IList<Team>[] Solve()
public TeamSchedulerSolution Solve()
{
// Model.
var model = new CpModel();
@@ -44,7 +45,7 @@ public class TeamScheduler
var m = new int[_students.Length,_teams.Length];
foreach (var i in _students)
foreach (var t in _teams)
m[i, t] = _studentObjs[i].Teams.Contains(_teamObjs[t]) ? 1 : 0;
m[i, t] = _studentObjects[i].Teams.Contains(_teamObjects[t]) ? 1 : 0;
// Variables.
// x - 1 if meeting of team t takes place at time slot s, else 0
@@ -82,55 +83,24 @@ public class TeamScheduler
foreach (var ts in _scheduleSeparateTeams)
foreach (var s in _timeSlots)
model.Add(x[ts.Item1, s] != x[ts.Item2, s]);
//model.Add(
// new BoundedLinearExpression(
// x[ts.Item1, s],
// x[ts.Item2, s],
// false));
var solver = new CpSolver();
var cpSolverStatus = solver.Solve(model);
Console.WriteLine($"Solver status: {cpSolverStatus}");
Debug.WriteLine($"Solver status: {cpSolverStatus}");
var timeSlotTeams = new Team[_timeSlots.Length][];
if (cpSolverStatus is CpSolverStatus.Optimal or CpSolverStatus.Feasible)
{
Console.WriteLine($"Total cost: {solver.ObjectiveValue}\n");
if (cpSolverStatus is not (CpSolverStatus.Optimal or CpSolverStatus.Feasible))
return new TeamSchedulerSolution(timeSlotTeams, cpSolverStatus.ToString());
//foreach (var t in _teams)
//foreach (var s in _timeSlots)
//{
// if (solver.Value(x[t, s]) > 0)
// Console.WriteLine($"{_teamObjs[t].Name} : {s}");
//}
//foreach (var i in _students)
//foreach (var s in _timeSlots)
//{
// if (solver.Value(y[i, s]) > 0)
// Console.WriteLine($"{_studentObjs[i].Name} : {s}");
//}
var timeSlotTeams = new List<Team>[_timeSlots.Length];
foreach (var s in _timeSlots)
{
var teams = new List<Team>();
foreach (var t in _teams)
{
if (solver.Value(x[t, s]) > 0)
{
teams.Add(_teamObjs[t]);
}
}
timeSlotTeams[s] = teams;
}
return timeSlotTeams;
}
else
{
//Console.WriteLine("No solution found.");
return Array.Empty<IList<Team>>();
}
Debug.WriteLine($"Total cost: {solver.ObjectiveValue}\n");
foreach (var s in _timeSlots)
{
var teams = (from t in _teams where solver.Value(x[t, s]) > 0 select _teamObjects[t]).ToArray();
timeSlotTeams[s] = teams;
}
//Debug.WriteLine("No solution found.");
return new TeamSchedulerSolution(timeSlotTeams, cpSolverStatus.ToString());
}
}