// Makes new chromosome with same setup but with randomly chosen code public Schedule MakeNewFromPrototype() { // make new chromosome, copy chromosome setup var newChromosome = Copy(this, true); // place classes at random position var c = Configuration.CourseClasses; int nr = Configuration.NumberOfRooms; foreach (var courseClass in c) { // determine random position of class int dur = courseClass.Duration; int day = Configuration.Rand() % Constant.DAYS_NUM; int room = Configuration.Rand() % nr; int time = Configuration.Rand() % (Constant.DAY_HOURS + 1 - dur); var reservation = new Reservation(nr, day, time, room); // fill time-space slots, for each hour of class for (int i = dur - 1; i >= 0; i--) { newChromosome.Slots[reservation.GetHashCode() + i].Add(courseClass); } // insert in class table of chromosome newChromosome.Classes[courseClass] = reservation; } newChromosome.CalculateFitness(); return(newChromosome); }
protected T[] Replacement(T[] population) { // produce offspring var offspring = new T[_replaceByGeneration]; for (int j = 0; j < _replaceByGeneration; j++) { var parent = Selection(population); offspring[j] = parent[0].Crossover(parent[1], _numberOfCrossoverPoints, _crossoverProbability); offspring[j].Mutation(_mutationSize, _mutationProbability); // replace chromosomes of current operation with offspring int ci; do { // select chromosome for replacement randomly ci = Configuration.Rand() % population.Length; // protect best chromosomes from replacement } while (IsInBest(ci)); // replace chromosomes population[ci] = offspring[j]; // try to add new chromosomes in best chromosome group AddToBest(ci); } return(offspring); }
protected T[] Selection(T[] population) { // selects parent randomly var p1 = population[Configuration.Rand() % population.Length]; var p2 = population[Configuration.Rand() % population.Length]; return(new T[] { p1, p2 }); }
// Performs mutation on chromosome public void Mutation(int mutationSize, float mutationProbability) { // check probability of mutation operation if (Configuration.Rand() % 100 > mutationProbability) { return; } // number of classes int numberOfClasses = Classes.Count; int nr = Configuration.NumberOfRooms; // move selected number of classes at random position for (int i = mutationSize; i > 0; i--) { // select ranom chromosome for movement int mpos = Configuration.Rand() % numberOfClasses; // current time-space slot used by class var cc1 = Classes.Keys.ElementAt(mpos); var reservation1 = Classes[cc1]; // determine position of class randomly int dur = cc1.Duration; int day = Configuration.Rand() % Constant.DAYS_NUM; int room = Configuration.Rand() % nr; int time = Configuration.Rand() % (Constant.DAY_HOURS + 1 - dur); var reservation2 = new Reservation(nr, day, time, room); // move all time-space slots for (int j = dur - 1; j >= 0; j--) { // remove class hour from current time-space slot var cl = Slots[reservation1.GetHashCode() + j]; cl.RemoveAll(cc => cc == cc1); // move class hour to new time-space slot Slots[reservation2.GetHashCode() + j].Add(cc1); } // change entry of class table to point to new time-space slots Classes[cc1] = reservation2; } CalculateFitness(); }
private void CreateOffspringPopulation() { int r1, r2, r3; for (int i = 0; i < _populationSize; ++i) { do { r1 = Configuration.Rand(_currentArchiveSize); } while (_archivePopulation[r1].Equals(_archivePopulation[i])); do { r2 = Configuration.Rand(_currentArchiveSize); } while (_archivePopulation[r2].Equals(_archivePopulation[i]) || r2 == r1); do { r3 = Configuration.Rand(_currentArchiveSize); } while (_archivePopulation[r3].Equals(_archivePopulation[i]) || r3 == r1 || r3 == r2); _offspringPopulation[i] = _offspringPopulation[i].Crossover(_parentPopulation[i], _archivePopulation[r1], _archivePopulation[r2], _archivePopulation[r3], _etaCross, _crossoverProbability); _offspringPopulation[i].Rank = _parentPopulation[i].Rank; //for rank based mutation } }
// Performes crossover operation using to chromosomes and returns pointer to offspring public Schedule Crossover(Schedule parent2, int numberOfCrossoverPoints, float crossoverProbability) { // check probability of crossover operation if (Configuration.Rand() % 100 > crossoverProbability) { // no crossover, just copy first parent return(Copy(this, false)); } // new chromosome object, copy chromosome setup var n = Copy(this, true); // number of classes int size = Classes.Count; var cp = new bool[size]; // determine crossover point (randomly) for (int i = numberOfCrossoverPoints; i > 0; i--) { for (; ;) { int p = Configuration.Rand() % size; if (!cp[p]) { cp[p] = true; break; } } } // make new code by combining parent codes bool first = Configuration.Rand() % 2 == 0; for (int i = 0; i < size; ++i) { if (first) { var courseClass = Classes.Keys.ElementAt(i); var reservation = Classes[courseClass]; // insert class from first parent into new chromosome's class table n.Classes[courseClass] = reservation; // all time-space slots of class are copied for (int j = courseClass.Duration - 1; j >= 0; j--) { n.Slots[reservation.GetHashCode() + j].Add(courseClass); } } else { var courseClass = parent2.Classes.Keys.ElementAt(i); var reservation = parent2.Classes[courseClass]; // insert class from second parent into new chromosome's class table n.Classes[courseClass] = reservation; // all time-space slots of class are copied for (int j = courseClass.Duration - 1; j >= 0; j--) { n.Slots[reservation.GetHashCode() + j].Add(courseClass); } } // crossover point if (cp[i]) { // change source chromosome first = !first; } } n.CalculateFitness(); // return smart pointer to offspring return(n); }
// Performes crossover operation using to chromosomes and returns pointer to offspring public Schedule Crossover(Schedule parent, Schedule r1, Schedule r2, Schedule r3, float etaCross, float crossoverProbability) { // number of classes int size = Classes.Count; int jrand = Configuration.Rand(size); // new chromosome object, copy chromosome setup var n = Copy(this, true); int nr = Configuration.NumberOfRooms; for (int i = 0; i < size; ++i) { // check probability of crossover operation if (Configuration.Rand() % 100 > crossoverProbability || i == jrand) { var courseClass = Classes.Keys.ElementAt(i); var reservation1 = r1.Classes[courseClass]; var reservation2 = r2.Classes[courseClass]; var reservation3 = r3.Classes[courseClass]; // determine random position of class int dur = courseClass.Duration; int day = (int)(reservation3.Day + etaCross * (reservation1.Day - reservation2.Day)); if (day < 0) { day = 0; } else if (day >= Constant.DAYS_NUM) { day = Constant.DAYS_NUM - 1; } int room = (int)(reservation3.Room + etaCross * (reservation1.Room - reservation2.Room)); if (room < 0) { room = 0; } else if (room >= nr) { room = nr - 1; } int time = (int)(reservation3.Time + etaCross * (reservation1.Time - reservation2.Time)); if (time < 0) { time = 0; } else if (time >= (Constant.DAY_HOURS + 1 - dur)) { time = Constant.DAY_HOURS - dur; } var reservation = new Reservation(nr, day, time, room); // fill time-space slots, for each hour of class for (int j = courseClass.Duration - 1; j >= 0; --j) { n.Slots[reservation.GetHashCode() + j].Add(courseClass); } // insert in class table of chromosome n.Classes[courseClass] = reservation; } else { var courseClass = parent.Classes.Keys.ElementAt(i); var reservation = parent.Classes[courseClass]; // insert class from second parent into new chromosome's class table n.Classes[courseClass] = reservation; // all time-space slots of class are copied for (int j = courseClass.Duration - 1; j >= 0; --j) { n.Slots[reservation.GetHashCode() + j].Add(courseClass); } } } n.CalculateFitness(); // return smart pointer to offspring return(n); }