public Schedule Crossover(Schedule parent2)
{
Random rand = new Random();
// check probability of crossover operation
if (rand.Next() % 100 > _crossoverProbability)
// no crossover, just copy first parent
return new Schedule(this, false);
// new chromosome object, copy chromosome setup
Schedule n = new Schedule(this, true);
// number of classes
int size = _classes.Count;
bool[] cp = new bool[size];
// determine crossover point (randomly)
for (int i = _numberOfCrossoverPoints; i > 0; i--)
{
while (true)
{
int p = rand.Next() % size;
if (!cp[p])
{
cp[p] = true;
break;
}
}
}
//Dictionary<CourseClass, int> it1 = _classes;
List<KeyValuePair<CourseClass, int>> it1 = _classes.ToList<KeyValuePair<CourseClass, int>>();
//Dictionary<CourseClass, int> it2 = parent2._classes;
List<KeyValuePair<CourseClass, int>> it2 = parent2._classes.ToList<KeyValuePair<CourseClass, int>>();
// make new code by combining parent codes
bool first = (rand.Next() % 2 == 0);
//
for (int i = 0; i < size; i++)
{
if (first)
{
// insert class from first parent into new chromosome's class table
n._classes.Add(it1[i].Key, it1[i].Value);
// all time-space slots of class are copied
for (int j = it1[i].Key.GetDuration - 1; j >= 0; j--)
n._slots[it1[i].Value + j].Add(it1[i].Key);
}
else
{
// insert class from second parent into new chromosome's class table
n._classes.Add(it2[i].Key, it2[i].Value);
// all time-space slots of class are copied
for (int j = it2[i].Key.GetDuration - 1; j >= 0; j--)
n._slots[it2[i].Value + j].Add(it2[i].Key);
}
// crossover point
if (cp[i])
// change source chromosome
first = !first;
}
n.CalculateFitness();
// return smart pointer to offspring
return n;
}