public static void SetEvaluate <G>(GeneticAlgorithm <G> alg, TeachingUnit teachingUnit, Schedule schedule) where G : TimeslotChromosome, IEquatable <G> { alg.Evaluate = chromosome => { var slot = teachingUnit.FreeTimeslots[chromosome.Code]; var cell = new ScheduleCell(slot.classroom, slot.periodTimeslot, teachingUnit); schedule.ScheduleCells.Add(cell); chromosome.Value = EvaluationCalculation.Calculate(schedule); schedule.ScheduleCells.Remove(cell); }; }
public override List <Schedule> Run(List <Classroom> classrooms, List <PeriodTimeslot> periodTimeslots, List <TeachingUnit> teachingUnits) { var freeTimeslots = GetFreeTimeslots(classrooms, periodTimeslots); GlobalGA.Evaluate = chromosome => { var schedule = new Schedule(); // Статические жёсткие ограничения teachingUnits.ForEach( unit => unit.FreeTimeslots = freeTimeslots .Where(t => unit.Group.StudentsCount < t.classroom.Capacity) // Вместимость аудиторий .Where(t => unit.ClassroomTypes.Contains(t.classroom.ClassroomType)) // Тип аудиторий .Where(t => !unit.Teacher.BanPeriodTimeslots.Contains(t.periodTimeslot)) // Ограничения преподавателей на таймслоты .ToList()); for (var i = 0; i < chromosome.Code.Length; i++) { var index = chromosome.Code[i]; var teachingUnit = teachingUnits[index]; for (var j = 0; j < teachingUnit.CountInPeriodTimeslot; j++) { if (teachingUnit.FreeTimeslots.Count == 0) { chromosome.Value = -100; return; } var timeslot = GetFreeTimeslot(teachingUnit, schedule); schedule.ScheduleCells.Add(new ScheduleCell(timeslot.classroom, timeslot.periodTimeslot, teachingUnit)); teachingUnit.FreeTimeslots.RemoveAll(t => t.periodTimeslot.Week.Equals(timeslot.periodTimeslot.Week) && t.periodTimeslot.Day.Equals(timeslot.periodTimeslot.Day)); for (var p = i + 1; p < chromosome.Code.Length; p++) { var k = chromosome.Code[p]; teachingUnits[k].FreeTimeslots.Remove(timeslot); teachingUnits[k].FreeTimeslots.RemoveAll(t => teachingUnits[k].Teacher.Equals(teachingUnit.Teacher) && t.periodTimeslot.Equals(timeslot.periodTimeslot)); teachingUnits[k].FreeTimeslots.RemoveAll(t => (teachingUnits[k].Group.Equals(teachingUnit.Group) || teachingUnits[k].Group.ParentGroupId == teachingUnit.Group.Id || teachingUnits[k].Group.ChildGroups.Contains(teachingUnit.Group)) && t.periodTimeslot.Equals(timeslot.periodTimeslot)); } } } chromosome.Schedule = schedule; chromosome.Value = EvaluationCalculation.Calculate(schedule); }; for (var i = 0; i < CountIterationsGlobalGA; i++) { GlobalGA.MakeIteration(); } var schedules = GlobalGA.ChromosomePool .Take(CountSchedules) .Select(x => x.Schedule) .Where(x => x != null) .ToList(); return(schedules); }
static async Task Main(string[] args) { var connectionOptions = new ConnectionOptions(ConnectionString); var periodTimeslotRepository = new MsSqlPeriodTimeslotRepository(connectionOptions); var classroomRepository = new MsSqlClassroomRepository(connectionOptions); var teachingUnitRepository = new MsSqlTeachingUnitRepository(connectionOptions); var scheduleCellRepository = new MsSqlScheduleCellRepository(connectionOptions); var periodTimeslots = (await periodTimeslotRepository.GetEntityListAsync()) .Select(x => PeriodTimeslotConverter.Convert(x)).ToList(); var classrooms = (await classroomRepository.GetEntityListAsync()) .Select(x => ClassroomConverter.Convert(x)).ToList(); var teachingUnits = (await teachingUnitRepository.GetEntityListAsync()) .Select(x => TeachingUnitConverter.Convert(x)).ToList(); var generation = new GeneticScheduleGeneration(10, teachingUnits.Count); var schedules = generation.Run(classrooms, periodTimeslots, teachingUnits); var i = 1; var sum = 0; var sum2 = 0; var sum3 = 0; var sum4 = 0; var sum5 = 0; var sum6 = 0; schedules.ForEach(x => { var f = Function1.Count(x); var f2 = Function3.Count(x); var f3 = Function4.Count(x); var f4 = Function5.Count(x); var f5 = Function6.Count(x); var f6 = Function7.Count(x); sum += f; sum2 += f2; sum3 += f3; sum4 += f4; sum5 += f5; sum6 += f6; Console.WriteLine($"Расписание {i++}"); Console.WriteLine($"Количество неутренних лекций: {f}"); Console.WriteLine($"Количество избыточных мест: {f2}"); Console.WriteLine($"Количество превышений пар в день для преподавателей: {f3}"); Console.WriteLine($"Количество окон для преподавателей: {f4}"); Console.WriteLine($"Количество превышений пар в день для студентов: {f5}"); Console.WriteLine($"Количество окон для студентов: {f6}"); Console.WriteLine($"Оценка расписания: {EvaluationCalculation.Calculate(x)}"); Console.WriteLine($"-------------------------------------"); }); Console.WriteLine($"Всего ошибок (Лекции): {sum}"); Console.WriteLine($"Всего ошибок (Избыточные места): {sum2}"); Console.WriteLine($"Всего ошибок (Количество превышений пар в день для преподавателей): {sum3}"); Console.WriteLine($"Всего ошибок (Количество окон для преподавателей): {sum4}"); Console.WriteLine($"Всего ошибок (Количество превышений пар в день для студентов): {sum5}"); Console.WriteLine($"Всего ошибок (Количество окон для студентов): {sum6}"); await scheduleCellRepository.Clear(); await scheduleCellRepository.AddRangeAsync(schedules.First().ScheduleCells.Select(x => ScheduleCellConverter.Convert(x))); Console.ReadKey(); }