private void CreateChildUsingCrossover(ushort[] parent1, ushort[] parent2, ushort[] child)
{
var rand = Generator.Random;
ushort[] indexDictionary1 = CreateIndexDictionary(parent1);
ushort[] indexDictionary2 = CreateIndexDictionary(parent2);
// temporary array to specify if certain gene already
// present in the child
bool[] geneIsBusy = new bool[length];
// previous gene in the child and two next candidates
ushort prev, next1, next2;
// candidates validness - candidate is valid, if it is not
// yet in the child
bool valid1, valid2;
int j, k = length - 1;
// first gene of the child is taken from the second parent
prev = child[0] = parent2[0];
geneIsBusy[prev] = true;
// resolve all other genes of the child
for (int i = 1; i < length; i++)
{
// find the next gene after PREV in both parents
// 1
j = indexDictionary1[prev];
next1 = (j == k) ? parent1[0] : parent1[j + 1];
// 2
j = indexDictionary2[prev];
next2 = (j == k) ? parent2[0] : parent2[j + 1];
// check candidate genes for validness
valid1 = !geneIsBusy[next1];
valid2 = !geneIsBusy[next2];
// select gene
if (valid1 && valid2)
{
// both candidates are valid
// select one of theme randomly
prev = (rand.Next(2) == 0) ? next1 : next2;
}
else if (!(valid1 || valid2))
{
// none of candidates is valid, so
// select random gene which is not in the child yet
int r = j = rand.Next(length);
// go down first
while ((r < length) && (geneIsBusy[r] == true))
r++;
if (r == length)
{
// not found, try to go up
r = j - 1;
while (geneIsBusy[r] == true) // && ( r >= 0 )
r--;
}
prev = (ushort)r;
}
else
{
// one of candidates is valid
prev = (valid1) ? next1 : next2;
}
child[i] = prev;
geneIsBusy[prev] = true;
}
}