Exemplo n.º 1
0
        /**
         * Recursively travel the tree so that depth and subtree below are computed
         * only once and can be reused later.
         *
         * @param node
         * @param nodeToDepth
         */
        public void TraverseTreeForDepth(GPNode node,
                                         ArrayList nodeToDepth,
                                         Hashtable sizeToNodes)
        {
            GPNode[] children = node.Children;
            NodeInfo nodeInfo = new NodeInfo(node, node.NumNodes(GP.GPNode.NODESEARCH_NONTERMINALS));

            nodeToDepth.Add(nodeInfo);
            // check to see if there is list in map for that size
            LinkedList <NodeInfo> listForSize = (LinkedList <NodeInfo>)sizeToNodes[nodeInfo.NumberOfSubTreesBeneath];

            if (listForSize == null)
            {
                listForSize = new LinkedList <NodeInfo>();
                sizeToNodes[nodeInfo.NumberOfSubTreesBeneath] = listForSize;
            }
            // add it to the list no matter what
            listForSize.AddLast(nodeInfo);
            // recurse
            if (children.Length > 0)
            {
                foreach (GPNode t in children)
                {
                    TraverseTreeForDepth(t, nodeToDepth, sizeToNodes);
                }
            }
        }
Exemplo n.º 2
0
        /// <summary>
        /// Returns true if inner1 can feasibly be swapped into inner2's position
        /// </summary>
        private bool VerifyPoints(GPNode inner1, GPNode inner2)
        {
            // We know they're swap-compatible since we generated inner1
            // to be exactly that.  So don't bother.

            // next check to see if inner1 can fit in inner2's spot
            if (inner1.Depth + inner2.AtDepth() > MaxDepth)
            {
                return(false);
            }

            // check for size
            if (MaxSize != NO_SIZE_LIMIT)
            {
                // first easy check
                var inner1Size = inner1.NumNodes(GPNode.NODESEARCH_ALL);
                var inner2Size = inner2.NumNodes(GPNode.NODESEARCH_ALL);
                if (inner1Size > inner2Size)  // need to test further
                {
                    // let's keep on going for the more complex test
                    GPNode root2     = ((GPTree)(inner2.RootParent())).Child;
                    var    root2Size = root2.NumNodes(GPNode.NODESEARCH_ALL);
                    if (root2Size - inner2Size + inner1Size > MaxSize)  // take root2, remove inner2 and swap in inner1.  Is it still small enough?
                    {
                        return(false);
                    }
                }
            }

            // checks done!
            return(true);
        }
Exemplo n.º 3
0
        private static int NumDemotableNodes(GPInitializer initializer, GPNode root, int soFar, GPFunctionSet funcs)
        {
            // if I have just one type, skip this and just return
            // the number of nonterminals in the tree
            if (initializer.NumAtomicTypes + initializer.NumSetTypes == 1)
            {
                return(root.NumNodes(GPNode.NODESEARCH_ALL));
            }

            // otherwise, I gotta do the dirty work
            return(NumDemotableNodesDirtyWork(initializer, root, soFar, funcs));
        }
Exemplo n.º 4
0
        /// <summary>
        /// Returns true if inner1 can feasibly be swapped into inner2's position.
        /// </summary>
        public bool VerifyPoints(GPInitializer initializer, GPNode inner1, GPNode inner2)
        {
            // first check to see if inner1 is swap-compatible with inner2
            // on a type basis
            if (!inner1.SwapCompatibleWith(initializer, inner2))
            {
                return(false);
            }

            // next check to see if inner1 can fit in inner2's spot
            if (inner1.Depth + inner2.AtDepth() > MaxDepth)
            {
                return(false);
            }

            // check for size
            // NOTE: this is done twice, which is more costly than it should be.  But
            // on the other hand it allows us to toss a child without testing both times
            // and it's simpler to have it all here in the verifyPoints code.
            if (MaxSize != NO_SIZE_LIMIT)
            {
                // first easy check
                var inner1Size = inner1.NumNodes(GPNode.NODESEARCH_ALL);
                var inner2Size = inner2.NumNodes(GPNode.NODESEARCH_ALL);
                if (inner1Size > inner2Size)  // need to test further
                {
                    // let's keep on going for the more complex test
                    var root2     = ((GPTree)(inner2.RootParent())).Child;
                    var root2Size = root2.NumNodes(GPNode.NODESEARCH_ALL);
                    if (root2Size - inner2Size + inner1Size > MaxSize)  // take root2, remove inner2 and swap in inner1.  Is it still small enough?
                    {
                        return(false);
                    }
                }
            }

            // checks done!
            return(true);
        }
Exemplo n.º 5
0
        /**
         * This method finds a node using the logic given in the langdon paper.
         * @param nodeToSubtrees For Tree of Parent2 all precomputed stats about depth,subtrees etc
         * @param sizeToNodes Quick lookup for LinkedList of size to Nodes
         * @param parent1SelectedNode Node selected in parent1
         * @param Tree2 Tree of parent2
         * @param state Evolution State passed for getting access to Random Object of MersenneTwiser
         * @param thread thread number
         */
        protected GPNode FindFairSizeNode(ArrayList nodeToSubtrees,
                                          Hashtable sizeToNodes,
                                          GPNode parent1SelectedNode,
                                          GPTree tree2,
                                          IEvolutionState state,
                                          int thread)
        {
            GPNode selectedNode = null;
            // get the size of subtrees of parent1
            int parent1SubTrees = parent1SelectedNode.NumNodes(GPNode.NODESEARCH_NONTERMINALS);
            // the maximum length in mate we are looking for
            int maxmatesublen = parent1SubTrees == 0 ? 0 : 2 * parent1SubTrees + 1;

            // lets see if for all lengths we have trees corresponding
            bool[] mateSizeAvailable = new bool[maxmatesublen + 1];
            // initialize the array to false
            for (int i = 0; i < maxmatesublen; i++)
            {
                mateSizeAvailable[i] = false;
            }
            // check for ones we have
            for (int i = 0; i < nodeToSubtrees.Count; i++)
            {
                NodeInfo nodeInfo = (NodeInfo)nodeToSubtrees[i];
                // get the length of trees
                int subtree = nodeInfo.NumberOfSubTreesBeneath;
                if (subtree <= maxmatesublen)
                {
                    mateSizeAvailable[subtree] = true;
                }
            }
            // choose matesublen so mean size change=0 if possible
            int countOfPositives = 0;
            int countOfNegatives = 0;
            int sumOfPositives   = 0;
            int sumOfNegatives   = 0;
            int l;

            for (l = 1; l < parent1SubTrees; l++)
            {
                if (mateSizeAvailable[l])
                {
                    countOfNegatives++;
                    sumOfNegatives += parent1SubTrees - l;
                }
            }
            for (l = parent1SubTrees + 1; l <= maxmatesublen; l++)
            {
                if (mateSizeAvailable[l])
                {
                    countOfPositives++;
                    sumOfPositives += l - parent1SubTrees;
                }
            }
            // if they are missing use the same
            int mateSublengthSelected = 0;

            if (sumOfPositives == 0 || sumOfNegatives == 0)
            {
                //if so then check if mate has the length and use that
                if (mateSizeAvailable[parent1SubTrees])
                {
                    mateSublengthSelected = parent1SubTrees;
                }
                //else we go with zero
            }
            else
            {
                // probability of same is dependent on do we find same sub trees
                // else 0.0
                double pzero = (mateSizeAvailable[parent1SubTrees]) ? 1.0 / parent1SubTrees : 0.0;
                // positive probability
                double ppositive = (1.0 - pzero) /
                                   (countOfPositives +
                                    ((double)(countOfNegatives * sumOfPositives) / (sumOfNegatives)));
                // negative probability
                double pnegative = (1.0 - pzero) /
                                   (countOfNegatives +
                                    ((double)(countOfPositives * sumOfNegatives) / (sumOfPositives)));
                // total probability, just for making sure math is right ;-)
                double total = countOfNegatives * pnegative + pzero + countOfPositives * ppositive;
                // putting an assert for floating point calculations, similar to what langdon does
                // assert(total<1.01&&total>.99);
                // now create a Roulette Wheel
                RouletteWheelSelector wheel = new RouletteWheelSelector(maxmatesublen);
                // add probabilities to the wheel
                // all below the length of parent node get pnegative
                // all above get ppositive and one on node gets pzero
                for (l = 1; l < parent1SubTrees; l++)
                {
                    if (mateSizeAvailable[l])
                    {
                        wheel.Add(pnegative, l);
                    }
                }
                if (mateSizeAvailable[parent1SubTrees])
                {
                    wheel.Add(pzero, parent1SubTrees);
                }
                for (l = parent1SubTrees + 1; l <= maxmatesublen; l++)
                {
                    if (mateSizeAvailable[l])
                    {
                        wheel.Add(ppositive, l);
                    }
                }
                // spin the wheel
                mateSublengthSelected = wheel.Roulette(state, thread);
            }
            // now we have length chosen, but there can be many nodes with that
            //
            LinkedList <NodeInfo> listOfNodes = (LinkedList <NodeInfo>)sizeToNodes[mateSublengthSelected];

            if (listOfNodes == null)
            {
                state.Output.Fatal("In SizeFairCrossoverPipeline, nodes for tree length " + mateSublengthSelected + " is null, indicates some serious error");
            }
            // in size fair we choose the elements at random for given length
            int chosenNode = 0;

            // if using fair size get random from the list
            if (!Homologous)
            {
                chosenNode = state.Random[thread].NextInt(listOfNodes.Count);
            }
            // if Homologous
            else
            {
                if (listOfNodes.Count > 1)
                {
                    GPInitializer initializer        = ((GPInitializer)state.Initializer);
                    int           currentMinDistance = int.MaxValue;
                    for (int i = 0; i < listOfNodes.Count; i++)
                    {
                        // get the GP node
                        GPNode selectedMateNode = listOfNodes.ElementAt(i).Node;
                        // now lets traverse selected and parent 1 to see divergence
                        GPNode currentMateNode    = selectedMateNode;
                        GPNode currentParent1Node = parent1SelectedNode;
                        // found a match?
                        bool foundAMatchInAncestor = false;
                        int  distance = 0;
                        while (currentMateNode.Parent != null &&
                               currentMateNode.Parent is GPNode &&
                               currentParent1Node.Parent != null &&
                               currentParent1Node.Parent is GPNode &&
                               !foundAMatchInAncestor)
                        {
                            GPNode parent1 = (GPNode)currentParent1Node.Parent;
                            GPNode parent2 = (GPNode)currentMateNode.Parent;
                            // if there is match between compatibility of Parents break
                            if (parent1.SwapCompatibleWith(initializer, parent2))
                            {
                                foundAMatchInAncestor = true;
                                break;
                            }
                            else
                            {
                                // need to go one level above of both
                                currentMateNode    = parent2;
                                currentParent1Node = parent1;
                                //increment the distance
                                distance = distance + 1;
                            }
                        }
                        // find the one with least distance
                        if (distance < currentMinDistance)
                        {
                            currentMinDistance = distance;
                            chosenNode         = i;
                        }
                    }
                }
                // else take the first node, no choice
            }
            NodeInfo nodeInfoSelected = listOfNodes.ElementAt(chosenNode);

            selectedNode = nodeInfoSelected.Node;

            return(selectedNode);
        }
Exemplo n.º 6
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);
        }