Пример #1
0
        public static string ToNormalNotation(GPTreeNode curNode)
        {
            var sb = new StringBuilder();

            if ((curNode.Children != null) && (curNode.Children.Count > 0))
            {
                sb.Append("(");
                if (curNode.Children.Count == 1)
                {
                    //if node's gene is a 1-arg function, write (op child1)
                    sb.AppendFormat("{0} {1}", curNode.Gene, ToNormalNotation(curNode.Children[0]));
                }
                else
                {
                    //else, write expression (child1 op child2)
                    sb.AppendFormat("{0} {1} {2}",
                                    ToNormalNotation(curNode.Children[0]), curNode.Gene,
                                    ToNormalNotation(curNode.Children[1]));
                }
                sb.Append(")");
            }
            else
            {
                //else just write the gene string rep
                sb.Append(curNode.Gene.ToString());
            }

            return(sb.ToString());
        }
Пример #2
0
        protected static void ProcessNode(GPTreeNode curNode, Stack <GPTreeNode> nodeStack)
        {
            //processes each expected child node
            var argumentsCount = curNode.Gene.ArgumentsCount;

            for (var i = 0; i < argumentsCount; i++)
            {
                if (nodeStack.Count == 0)
                {
                    return;
                }

                //gets child node from stack, if possible, and processes that node
                var childNode = nodeStack.Pop();
                if (curNode.Children == null)
                {
                    curNode.Children = new List <GPTreeNode>(argumentsCount);
                }
                curNode.Children.Add(childNode);
                ProcessNode(childNode, nodeStack);
            }

            //reverse order of children for correct order
            if (argumentsCount == 0)
            {
                return;
            }
            curNode.Children.Reverse();
        }
Пример #3
0
        public static uint GetDepth(GPTreeNode curNode, uint curDepth)
        {
            //for each child determines depth by adding one level, return max child depth
            if ((curNode.Children != null) && (curNode.Children.Count > 0))
            {
                return(curNode.Children.Max(child => GetDepth(child, curDepth + 1)));
            }

            //or else just return current depth
            return(curDepth);
        }
Пример #4
0
        public static List <GPTreeNode> GetAllChildren(GPTreeNode node)
        {
            var children = new List <GPTreeNode> {
                node
            };

            if ((node.Children != null) && (node.Children.Count > 0))
            {
                foreach (var child in node.Children)
                {
                    children.AddRange(GetAllChildren(child));
                }
            }
            return(children);
        }
Пример #5
0
        public static HashSet <ChromosomeParameters> GenerateAllCombinations(GPTreeNode node)
        {
            var combChromosomes = new HashSet <ChromosomeParameters>();

            //tests end condition, ie no more children, add node itself
            if ((node.Children == null) || (node.Children.Count == 0))
            {
                combChromosomes.Add(new ChromosomeParameters {
                    ProgramExpression = node.ToString()
                });
                return(combChromosomes);
            }

            //add all combinations from each child
            foreach (var child in node.Children)
            {
                combChromosomes.UnionWith(GenerateAllCombinations(child));
            }

            //for one argument functions, gets children
            var children0 = GetAllChildren(node.Children[0]);

            //creates combinations for all children
            foreach (var child0 in children0)
            {
                var newNode = (GPTreeNode)node.Clone();
                newNode.Children[0] = child0;
                combChromosomes.Add(new ChromosomeParameters {
                    ProgramExpression = newNode.ToString()
                });
            }

            //for two argument functions
            if (node.Children.Count < 2)
            {
                return(combChromosomes);
            }

            //gets children from both sides
            var children1 = GetAllChildren(node.Children[1]);

            //creates combinations between the different children
            foreach (var child0 in children0)
            {
                foreach (var child1 in children1)
                {
                    var newNode = (GPTreeNode)node.Clone();
                    newNode.Children[0] = child0;
                    newNode.Children[1] = child1;
                    combChromosomes.Add(new ChromosomeParameters {
                        ProgramExpression = newNode.ToString()
                    });
                }
            }

            //if function is subtraction
            if (!node.Gene.ToString().Equals(RewardGeneFunction.GetFunctionTypeString(FunctionType.Subtract)))
            {
                return(combChromosomes);
            }

            //consider right side negative by adding "0 - 'childNode'"
            foreach (var child1 in children1)
            {
                var newNode = (GPTreeNode)node.Clone();
                newNode.Children[0] = ZeroNode;
                newNode.Children[1] = child1;
                combChromosomes.Add(new ChromosomeParameters {
                    ProgramExpression = newNode.ToString()
                });
            }

            return(combChromosomes);
        }
 /// <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;
 }
        /// <summary>
        /// Crossover helper routine - selects random node of chromosomes tree and
        /// swaps it with specified node.
        /// </summary>
        private GPTreeNode RandomSwap( GPTreeNode source )
        {
            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 = null;

                    try
                    {
                        child = (GPTreeNode) node.Children[r];
                    }
                    catch (ArgumentOutOfRangeException e)
                    {
                        child = node;
                    }

                    // 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;
                        try
                        {
                            node.Children[r] = source;
                        }
                        catch (ArgumentOutOfRangeException e)
                        {
                            node.Children.Add(source);
                            //node = source;
                        }
                        break;
                    }

                    // go further by tree
                    node = child;
                }
            }
            return retNode;
        }
 /// <summary>
 /// Trim tree node, so its depth does not exceed specified level.
 /// </summary>
 private static void Trim( GPTreeNode 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 ( GPTreeNode n in node.Children )
             {
                 Trim( n, level - 1 );
             }
         }
     }
 }
        /// <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( GPTreeNode node, int level )
        {
            // create gene for the node
            if ( level == 0 )
            {
                // the gene should be an argument or constant
                node.Gene = root.Gene.CreateNew((rand.Next(4) >= 2) ? GPGeneType.Constant : GPGeneType.Argument); //GPGeneType.Argument
            }
            else
            {
                // the gene can be function or argument or constant
                node.Gene = root.Gene.CreateNew( );
            }

            // add children
            if ( node.Gene.ArgumentsCount != 0 )
            {
                node.Children = new List<GPTreeNode>( );
                for ( int i = 0; i < node.Gene.ArgumentsCount; i++ )
                {
                    // create new child
                    GPTreeNode child = new GPTreeNode( );
                    Generate( child, level - 1 );
                    // add the new child
                    node.Children.Add( child );
                }
            }
        }
        /// <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
            GPTreeNode	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
                        Generate( node, rand.Next( maxLevel - currentLevel ) );
                    }
                    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<GPTreeNode>( );

                        // 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
                                    GPTreeNode child = new GPTreeNode( );
                                    Generate( child, rand.Next( maxLevel - currentLevel ) );
                                    // add the new child
                                    node.Children.Add( child );
                                }
                            }
                        }
                    }
                    break;
                }

                // mutation goes further to one of the children
                node = (GPTreeNode) node.Children[r];
                currentLevel++;
            }
        }
 /// <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<GPTreeNode>( );
         for ( int i = 0; i < root.Gene.ArgumentsCount; i++ )
         {
             // create new child
             GPTreeNode child = new GPTreeNode( );
             Generate( child, rand.Next( maxInitialLevel ) );
             // add the new child
             root.Children.Add( child );
         }
     }
 }
        /// <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>
        /// Get tree representation of the chromosome.
        /// </summary>
        /// 
        /// <returns>Returns expression's tree represented by the chromosome.</returns>
        /// 
        /// <remarks><para>The method builds expression's tree for the native linear representation
        /// of the GEP chromosome.</para></remarks>
        /// 
        protected GPTreeNode GetTree( )
        {
            // function node queue. the queue contains function node,
            // which requires children. when a function node receives
            // all children, it will be removed from the queue
            Queue functionNodes = new Queue( );

            // create root node
            GPTreeNode root = new GPTreeNode( genes[0] );

            // check children amount of the root node
            if ( root.Gene.ArgumentsCount != 0 )
            {
                root.Children = new List<GPTreeNode>( );
                // place the root to the queue
                functionNodes.Enqueue( root );

                // go through genes
                for ( int i = 1; i < length; i++ )
                {
                    // create new node
                    GPTreeNode node = new GPTreeNode( genes[i] );

                    // if next gene represents function, place it to the queue
                    if ( genes[i].GeneType == GPGeneType.Function )
                    {
                        node.Children = new List<GPTreeNode>( );
                        functionNodes.Enqueue( node );
                    }

                    // get function node from the top of the queue
                    GPTreeNode parent = (GPTreeNode) functionNodes.Peek( );

                    // add new node to children of the parent node
                    parent.Children.Add( node );

                    // remove the parent node from the queue, if it is
                    // already complete
                    if ( parent.Children.Count == parent.Gene.ArgumentsCount )
                    {
                        functionNodes.Dequeue( );

                        // check the queue if it is empty
                        if ( functionNodes.Count == 0 )
                            break;
                    }
                }
            }
            // return formed tree
            return root;
        }