예제 #1
0
        public override int Produce(
            int min,
            int max,
            int subpop,
            IList <Individual> inds,
            IEvolutionState state,
            int thread,
            IDictionary <string, object> misc)
        {
            int start = inds.Count;

            // grab individuals from our source and stick 'em right into inds.
            // we'll modify them from there
            var n = Sources[0].Produce(min, max, subpop, inds, state, thread, misc);

            // should we bother?
            if (!state.Random[thread].NextBoolean(Likelihood))
            {
                return(n);
            }

            var initializer = ((GPInitializer)state.Initializer);

            // now let's mutate 'em
            for (var q = start; q < n + start; q++)
            {
                var i = (GPIndividual)inds[q];

                if (Tree != TREE_UNFIXED && (Tree < 0 || Tree >= i.Trees.Length))
                {
                    // uh oh
                    state.Output.Fatal("GP Mutation Pipeline attempted to fix Tree.0 to a value which was out of bounds"
                                       + " of the array of the individual's Trees.  Check the pipeline's fixed Tree values"
                                       + " -- they may be negative or greater than the number of Trees in an individual");
                }


                int t;
                // pick random Tree
                if (Tree == TREE_UNFIXED)
                {
                    if (i.Trees.Length > 1)
                    {
                        t = state.Random[thread].NextInt(i.Trees.Length);
                    }
                    else
                    {
                        t = 0;
                    }
                }
                else
                {
                    t = Tree;
                }

                // validity result...
                var res = false;

                // prepare the NodeSelector
                NodeSelect.Reset();

                // pick a node

                GPNode p1 = null; // the node we pick
                GPNode p2 = null;

                for (var x = 0; x < NumTries; x++)
                {
                    // pick a node in individual 1
                    p1 = NodeSelect.PickNode(state, subpop, thread, i, i.Trees[t]);

                    // generate a Tree swap-compatible with p1's position


                    var size = GPNodeBuilder.NOSIZEGIVEN;
                    if (EqualSize)
                    {
                        size = p1.NumNodes(GPNode.NODESEARCH_ALL);
                    }

                    p2 = Builder.NewRootedTree(state, p1.ParentType(initializer), thread, p1.Parent,
                                               i.Trees[t].Constraints(initializer).FunctionSet, p1.ArgPosition, size);

                    // check for depth and swap-compatibility limits
                    res = VerifyPoints(p2, p1); // p2 can fit in p1's spot  -- the order is important!

                    // did we get something that had both nodes verified?
                    if (res)
                    {
                        break;
                    }
                }

                if (res)
                // we're in business
                {
                    p2.Parent      = p1.Parent;
                    p2.ArgPosition = p1.ArgPosition;
                    if (p2.Parent is GPNode)
                    {
                        ((GPNode)p2.Parent).Children[p2.ArgPosition] = p2;
                    }
                    else
                    {
                        ((GPTree)p2.Parent).Child = p2;
                    }
                    i.Evaluated = false; // we've modified it
                }

                // add the new individual, replacing its previous source
                inds[q] = i;
            }
            return(n);
        }