public Schedule MakeSchedule(LearningPlan learningPlan, MeetingEvaluator evaluator, Requisition requisition) { var meetingsToFill = requisition.Items.Select( Conversions.RequisitionToMeetingConverter.ConvertRequisitionToMeetingWithoutTime).SelectMany(x => x).ToArray(); var bestSchedule = new Schedule(new Meeting[0]); var bestPenalty = double.PositiveInfinity; for (var i = 0; i < 100; ++i) { var shuffledMeetingsToFill = meetingsToFill.Shuffled(); var tryingResult = TryMakeSchedule(learningPlan, evaluator, shuffledMeetingsToFill, requisition); if (bestPenalty > tryingResult.Item2) { bestPenalty = tryingResult.Item2; bestSchedule = tryingResult.Item1; } } return(bestSchedule); }
public void Test() { var learningPlanItem = new LearningPlanItem("A", new Discipline("X"), MeetingType.Lecture, GroupSize.FullGroup, 1); var learningPlan = new LearningPlan(new LearningPlanItem[] { learningPlanItem }); var groupsChoices = new GroupsChoice[] { new GroupsChoice(new MeetingGroup[] { new MeetingGroup("A", GroupPart.FullGroup) }) }; var groupRequisition = new GroupRequisition[] { new GroupRequisition(groupsChoices) }; var meetingTimeRequisitions = new MeetingTimeRequisition[] { new MeetingTimeRequisition(new MeetingTime[] { new MeetingTime(DayOfWeek.Friday, 5) }) }; var requisition = new Requisition(new RequisitionItem[] { new RequisitionItem(learningPlanItem, groupRequisition, "", 1, meetingTimeRequisitions, new Teacher("1"), WeekType.Any) }); var generator = new GreedyScheduleGenerator(); var evaluator = new MeetingEvaluator(new IRule[0]); var schedule = generator.MakeSchedule(learningPlan, evaluator, requisition); Assert.True(schedule.Meetings.Length == 1); var actualMeeting = schedule.Meetings[0]; var expectedMeeting = new Meeting(new Discipline("X"), MeetingType.Lecture, new MeetingGroup[] { new MeetingGroup("A", GroupPart.FullGroup) }) { MeetingTime = new MeetingTime(DayOfWeek.Friday, 5), Teacher = new Teacher("1"), Location = "", WeekType = WeekType.Any, }; Assert.AreEqual(expectedMeeting.MeetingTime, actualMeeting.MeetingTime); Assert.AreEqual(expectedMeeting.Discipline, actualMeeting.Discipline); Assert.AreEqual(expectedMeeting.Groups, actualMeeting.Groups); Assert.AreEqual(expectedMeeting.Location, actualMeeting.Location); Assert.AreEqual(expectedMeeting.MeetingType, actualMeeting.MeetingType); Assert.AreEqual(expectedMeeting.Teacher, actualMeeting.Teacher); Assert.AreEqual(expectedMeeting.WeekType, actualMeeting.WeekType); }
private (Schedule, double) TryMakeSchedule(LearningPlan learningPlan, MeetingEvaluator evaluator, Meeting[] meetingsToFill, Requisition requisition) { var penalty = 0d; List <Meeting> currentMeetings = new List <Meeting>(); foreach (var meeting in meetingsToFill) { var requisitionItem = GetCorrespondingRequisitionItem(meeting, requisition); var bestPenalty = double.PositiveInfinity; var bestMeeting = default(Meeting); foreach (var groupPriority in requisitionItem.GroupPriorities) { foreach (var groupsChoice in groupPriority.GroupsChoices) { foreach (var meetingTimePriority in requisitionItem.MeetingTimePriorities) { foreach (var meetingTimeChoice in meetingTimePriority.MeetingTimeChoices) { meeting.MeetingTime = meetingTimeChoice; meeting.Groups = groupsChoice.Groups; var currentPenalty = evaluator.Evaluate(learningPlan, requisition, new Schedule(currentMeetings.ToArray()), meeting); if (bestPenalty > currentPenalty) { bestPenalty = currentPenalty; bestMeeting = meeting.Copy(); } } } } } currentMeetings.Add(bestMeeting); } return(new Schedule(currentMeetings.ToArray()), penalty); }