Represents tree node of genetic programming tree.

In genetic programming a chromosome is represented by a tree, which is represented by GPTreeChromosome class. The GPTreeNode class represents single node of such genetic programming tree.

Each node may or may not have children. This means that particular node of a genetic programming tree may represent its sub tree or even entire tree.

Наследование: ICloneable
Пример #1
0
        /// <summary>
        /// Clone the tree node.
        /// </summary>
        /// 
        /// <returns>Returns exact clone of the node.</returns>
        /// 
        public object Clone()
        {
            GPCustomTreeNode clone = new GPCustomTreeNode();

            // clone gene
            clone.Gene = this.Gene.Clone();
            // clone its children
            if (this.Children != null)
            {
                clone.Children = new List<GPCustomTreeNode>();
                // clone each child gene
                foreach (GPCustomTreeNode node in Children)
                {
                    clone.Children.Add((GPCustomTreeNode)node.Clone());
                }
            }
            return clone;
        }
Пример #2
0
 public GPCustomTreeNode Repeat(int n)
 {
     GPCustomTreeNode t = this.Clone() as GPCustomTreeNode;
     GPCustomTreeNode root = new GPCustomTreeNode(new NoteGene(0, 0, 0, NoteGene.FunctionTypes.Concatenation, GPGeneType.Function));
     while(n>0)
     {
         root.Children = new List<GPCustomTreeNode>();
         root.Children.Add(this.Clone() as GPCustomTreeNode);
         root.Children.Add(new GPCustomTreeNode(new NoteGene(0, 0, 0, NoteGene.FunctionTypes.Concatenation, GPGeneType.Function)));
         root = root.Children[1];
         n--;
     }
     return root;
 }
Пример #3
0
        /// <summary>
        /// Crossover helper routine - selects random node of chromosomes tree and
        /// swaps it with specified node.
        /// </summary>
        private GPCustomTreeNode RandomSwap(GPCustomTreeNode source)
        {
            GPCustomTreeNode retNode = null;

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

                for (; ; )
                {
                    // choose random child
                    int r = rand.Next(node.Gene.ArgumentsCount);
                    GPCustomTreeNode child = (GPCustomTreeNode)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;
        }
Пример #4
0
 /// <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 GPCustomTree(GPCustomTree source)
 {
     root = (GPCustomTreeNode)source.root.Clone();
     fitness = source.fitness;
 }
Пример #5
0
 /// <summary>
 /// Trim tree node, so its depth does not exceed specified level.
 /// </summary>
 private static void Trim(GPCustomTreeNode node, int level)
 {
     // check if the node has children
     if (node.Children != null)
     {
         if (level == 0)
         {
             // remove all children
             node.Children = null;
             // and make the node of argument type
             node.Gene.Generate(GPGeneType.Argument);
         }
         else
         {
             // go further to children
             foreach (GPCustomTreeNode n in node.Children)
             {
                 Trim(n, level - 1);
             }
         }
     }
 }
Пример #6
0
        /// <summary>
        /// Generate chromosome's subtree of specified level.
        /// </summary>
        /// 
        /// <param name="node">Sub tree's node to generate.</param>
        /// <param name="level">Sub tree's level to generate.</param>
        /// 
        protected void Generate(GPCustomTreeNode node, int level)
        {
            if(generator != null)
            {
                if (level == 0)
                {
                    node.Gene = root.Gene.CreateNew(GPGeneType.Argument);
                }
                else
                {
                    var notes = generator.Generate();
                    List<Note> notes_cut = new List<Note>();
                    int j = 0;
                    int max = (int)Math.Pow(2,level-1);
                    foreach(Note n in notes.Notes)
                    {
                        if(j>max)
                        {
                            if (n.Velocity <= 0 || n.Pitch < 0)
                                break;
                        }
                        notes_cut.Add(n);
                    }
                    node.Generate(notes_cut);
                }
                return;
            }

            /// OLD !!!
            // create gene for the node
            if (level == 0)
            {
                // the gene should be an argument
                node.Gene = root.Gene.CreateNew(GPGeneType.Argument);
            }
            else
            {
                // the gene can be function or argument
                node.Gene = root.Gene.CreateNew();
            }

            // add children
            if (node.Gene.ArgumentsCount != 0)
            {
                node.Children = new List<GPCustomTreeNode>();
                for (int i = 0; i < node.Gene.ArgumentsCount; i++)
                {
                    // create new child
                    GPCustomTreeNode child = new GPCustomTreeNode();
                    Generate(child, level - 1);
                    // add the new child
                    node.Children.Add(child);
                }
            }
        }
Пример #7
0
        /// <summary>
        /// Mutation operator.
        /// </summary>
        /// 
        /// <remarks><para>The method performs chromosome's mutation by regenerating tree's
        /// randomly selected node.</para></remarks>
        ///
        public override void Mutate()
        {
            // current tree level
            int currentLevel = 0;
            // current node
            GPCustomTreeNode node = root;

            for (; ; )
            {
                // regenerate node if it does not have children
                if (node.Children == null)
                {
                    if (currentLevel == maxLevel)
                    {
                        // we reached maximum possible level, so the gene
                        // can be an argument only
                        node.Gene.Generate(GPGeneType.Argument);
                    }
                    else
                    {
                        // generate subtree
                        int level = maxLevel - currentLevel;
                        if (level < 0)
                            level = 0;
                        Generate(node, rand.Next(level));
                    }
                    break;
                }

                // if it is a function node, than we need to get a decision, about
                // mutation point - the node itself or one of its children
                int r = rand.Next(node.Gene.ArgumentsCount + 1);

                if (r == node.Gene.ArgumentsCount)
                {
                    // node itself should be regenerated
                    node.Gene.Generate();

                    // check current type
                    if (node.Gene.GeneType == GPGeneType.Argument)
                    {
                        node.Children = null;
                    }
                    else
                    {
                        // create children's list if it was absent
                        if (node.Children == null)
                            node.Children = new List<GPCustomTreeNode>();

                        // check for missing or extra children
                        if (node.Children.Count != node.Gene.ArgumentsCount)
                        {
                            if (node.Children.Count > node.Gene.ArgumentsCount)
                            {
                                // remove extra children
                                node.Children.RemoveRange(node.Gene.ArgumentsCount, node.Children.Count - node.Gene.ArgumentsCount);
                            }
                            else
                            {
                                // add missing children
                                for (int i = node.Children.Count; i < node.Gene.ArgumentsCount; i++)
                                {
                                    // create new child
                                    GPCustomTreeNode child = new GPCustomTreeNode();
                                    Generate(child, rand.Next(maxLevel - currentLevel));
                                    // add the new child
                                    node.Children.Add(child);
                                }
                            }
                        }
                    }
                    break;
                }

                // mutation goes further to one of the children
                node = (GPCustomTreeNode)node.Children[r];
                currentLevel++;
            }
        }
Пример #8
0
        /// <summary>
        /// Generate random chromosome value.
        /// </summary>
        /// 
        /// <remarks><para>Regenerates chromosome's value using random number generator.</para>
        /// </remarks>
        ///
        public override void Generate()
        {
            // randomize the root
            root.Gene.Generate();
            // create children
            if (root.Gene.ArgumentsCount != 0)
            {
                root.Children = new List<GPCustomTreeNode>();
                for (int i = 0; i < root.Gene.ArgumentsCount; i++)
                {
                    // create new child

                    GPCustomTreeNode child = new GPCustomTreeNode();
                    Generate(child, rand.Next(maxInitialLevel));
                    // add the new child
                    root.Children.Add(child);
                }
            }
        }
Пример #9
0
        /// <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)
        {
            GPCustomTree p = (GPCustomTree)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
                {
                    GPCustomTreeNode node = root;

                    for (; ; )
                    {
                        // choose random child
                        int r = rand.Next(node.Gene.ArgumentsCount);
                        GPCustomTreeNode child = (GPCustomTreeNode)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);
            }
        }