/// <summary>
        /// Returns true if inner1 can feasibly be swapped into inner2's position.
        /// </summary>
        private 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);
            }

            // checks done!
            return(true);
        }
Example #2
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);
        }
Example #3
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);
        }