/// <summary> /// Crossover operator. /// </summary> /// /// <param name="pair">Pair chromosome to crossover with.</param> /// /// <remarks><para>The method performs crossover between two chromosomes – interchanging /// randomly selected sub trees.</para></remarks> /// public override void Crossover(IChromosome pair) { GPTreeChromosome p = (GPTreeChromosome)pair; // check for correct pair if (p != null) { // do we need to use root node for crossover ? if ((root.Children == null) || (rand.Next(maxLevel) == 0)) { // give the root to the pair and use pair's part as a new root root = p.RandomSwap(root); } else { GPTreeNode node = root; for ( ; ;) { // choose random child int r = rand.Next(node.Gene.ArgumentsCount); GPTreeNode child = null; try { child = (GPTreeNode)node.Children[r]; } catch (ArgumentOutOfRangeException e) { child = node; } // testado mas alterou a forma de trabalho do cross-over //GPTreeNode child = (r <= 0) ? node : (GPTreeNode) node.Children[r]; // swap the random node, if it is an end node or // random generator "selected" this node if ((child.Children == null) || (rand.Next(maxLevel) == 0)) { // swap the node with pair's one try { node.Children[r] = p.RandomSwap(child); } catch (ArgumentOutOfRangeException e) { node.Children.Add(p.RandomSwap(child)); //node = p.RandomSwap(child); } break; } // go further by tree node = child; } } // trim both of them Trim(root, maxLevel); Trim(p.root, maxLevel); } }
/// <summary> /// Initializes a new instance of the <see cref="GPTreeChromosome"/> class. /// </summary> /// /// <param name="source">Source genetic tree to clone from.</param> /// /// <remarks><para>This constructor creates new genetic tree as a copy of the /// specified <paramref name="source"/> tree.</para></remarks> /// protected GPTreeChromosome(GPTreeChromosome source) { root = (GPTreeNode)source.root.Clone( ); fitness = source.fitness; }