public void EndInit() { if (this.mIsInitBegan == false) { throw new GeneticAlgorithmInitializationNotStartedException("EndInit() invoked before BeginInit()"); } try { this.CheckInitFinished(); } catch (GeneticAlgorithmNotInitializedException e) { throw new GeneticAlgorithmNotInitializedException("Initialization not completed", e); } this.mCurrentGeneration = new List<Schedule> { }; var data = from p in this.mData group p by p.Class into gr select new { Class = gr.Key, Subjects = from t in gr group t by t.Subject into c select new { Subject = c.Key, Groups = c } }; List<Day> timetable = new List<Day>{ }; for (int i = 0; i < mDaysCount; ++i) { Day d = new Day(new List<ClassSchedule>{}); for (int j = 0;j < data.Count(); ++j) { List<Lesson> lessons = new List<Lesson>{}; for (int k = 0; k < PeriodsCount; ++k) { lessons.Add(null); } ClassSchedule cs = new ClassSchedule(null, lessons); d.Classes.Add(cs); } timetable.Add(d); } int day = 0; int period = 0; int classN = 0; int hoursWeekly; foreach (var item in data) { day = 0; period = 0; for (int i = 0; i < Days; ++i) { timetable[i].Classes[classN].Class = item.Class; } foreach (var current in item.Subjects) { hoursWeekly = 0; List<Group> groups = new List<Group>(); foreach (Curriculum curric in current.Groups) { hoursWeekly = curric.HoursPerWeek; Group g = new Group(curric.Teacher, curric.Group, curric.DesiredClassroom, curric.AlternativeClassrooms); groups.Add(g); } for (int i = 0; i < hoursWeekly; i++) { Lesson l = new Lesson(item.Class, current.Subject, groups); timetable[day].Classes[classN].Lessons[period] = l; if (period == PeriodsCount - 1) { day++; period = 0; } else { period++; } } } classN++; } Random rnd = new Random(); Schedule s = new Schedule(timetable, mSubjectsDifficulty); SaveCopy = new Schedule(s.Timetable, mSubjectsDifficulty); s.Shuffle(rnd); this.mLastSuiting = s; this.mSuitingConstraints = s; this.mCurrentGeneration.Add(s); for (int i = 0; i < GenerationSize * 10; ++i) { s = new Schedule(timetable, mSubjectsDifficulty); s.Shuffle(rnd); this.mCurrentGeneration.Add(s); } EqualityComparer<Schedule> comp = new ScheduleComparator(); this.mCurrentGeneration = mCurrentGeneration.OrderByDescending(x => x.Rating.Errors). Distinct(comp).ToList(); this.mCurrentGeneration = mCurrentGeneration.GetRange(0, GenerationSize); this.mIsInitialized = true; }
public void Generate() { int source, sink; #region Build graph List<CHPair> clHourPairs = new List<CHPair>(); for (int i = 0; i < this.mPeriodsCount * Days; ++i) { for (int j = 0; j < mRooms.Count; ++j) { CHPair p = new CHPair() { classroom = mRooms[j], hour = i, index = clHourPairs.Count }; clHourPairs.Add(p); } } List<CurricLPair> lessons = new List<CurricLPair>(); foreach (Curriculum curriculum in mData) { for (int i = 0; i < curriculum.HoursPerWeek; i++ ) { Lesson l = new Lesson(curriculum.Class, curriculum.Subject, new List<Group> { }); CurricLPair p = new CurricLPair() { curric = curriculum, lesson = l }; lessons.Add(p); } } source = lessons.Count + clHourPairs.Count; sink = source + 1; n = sink + 1; for (int i = 0; i < lessons.Count; ++i) { var desiredRoom = from t in clHourPairs where t.classroom == lessons[i].curric.DesiredClassroom select t; foreach (var t in desiredRoom) { Edge e = new Edge(t.index + lessons.Count, 2000); Edge rev = new Edge(i, 0); e.backwardsIndex = neigs[t.index + lessons.Count].Count; e.backwardsNode = t.index + lessons.Count; rev.backwardsIndex = neigs[i].Count; rev.backwardsNode = i; neigs[t.index + lessons.Count].Add(rev); neigs[i].Add(e); } for (int j = 0; j < lessons[i].curric.AlternativeClassrooms.Count; ++j) { var alternative = from t in clHourPairs where t.classroom == lessons[i].curric.AlternativeClassrooms[i] select t; foreach (var t in alternative) { Edge e = new Edge(t.index + lessons.Count, 2000 - j - 1); Edge rev = new Edge(i, 0); e.backwardsIndex = neigs[t.index + lessons.Count].Count; e.backwardsNode = t.index + lessons.Count; rev.backwardsIndex = neigs[i].Count; rev.backwardsNode = i; neigs[t.index + lessons.Count].Add(rev); neigs[i].Add(e); } } #region From Source Edge ed = new Edge(i, 2000); Edge reve = new Edge(source, 0); ed.backwardsIndex = neigs[i].Count; ed.backwardsNode = i; reve.backwardsIndex = neigs[source].Count; reve.backwardsNode = source; neigs[source].Add(ed); neigs[i].Add(reve); #endregion } #region To Sink for (int i = lessons.Count; i < lessons.Count + clHourPairs.Count; ++i) { Edge ed = new Edge(sink, 2000); Edge reve = new Edge(i, 0); ed.backwardsIndex = neigs[sink].Count; ed.backwardsNode = sink; reve.backwardsIndex = neigs[i].Count; reve.backwardsNode = source; neigs[i].Add(ed); neigs[sink].Add(reve); } #endregion #endregion #region Matching source = n; sink = n + 1; n += 2; for (int i = 0; i < n; ++i) { bfsNumber[i] = -1; } while (bfs(source, sink)) { for (int i = 0; i < n; ++i) used[i] = false; while (dfs(source, sink)) for (int i = 0; i < n; ++i) used[i] = false; for (int i = 0; i < n; ++i) { bfsNumber[i] = -1; } } #endregion #region Building the schedule #endregion }