AForge.Genetic.GPCustomTree.Mutate C# (CSharp) Method

Mutate() public method

Mutation operator.

The method performs chromosome's mutation by regenerating tree's randomly selected node.

public Mutate ( ) : void
return void
        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++;
            }
        }

Usage Example

コード例 #1
0
        public MelodySequence Generate()
        {
            NoteGene baseGene = new NoteGene(GPGeneType.Function);
            baseGene.Function = NoteGene.FunctionTypes.Concatenation;
            GPCustomTree tree = new GPCustomTree(baseGene);
            if (base_seq != null)
            {
                tree.Generate(base_seq.ToArray());
                tree.Mutate();
                tree.Crossover(tree);

                int length = base_seq.Length;
                int depth = (int)Math.Ceiling(Math.Log(length, 2));
                GPCustomTree.MaxInitialLevel = depth - 2;
                GPCustomTree.MaxLevel = depth + 5;
            }
            var selection = new EliteSelection();
            pop = new Population(30, tree, fitnessFunction, selection);

            pop.AutoShuffling = true;
            pop.CrossoverRate = 0.9;
            pop.MutationRate = 0.1;

            int percentage = MaxGenerations / 100;

            for (int i = 0; i < MaxGenerations; i++)
            {
                if(i>percentage)
                {
                    if (OnPercentage != null)
                        OnPercentage(this, i, pop.FitnessAvg);
                    percentage += MaxGenerations / 100;
                }

                pop.RunEpoch();
                if ((int)(i) % 100 == 0)
                    Console.WriteLine(i / (float)MaxGenerations * 100 + "% : " + pop.FitnessAvg);
            }

            GPCustomTree best = pop.BestChromosome as GPCustomTree;
            var notes = best.GenerateNotes();
            return new MelodySequence(notes);
        }