Accord.Genetic.GPTreeChromosome.RandomSwap C# (CSharp) Method

RandomSwap() private method

Crossover helper routine - selects random node of chromosomes tree and swaps it with specified node.
private RandomSwap ( GPTreeNode source ) : GPTreeNode
source GPTreeNode
return GPTreeNode
        private GPTreeNode RandomSwap(GPTreeNode source)
        {
            var rand = Generator.Random;
            GPTreeNode retNode = null;

            // swap root node ?
            if ((root.Children == null) || (rand.Next(maxLevel) == 0))
            {
                // replace current root and return it
                retNode = root;
                root = source;
            }
            else
            {
                GPTreeNode node = root;

                for (; ; )
                {
                    // choose random child
                    int r = rand.Next(node.Gene.ArgumentsCount);
                    GPTreeNode child = (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
                        retNode = child;
                        node.Children[r] = source;
                        break;
                    }

                    // go further by tree
                    node = child;
                }
            }
            return retNode;
        }

Usage Example

        /// <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)
        {
            var rand           = Generator.Random;
            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 = (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
                            node.Children[r] = p.RandomSwap(child);
                            break;
                        }

                        // go further by tree
                        node = child;
                    }
                }
                // trim both of them
                Trim(root, maxLevel);
                Trim(p.root, maxLevel);
            }
        }