Exemple #1
0
 public void AddCourseClass(CourseClass courseClass)
 {
     if (CourseClasses == null)
     {
         CourseClasses = new List <CourseClass>();
     }
     CourseClasses.Add(courseClass);
 }
 public bool BranchsOverlaps(CourseClass courseClass)
 {
     foreach (StudentGroup group1 in StudentGroups)
     {
         foreach (StudentGroup group2 in courseClass.StudentGroups)
         {
             if (group1.Branch == group2.Branch && Course != courseClass.Course)
             {
                 return(true);
             }
         }
     }
     return(false);
 }
 public bool GroupsOverlap(CourseClass courseClass)
 {
     foreach (StudentGroup group1 in StudentGroups)
     {
         foreach (StudentGroup group2 in courseClass.StudentGroups)
         {
             if (group1 == group2 && Course != courseClass.Course)
             {
                 return(true);
             }
         }
     }
     return(false);
 }
        public void CalculateFitness()
        {
            int _score = 0;

            int _numberOfRooms = Configuration.GetInstance.GetNumberOfRooms();
            int _daySize       = DAY_HOURS * _numberOfRooms;

            int _ci = 0;

            foreach (KeyValuePair <CourseClass, int> it in _classes.ToList())
            {
                int _pos    = it.Value;
                int _day    = _pos / _daySize;
                int _time   = _pos % _daySize;
                int _roomId = _time / DAY_HOURS;
                _time %= DAY_HOURS;
                int _dur = it.Key.Duration;

                CourseClass _cc   = it.Key;
                Room        _room = Configuration.GetInstance.GetRoomById(_roomId);

                #region Score 1 (check for room overlapping of classes)                                                                          [+7]

                bool _overlapping = false;
                for (int i = _dur - 1; i >= 0; i--)
                {
                    if (_slots[_pos + i].Count > 1)
                    {
                        _overlapping = true;
                        break;
                    }
                }

                if (!_overlapping)
                {
                    _score += 7;
                }

                Criteria[_ci + 0] = !_overlapping;

                #endregion

                #region Score 2 (does current room have enough seats)                                                                            [+10]

                Criteria[_ci + 1] = _room.Capacity >= _cc.StudentCount;
                if (Criteria[_ci + 1])
                {
                    _score += 10;
                }

                #endregion

                #region Score 3 (does current room fair)                                                                                         [+3]

                Criteria[_ci + 2] = _cc.RequiresLab.Equals(_room.IsLab);
                if (Criteria[_ci + 2])
                {
                    _score += 3;
                }

                #endregion

                #region Score 4 and 5 and 6 (check for overlapping of classes for branches and student groups && same course exams in same time) [+5][+10][+10]

                bool _bra = false, _gro = false, _sameExamsNotInSameTime = false;
                for (int i = _numberOfRooms, t = (_day * _daySize + _time); i > 0; i--, t += DAY_HOURS)
                {
                    List <CourseClass> _courseClassesOnSameTime = new List <CourseClass>();
                    for (int j = 0; j < _numberOfRooms; j++)
                    {
                        int _roomChangeIndex = (DAYS_COUNT * DAY_HOURS) * j;
                        _courseClassesOnSameTime.AddRange(_slots[_time + _roomChangeIndex]);
                    }

                    for (int j = _dur - 1; j >= 0; j--)
                    {
                        List <CourseClass> cl = _slots[t + j];
                        foreach (CourseClass it_cc in cl)
                        {
                            if (_cc != it_cc)
                            {
                                if (!_bra && _cc.BranchsOverlaps(it_cc))
                                {
                                    _bra = true;
                                }

                                if (!_gro && _cc.GroupsOverlap(it_cc))
                                {
                                    _gro = true;
                                }

                                if (_bra && _gro)
                                {
                                    goto total_overlap;
                                }
                            }
                        }

                        List <CourseClass> _courseClassesWithSameCourse = Configuration.GetInstance.GetCourseClassesWithCourse(_cc.Course);
                        _courseClassesWithSameCourse.Remove(_cc);
                        if (_courseClassesWithSameCourse.Count > 0)
                        {
                            foreach (CourseClass it_cc in _courseClassesWithSameCourse)
                            {
                                if (!_courseClassesOnSameTime.Contains(it_cc))
                                {
                                    if (!_sameExamsNotInSameTime && _cc.Course == it_cc.Course)
                                    {
                                        _sameExamsNotInSameTime = true;
                                    }
                                }
                            }
                        }
                    }
                }

total_overlap:

                if (!_bra)
                {
                    _score += 5;
                }
                Criteria[_ci + 3] = !_bra;

                if (!_gro)
                {
                    _score += 10;
                }
                Criteria[_ci + 4] = !_gro;

                if (!_sameExamsNotInSameTime)
                {
                    _score += 10;
                }
                Criteria[_ci + 5] = !_sameExamsNotInSameTime;

                #endregion

                #region Score 7 (check difficulty limit in one day for student groups)                                                           [+3]

                bool _limitExceeded = false;
                foreach (StudentGroup group in _cc.StudentGroups)
                {
                    List <CourseClass> _courseClassesInThisDay = new List <CourseClass>();
                    int _diffInDay = 0;
                    for (int j = 0; j < DAY_HOURS; j++)
                    {
                        if (_limitExceeded)
                        {
                            break;
                        }

                        List <CourseClass> _courseClassesOnSameDay = new List <CourseClass>();
                        for (int k = 0; k < _numberOfRooms; k++)
                        {
                            int _roomChangeIndex = (DAYS_COUNT * DAY_HOURS) * k;
                            _courseClassesOnSameDay.AddRange(_slots[(_day * DAY_HOURS) + j + _roomChangeIndex]);
                        }

                        foreach (CourseClass cc_it in _courseClassesOnSameDay)
                        {
                            if (_limitExceeded)
                            {
                                break;
                            }
                            if (!_courseClassesInThisDay.Contains(cc_it) && cc_it.StudentGroups.Contains(group))
                            {
                                _courseClassesInThisDay.Add(cc_it);
                                _diffInDay += cc_it.Difficulty;
                            }
                        }
                    }

                    if (!_limitExceeded && _diffInDay > group.MaxDifficultyInDay)
                    {
                        _limitExceeded = true;
                        break;
                    }
                    if (_limitExceeded)
                    {
                        break;
                    }
                }

                if (!_limitExceeded)
                {
                    _score += 3;
                }
                Criteria[_ci + 6] = !_limitExceeded;


                #endregion

                #region Score 8 (check this exam day in prelector schedule table)                                                                [+2]

                Criteria[_ci + 7] = true;
                for (int i = 0; i < _dur; i++)
                {
                    if (!_cc.Prelector.ScheduleDays[_day])
                    {
                        Criteria[_ci + 7] = false;
                        break;
                    }
                }
                if (Criteria[_ci + 7])
                {
                    _score += 2;
                }

                #endregion

                _ci += 8;
            }

            Fitness = (float)_score / (Configuration.GetInstance.GetNumberOfCourseClasses() * NUMBER_OF_SCORES);
        }
        public void Mutation()
        {
            Random _rnd = new Random();

            if (_rnd.Next() % 100 > MutationProbability)
            {
                return;
            }

            int _numberOfClasses = _classes.Count;

            for (int i = MutationSize; i > 0; i--)
            {
                int mpos = _rnd.Next() % _numberOfClasses;
                KeyValuePair <CourseClass, int>         it = _classes.ToList <KeyValuePair <CourseClass, int> >()[mpos];
                List <KeyValuePair <CourseClass, int> > _classesWithSameCourse = _classes.Where(x => x.Key.Course == it.Key.Course).ToList();
                if (_classesWithSameCourse.Contains(it))
                {
                    _classesWithSameCourse.Remove(it);
                }

                int         pos1 = it.Value;
                CourseClass cc1  = it.Key;

                int nr   = Configuration.GetInstance.GetNumberOfRooms();
                int dur  = cc1.Duration;
                int day  = _rnd.Next() % DAYS_COUNT;
                int room = _rnd.Next() % nr;
                int time = _rnd.Next() % (DAY_HOURS + 1 - dur);
                int pos2 = day * nr * DAY_HOURS + room * DAY_HOURS + time;

                for (int j = dur - 1; j >= 0; j--)
                {
                    List <CourseClass> cl = _slots[pos1 + j];
                    foreach (CourseClass It in cl)
                    {
                        if (It == cc1)
                        {
                            cl.Remove(It);
                            break;
                        }
                    }

                    _slots[pos2 + j].Add(cc1);
                }

                _classes[cc1] = pos2;

                if (_classesWithSameCourse.Count > 0)
                {
                    foreach (KeyValuePair <CourseClass, int> sameCourse in _classesWithSameCourse)
                    {
                        int _posOld  = sameCourse.Value;
                        int _newRoom = _rnd.Next() % nr;
                        int _posNew  = day * nr * DAY_HOURS + _newRoom * DAY_HOURS + time;

                        for (int j = dur - 1; j >= 0; j--)
                        {
                            List <CourseClass> cl = _slots[_posOld + j];
                            foreach (CourseClass It in cl)
                            {
                                if (It == sameCourse.Key)
                                {
                                    cl.Remove(It);
                                    break;
                                }
                            }

                            _slots[_posNew + j].Add(sameCourse.Key);
                        }

                        _classes[sameCourse.Key] = _posNew;
                    }
                }
            }

            CalculateFitness();
        }