/// <summary> /// 随机生成一个全新的染色体 /// </summary> /// <returns></returns> public Schedule MakeNewFromPrototype(List<CourseClass> courseList) { // number of time-space slots int size = slots.Capacity; // make new chromosome, copy chromosome setup // 根据当前的染色体复制一个新的染色体,因为true为setupOnly的值,所以这里生成的染色体是全新的 Schedule newChromosome = new Schedule(this, true); // place classes at random position // 将课程放在一个随机的位置 List<CourseClass> c = courseList;// 获取所有课程,存放在类型为list的c中 foreach (CourseClass it in c)// 利用迭代器,开始遍历c { // determine random position of class int nr = ROOM_NUM; int dur = it.GetDuration(); int day = RandomNbr.GetRandomNbr() % DAYS_NUM; int room = RandomNbr.GetRandomNbr() % nr; int time = RandomNbr.GetRandomNbr() % (DAY_HOURS + 1 - dur); int pos = day * nr * DAY_HOURS + room * DAY_HOURS + time; for (int i = dur - 1; i >= 0; i--) { newChromosome.slots[pos + i].Add(it); } newChromosome.classes.Add(it, pos); } newChromosome.CalculateFitness(); return newChromosome; }
/// <summary> /// 进行交叉配对以生成新的染色体 /// </summary> /// <param name="parent2"></param> /// <returns></returns> public Schedule Crossover(Schedule parent2) { // check probability of crossover operation if (RandomNbr.GetRandomNbr() % 100 > crossoverProbability) { return new Schedule(this, false); } // new chromosome object, copy chromosome setup // n 是个全新的染色体 Schedule n = new Schedule(this, true); // number of classes int size = classes.Count; List<bool> cp = new List<bool>(); cp.Capacity = size; for (int c = 0; c < cp.Capacity; c++) { cp.Add(false); } // determine crossover point (randomly) // 随机指定的交叉位置 for (int i = numberOfCrossoverPoints; i > 0; i--) { while (true) { int p = RandomNbr.GetRandomNbr() % size; if (!cp[p]) { cp[p] = true; break; } } } // 分别获取需要进行交叉的两个课表的迭代器的首位 IDictionaryEnumerator it1 = this.classes.GetEnumerator(); IDictionaryEnumerator it2 = parent2.classes.GetEnumerator(); bool first = RandomNbr.GetRandomNbr() % 2 == 0; for (int i = 0; i < size; i++) { it1.MoveNext(); it2.MoveNext(); // crossover point if (cp[i]) { // change source chromosome first = !first; } if (first) { // insert class from first parent into new chromosome's class table if (n.classes.ContainsKey(it1.Key as CourseClass)) { n.classes.Remove(it1.Key as CourseClass); n.classes.Add(it1.Key as CourseClass, (int)it1.Value); } else { n.classes.Add(it1.Key as CourseClass, (int)it1.Value); } // all time-space slots of class are copied for (int j = (it1.Key as CourseClass).GetDuration() - 1; j >= 0; j--) { n.slots[(int)it1.Value + j].Add(it1.Key as CourseClass); } } else { // insert class from second parent into new chromosome's calss table if (n.classes.ContainsKey(it2.Key as CourseClass)) { n.classes.Remove(it2.Key as CourseClass); n.classes.Add(it2.Key as CourseClass, (int)it2.Value); } else { n.classes.Add(it2.Key as CourseClass, (int)it2.Value); } // all time-space slots of class are copied for (int j = (it2.Key as CourseClass).GetDuration() - 1; j >= 0; j--) { n.slots[(int)it2.Value + j].Add(it2.Key as CourseClass); } } } // 计算交叉后染色体的适应值 n.CalculateFitness(); return n; }