private void TimetableGroups() { List <Raschasovka> Loads = services.GetGroupsLoadForCurrentSemester(); List <RateData> teachers = UniqueTeachers(Loads).Select(t => new RateData { Id = t }).ToList(); //Оценка личного времени преподавателей преподавателей TeachersRatePersonalTime(teachers); //services.GetTeachersWeight(); //Выборка критерия личного времени var query = Loads.Join(services.GetTeachersWeight(), l => l.TeacherId, w => w.Id, (l, w) => new QueryClass { load = l, TeacherWeight = w.Weight }).ToList(); //Оценка по критерию нагруженности из расчасовки TeachersRate(services.GetTeachersLoadRate()); //Выборка по критерию нагруженности var query2 = query.Join(services.GetTeachersWeight(), l => l.load.TeacherId, w => w.Id, (l, w) => new { l.load, l.TeacherWeight, TeachersLoadWeight = w.Weight }); //Выборка критерия типа предмета var LoadWithWeights = query2.Join(services.GetSubjectClassWeight(), l => l.load.SubjectClassId, w => w.Id, (l, w) => new { l.load, l.TeacherWeight, l.TeachersLoadWeight, SubjectClassWeight = w.Weight }); Console.WriteLine(); //Критерии умножаются на приоритет и суммируются float SubjectClassPriority = 9.5f; float TeacherPriority = 7; float TeachersLoadPriority = 10f; var LoadWeighted = LoadWithWeights.Select(l => new { l.load, FullWeight = l.SubjectClassWeight * SubjectClassPriority + l.TeacherWeight * TeacherPriority + l.TeachersLoadWeight * TeachersLoadPriority }).OrderByDescending(l => l.FullWeight); //!!!!!!! надо исключить таймслоты по неделям, т.е. запихнуть сюда таймслоты которые доступны //для всех недель которые нужны для занятий foreach (var load in LoadWeighted) { var Timeslots = services.GetHours().SelectMany(x => services.GetDaysOfWeek().Where(d => d.Number != 6).Select(y => new { HourId = x.Id, DayId = y.Id })).ToList(); var PersonalTimeSlots = services.GetTeacherPersonalTime(load.load.TeacherId).Select(pt => new { HourId = pt.HourId, DayId = pt.DayOfWeekId }); //Исключить занятые таймслоты преподавателя var TeacherSchedule = services.GetTeacherSchedule(load.load).Select(s => new { HourId = s.HourId, DayId = s.DayOfWeekId }); //Исключить занятые таймслоты группы var GroupShcedule = services.GetGroupSchedule(load.load).Select(s => new { HourId = s.HourId, DayId = s.DayOfWeekId }); Timeslots = Timeslots.Except(PersonalTimeSlots) .Except(TeacherSchedule).Except(GroupShcedule).ToList(); var DepartmentAuditoriums = services.GetDepartmentAuditoriumsForSubjectType(load.load.DepartmentId, load.load.SubjectTypeId); List <Timeslots> FinalTimeslots = DepartmentAuditoriums.SelectMany(a => Timeslots.Select(t => new Timeslots { HourId = t.HourId, DayId = t.DayId, AuditoriumId = a.Id })).ToList(); //Исключение таймслотов аудиторий из доступных тайслотов List <Timeslots> AuditoriumSchedule = new List <Timeslots>(); DepartmentAuditoriums.ToList().ForEach(a => AuditoriumSchedule.AddRange(services.GetAuditoriumSchedule(a.Id) .Select(at => new Timeslots { HourId = at.HourId, DayId = at.DayOfWeekId, AuditoriumId = at.AuditoriumId }).ToList())); foreach (Timeslots ts in AuditoriumSchedule) { FinalTimeslots.Remove(FinalTimeslots.FirstOrDefault(ft => ft.DayId == ts.DayId && ft.HourId == ts.HourId && ft.AuditoriumId == ts.AuditoriumId)); } //DepartmentAuditoriums.ToList().ForEach(a => FinalTimeslots = FinalTimeslots.Except(services.GetAuditoriumSchedule(a.Id) // .Select(at => new Timeslots { HourId = at.HourId, DayId = at.DayOfWeekId, AuditoriumId = at.AuditoriumId })).ToList()); //Если часов для занятия > 2, то исключить таймслоты без смежных пустых таймслотов //потом изменить под недели if (load.load.TotalHoursForSemestr / 16 > 2) { foreach (var ts in FinalTimeslots) { } } //Если есть рекомендованная аудитория if (load.load.AuditoriumId != null) { ; } var criteria = services.GetCriteria(); List <TimeslotsCriteriaWeight> timeslotsWeight = FinalTimeslots.Select(ts => new TimeslotsCriteriaWeight { AuditoriumId = ts.AuditoriumId, DayId = ts.DayId, HourId = ts.HourId }).ToList(); foreach (Criteria c in criteria) { foreach (var criteriaList in UseCriteria(c, FinalTimeslots, load.load).ToList()) { foreach (var timeslot in timeslotsWeight.Where(ts => ts.DayId == criteriaList.DayId && ts.HourId == criteriaList.HourId && ts.AuditoriumId == criteriaList.AuditoriumId).ToList()) { timeslot.criteriaWeight.Add(new CriteriaWeight { criteria = c, Weight = criteriaList.Weight }); } } Console.WriteLine(); } foreach (TimeslotsCriteriaWeight tw in timeslotsWeight) { Console.WriteLine(tw.AllCriteriaWeight); tw.criteriaWeight.ForEach(cw => tw.AllCriteriaWeight += cw.Weight * cw.criteria.Rate); } timeslotsWeight = timeslotsWeight.OrderByDescending(tw => tw.AllCriteriaWeight).ThenBy(tw => tw.DayId).ThenBy(tw => tw.HourId).ToList(); services.AddScheduleWeeks(services.AddScheduleTimeslot(load.load, timeslotsWeight.FirstOrDefault()), load.load.Id); Console.WriteLine(); } Console.WriteLine(); }