// Performs mutation on chromosome public void Mutation() { Random rand = new Random(); // check probability of mutation operation if (rand.Next() % 100 > _mutationProbability) { // will not do mutation return; } // number of classes int numberOfClasses = _classes.Count; // number of time-space slots int size = _slots.Length; // move selected number of classes at random position for (int i = _mutationSize; i > 0; i--) { // select random chromosome for movement int mpos = rand.Next() % numberOfClasses; int pos1 = 0; KeyValuePair <CourseClass, int> it = _classes.ToList <KeyValuePair <CourseClass, int> >()[mpos]; // current time-space slot used by class pos1 = it.Value; CourseClass cc1 = it.Key; // determine position of class randomly int nr = Configuration.GetInstance.GetNumberOfRooms(); int dur = cc1.GetDuration; int day = rand.Next() % DAYS_NUM; int room = rand.Next() % nr; int time = rand.Next() % (DAY_HOURS + 1 - dur); int pos2 = day * nr * DAY_HOURS + room * DAY_HOURS + time; // move all time-space slots for (int j = dur - 1; j >= 0; j--) { // remove class hour from current time-space slot List <CourseClass> cl = _slots[pos1 + j]; foreach (CourseClass It in cl) { if (It == cc1) { cl.Remove(It); break; } } // move class hour to new time-space slot _slots[pos2 + j].Add(cc1); } // change entry of class table to point to new time-space slots _classes[cc1] = pos2; } }
// Returns TRUE if another class has one or overlapping student groups. public bool GroupsOverlap(CourseClass c) { foreach (StudentsGroup it1 in _groups) { foreach (StudentsGroup it2 in c._groups) { if (it1 == it2) { return(true); } } } return(false); }
/// <summary> /// Bind professor to course /// </summary> /// <param name="_courseClass"></param> public void AddCourseClass(CourseClass courseClass) { _courseClasses.Add(courseClass); }
/// <summary> /// Bind professor to course /// </summary> /// <param name="_courseClass"></param> public void AddCourseClass(CourseClass courseClass) { _courseClasses.Add(courseClass); }
// Parse file and store parsed object public void ParseFile(LINQDataContext db) { // clear previously parsed objects _professors.Clear(); _studentGroups.Clear(); _courses.Clear(); _rooms.Clear(); _courseClasses.Clear(); Room.RestartIDs(); // // Save Professor Data // foreach (var any in db.Professors) { ProfessorInfoCompiler pIc = new ProfessorInfoCompiler(); Professor p; if (pIc.StartScanner(any.Schedule)) { p = new Professor(any.ID, any.Name_Professor, pIc.CompiledData); _professors.Add(p.GetId, p); } } // // Save StudentsGroup Data // foreach (var any in db.Groups) { StudentsGroup sg; string sg_name = string.Format(CultureInfo.CurrentCulture, "{0} {1} {2}-{3}", any.Branch.Degree, any.Branch.Branch_Name, any.Semester_Entry_Year, (any.Semester_Entry_FS) ? "1" : "2"); sg = new StudentsGroup(any.ID, sg_name, any.Size_No); _studentGroups.Add(sg.GetId, sg); } // // Save Course Data // foreach (var any in db.Courses) { Course c; c = new Course(any.Course_ID, any.Name_Course); _courses.Add(c.GetId, c); } // // Save Room Data // foreach (var any in db.Rooms) { Room r; r = new Room(any.Room_ID, any.Name_Room, any.Type_Room, any.Size_No); _rooms.Add(r.GetId, r); } // // Save CourseClass Data ----------------------------------------------------------------------------- // foreach (var any in db.Classes) { // // set Professor by best priority // var prof = (from p1 in db.Priority_Professors join p2 in db.Professors on p1.Professor_ID equals p2.ID where (p1.Class_ID == any.Class_ID) orderby p1.Priority select new { p1.Professor_ID, p2.Name_Professor, p2.Schedule }).ToArray()[0]; ProfessorInfoCompiler pIc = new ProfessorInfoCompiler(); Professor p = (pIc.StartScanner(prof.Schedule)) ? new Professor(prof.Professor_ID, prof.Name_Professor, pIc.CompiledData) : new Professor(prof.Professor_ID, prof.Name_Professor, pIc.CompiledData); // // set selected course for class // Course c = new Course(any.Course_ID, any.Course.Name_Course); // // set StudentsGroup in List // List <StudentsGroup> g = new List <StudentsGroup>(); foreach (var lstGroup in (from gil in db.Group_ID_Lists join groups in db.Groups on gil.Group_ID equals groups.ID where gil.Class_ID == any.Class_ID select new { gil.Group_ID, groups.Size_No, sg_name = string.Format(CultureInfo.CurrentCulture, "{0} {1} {2}-{3}", groups.Branch.Degree, groups.Branch.Branch_Name, groups.Semester_Entry_Year, (groups.Semester_Entry_FS) ? "1" : "2") })) { StudentsGroup sg = new StudentsGroup(lstGroup.Group_ID, lstGroup.sg_name, lstGroup.Size_No); g.Add(sg); } // // save class by created data // CourseClass cc = new CourseClass(p, c, g, any.RoomType, (any.Practical_unit + any.Theory_unit), any.Class_ID); _courseClasses.Add(cc); } //---------------------------------------------------------------------------------------------------------------- // db.Dispose(); _isEmpty = false; }
// Calculates fitness value of chromosome public void CalculateFitness() { // chromosome's score int score = 0; int numberOfRooms = Configuration.GetInstance.GetNumberOfRooms(); int daySize = DAY_HOURS * numberOfRooms; int ci = 0; // check criteria and calculate scores for each class in schedule foreach (KeyValuePair <CourseClass, int> it in _classes.ToList()) { //_classes.ToList<KeyValuePair<CourseClass, int>>()) // coordinate of time-space slot int pos = it.Value; // int pos of _slot array int day = pos / daySize; int time = pos % daySize; // this is not time now! int room = time / DAY_HOURS; time = time % DAY_HOURS; // this is a time now! int dur = it.Key.GetDuration; CourseClass cc = it.Key; Room r = Configuration.GetInstance.GetRoomById(room); #region Score 1 (check for room overlapping of classes) [+3] // check for room overlapping of classes bool overlapping = false; for (int i = dur - 1; i >= 0; i--) { if (_slots[pos + i].Count > 1) { overlapping = true; break; } } // on room overlapping if (!overlapping) { score += 3; } _criteria[ci + 0] = !overlapping; #endregion #region Score 2 (does current room have enough seats) [+2] // does current room have enough seats _criteria[ci + 1] = r.GetNumberOfSeats >= cc.GetNumberOfSeats; if (_criteria[ci + 1]) { score += 2; } #endregion #region Score 3 (does current room have computers if they are required) [+12] // does current room have computers if they are required _criteria[ci + 2] = (cc.Lab == r.GetLab) ? true : false; if (_criteria[ci + 2]) { score += 10; } #endregion #region Score 4 and 5 (check overlapping of classes for professors and student groups) [+4][+4] bool prof = false, gro = false; // check overlapping of classes for professors and student groups for (int i = numberOfRooms, t = (day * daySize + time); i > 0; i--, t += DAY_HOURS) { // for each hour of class for (int j = dur - 1; j >= 0; j--) { // check for overlapping with other classes at same time List <CourseClass> cl = _slots[t + j]; foreach (CourseClass it_cc in cl) { if (cc != it_cc) { // professor overlaps? if (!prof && cc.ProfessorOverlaps(it_cc)) { prof = true; } // student group overlaps? if (!gro && cc.GroupsOverlap(it_cc)) { gro = true; } // both type of overlapping? no need to check more if (prof && gro) { goto total_overlap; } } } } } total_overlap: // professors have no overlapping classes? if (!prof) { score += 4; } _criteria[ci + 3] = !prof; // student groups has no overlapping classes? if (!gro) { score += 4; } _criteria[ci + 4] = !gro; #endregion #region Score 6 (check this class time by professor's free TimeTable) [+8] _criteria[ci + 5] = true; for (int i = 0; i < dur; i++) { if (!cc.GetProfessor.GetSchedule[time + i, day + 1]) { _criteria[ci + 5] = false; break; } } if (_criteria[ci + 5]) { score += 8; } #endregion #region Score 7 (doesn't current class in 13-14 DayHours or it TimeSlot is 5) [+1] // All Time-Slot is 8~19 in 12 Hours // Time-Slot 5 is in 13-14 Hour's _criteria[ci + 6] = true; for (int i = 0; i < dur; i++) { if ((time + i) == 5) { _criteria[ci + 6] = false; break; } } if (_criteria[ci + 6]) { score++; } #endregion ci += numberOfScores; } // calculate fitness value based on score _fitness = (float)score / (Configuration.GetInstance.GetNumberOfCourseClasses() * numberOfScores); }
// Returns TRUE if another class has same professor. public bool ProfessorOverlaps(CourseClass c) { return _professor == c._professor; }
// Returns TRUE if another class has one or overlapping student groups. public bool GroupsOverlap(CourseClass c) { foreach (StudentsGroup it1 in _groups) { foreach (StudentsGroup it2 in c._groups) { if (it1 == it2) return true; } } return false; }
// Parse file and store parsed object public void ParseFile(LINQDataContext db) { // clear previously parsed objects _professors.Clear(); _studentGroups.Clear(); _courses.Clear(); _rooms.Clear(); _courseClasses.Clear(); Room.RestartIDs(); // // Save Professor Data // foreach (var any in db.Professors) { ProfessorInfoCompiler pIc = new ProfessorInfoCompiler(); Professor p; if (pIc.StartScanner(any.Schedule)) { p = new Professor(any.ID, any.Name_Professor, pIc.CompiledData); _professors.Add(p.GetId, p); } } // // Save StudentsGroup Data // foreach (var any in db.Groups) { StudentsGroup sg; string sg_name = string.Format(CultureInfo.CurrentCulture, "{0} {1} {2}-{3}", any.Branch.Degree, any.Branch.Branch_Name, any.Semester_Entry_Year, (any.Semester_Entry_FS) ? "1" : "2"); sg = new StudentsGroup(any.ID, sg_name, any.Size_No); _studentGroups.Add(sg.GetId, sg); } // // Save Course Data // foreach (var any in db.Courses) { Course c; c = new Course(any.Course_ID, any.Name_Course); _courses.Add(c.GetId, c); } // // Save Room Data // foreach (var any in db.Rooms) { Room r; r = new Room(any.Room_ID, any.Name_Room, any.Type_Room, any.Size_No); _rooms.Add(r.GetId, r); } // // Save CourseClass Data ----------------------------------------------------------------------------- // foreach (var any in db.Classes) { // // set Professor by best priority // var prof = (from p1 in db.Priority_Professors join p2 in db.Professors on p1.Professor_ID equals p2.ID where (p1.Class_ID == any.Class_ID) orderby p1.Priority select new { p1.Professor_ID, p2.Name_Professor, p2.Schedule }).ToArray()[0]; ProfessorInfoCompiler pIc = new ProfessorInfoCompiler(); Professor p = (pIc.StartScanner(prof.Schedule)) ? new Professor(prof.Professor_ID, prof.Name_Professor, pIc.CompiledData) : new Professor(prof.Professor_ID, prof.Name_Professor, pIc.CompiledData); // // set selected course for class // Course c = new Course(any.Course_ID, any.Course.Name_Course); // // set StudentsGroup in List // List<StudentsGroup> g = new List<StudentsGroup>(); foreach (var lstGroup in (from gil in db.Group_ID_Lists join groups in db.Groups on gil.Group_ID equals groups.ID where gil.Class_ID == any.Class_ID select new { gil.Group_ID, groups.Size_No, sg_name = string.Format(CultureInfo.CurrentCulture, "{0} {1} {2}-{3}", groups.Branch.Degree, groups.Branch.Branch_Name, groups.Semester_Entry_Year, (groups.Semester_Entry_FS) ? "1" : "2") })) { StudentsGroup sg = new StudentsGroup(lstGroup.Group_ID, lstGroup.sg_name, lstGroup.Size_No); g.Add(sg); } // // save class by created data // CourseClass cc = new CourseClass(p, c, g, any.RoomType, (any.Practical_unit + any.Theory_unit), any.Class_ID); _courseClasses.Add(cc); } //---------------------------------------------------------------------------------------------------------------- // db.Dispose(); _isEmpty = false; }
// Returns TRUE if another class has same professor. public bool ProfessorOverlaps(CourseClass c) { return(_professor == c._professor); }