Beispiel #1
0
        private Slot GetNewSlot(CourseClass cc)
        {
            //TODO: 没有考虑午休
            Slot newSlot = null;
            int  count   = 0;
            int  group   = this.configuration.GetStudentsGroupIdx(cc);
            bool isFixed = false;

            // 尽量选中空slot,最多尝试10次
            do
            {
                // 第几个工作日
                int day = this.Rand() % this.configuration.Parameters.WorkingDaysNumber;

                // 第几节课开始上,考虑了duration
                int time = this.Rand() % (this.configuration.Parameters.NumberOfClassPerDay + 1 - cc.Duration);

                // 如果用户有偏好,前5次尝试按照用户偏好优先。如果不能成功,则忽略偏好。
                if (count < 5 && cc.ExpectedClassIndexes != null && cc.ExpectedClassIndexes.Length > 0)
                {
                    if (cc.ExpectedClassIndexes.Length == 1)
                    {
                        time = cc.ExpectedClassIndexes[0];
                    }
                    else
                    {
                        int idx = this.Rand() % cc.ExpectedClassIndexes.Length;
                        time = cc.ExpectedClassIndexes[idx];
                    }
                }

                // 得到新的时间槽
                newSlot = this.GetSlot(day, group, time);

                isFixed = false;
                bool isOccupied = false;
                for (int i = 0; i < cc.Duration; i++)
                {
                    // 是否包含已经冻结的slot
                    if (this.Slots[newSlot.SlotIndex + i].IsFixed)
                    {
                        isFixed = true;
                        break;
                    }

                    // Slot是否为空,我们希望优先选中空slot
                    if (this.Slots[newSlot.SlotIndex + i].Classes.Count > 0)
                    {
                        isOccupied = true;
                    }
                }

                if (!isOccupied)
                {
                    break;
                }
            }while (isFixed || count++ < 10);

            return(newSlot);
        }
Beispiel #2
0
        /// <summary>
        /// 随机选择一个可排课的课堂
        /// </summary>
        /// <returns>一个课堂</returns>
        private CourseClass GetRandomUnfixedClass()
        {
            CourseClass cc = null;

            do
            {
                cc = this.configuration.CourseClasses[this.Rand() % this.configuration.CourseClasses.Count];
            }while (cc.IsFixed);

            return(cc);
        }
Beispiel #3
0
        // Performs mutation on chromosome
        // 在当前染色体上执行变异
        public void Mutation()
        {
            this.SelfCheck();

            // 检查是否需要变异
            if (this.Rand() % 100 > this.configuration.Parameters.MutationProbability)
            {
                return;
            }

            // move selected number of classes at random position
            // 随机移动指定数量课堂的时间槽
            for (int i = this.configuration.Parameters.MutationSize; i > 0; i--)
            {
                // 随机选择一个课堂
                CourseClass cc = this.GetRandomUnfixedClass();

                // 将课堂从现在的时间槽里删除
                foreach (var slot in this.GetSlots(cc))
                {
                    slot.Classes.Remove(cc);
                }

                // 随机决定课堂新的时间槽
                int newSlotIndex = this.GetNewSlot(cc).SlotIndex;

                // 放入新的时间槽
                for (int j = 0; j < cc.Duration; j++)
                {
                    this.Slots[newSlotIndex + j].Classes.Add(cc);
                }

                // 验证课程节数
                var count = this.Slots.FindAll(s => s.Classes.Contains(cc)).Count;
                Debug.Assert(cc.Duration == count, "确保排课结果中的课程的节数没有变化");
            }

            // 重新计算适应度
            this.CalculateFitnessAndEvenness();

            this.SelfCheck();
        }
Beispiel #4
0
 // Bind group to class
 public void AddClass(CourseClass courseClass)
 {
     CourseClasses.Add(courseClass);
 }
Beispiel #5
0
 // Returns TRUE if another class has same professor.
 public bool ProfessorOverlaps(CourseClass c)
 {
     return(Professor.Equals(c.Professor));
 }
Beispiel #6
0
 // Returns TRUE if another class has one or overlapping student groups.
 public bool GroupsOverlap(CourseClass c)
 {
     return(Groups.Intersect(c.Groups).Any());
 }
Beispiel #7
0
 public int GetStudentsGroupIdx(CourseClass cc)
 {
     return(this.StudentsGroups.FindIndex(sg => sg.Id == cc.StudentsGroupId));
 }
Beispiel #8
0
 private List <Slot> GetSlots(CourseClass cc)
 {
     return(this.Slots.FindAll(s => s.Classes.Contains(cc)));
 }