Example #1
0
        public void GPNodeWriteAndRead()
        {
            var state       = new SimpleEvolutionState();
            var initializer = new GPInitializer();

            state.Initializer = initializer; // Ensure that our initializer is accessible

            var treeConstraints = new GPTreeConstraints();

            initializer.TreeConstraints = new List <GPTreeConstraints>();
            initializer.TreeConstraints.Add(treeConstraints); // Ensure that our constraints are accessible

            var nodeConstraints = new GPNodeConstraints();

            var rootType = new GPAtomicType("MyRootType");

            treeConstraints.TreeType = rootType;
            var root = new MyRootNode();
            var tree = new GPTree {
                Child = root
            };

            root.Parent      = tree;
            root.ArgPosition = 0; // This is the root, so there is only one position (0)
        }
Example #2
0
        public virtual BigInteger NumTreesRootedByNode(GPInitializer initializer, int functionset, GPNode node, int size)
        {
            if (NUMTREESROOTEDBYNODE[functionset][IntForNode(node)][size] == BigInteger.Zero)
            {
                var one   = BigInteger.One;
                var count = BigInteger.Zero;
                var outof = size - 1;

                if (node.Children.Length == 0 && outof == 0)
                {
                    // a valid terminal
                    count = one;
                }

                else if (node.Children.Length <= outof)
                {
                    // a valid nonterminal
                    for (var s = 1; s <= outof; s++)
                    {
                        count = BigInteger.Add(count, NumChildPermutations(initializer, functionset, node, s, outof, 0));
                    }
                }

                //System.out.PrintLn("Node: " + node + " Size: " + size + " Count: " +count);
                NUMTREESROOTEDBYNODE[functionset][IntForNode(node)][size] = count;
            }
            return(NUMTREESROOTEDBYNODE[functionset][IntForNode(node)][size]);
        }
Example #3
0
        private static bool Promotable(GPInitializer initializer, GPNode node)
        {
            // A node is promotable if:
            // 1: its parent is a GPNode
            if (!(node.Parent is GPNode))
            {
                return(false);
            }
            var parent = (GPNode)(node.Parent);

            GPType t;

            if (parent.Parent is GPNode)
            {
                // ugh, expensive
                t = ((GPNode)parent.Parent).Constraints(initializer).ChildTypes[parent.ArgPosition];
            }
            else
            {
                t = ((GPTree)parent.Parent).Constraints(initializer).TreeType;
            }

            // 2: the node's returntype is type-compatible with its GRANDparent's return slot
            return(node.Constraints(initializer).ReturnType.CompatibleWith(initializer, t));
        }
Example #4
0
 /// <summary>
 /// This very expensive method (for types) might be improved in various ways I guess.
 /// </summary>
 private static bool Swappable(GPInitializer initializer, GPNode node)
 {
     if (node.Children.Length < 2)
     {
         return(false); // fast check
     }
     if (initializer.NumAtomicTypes + initializer.NumSetTypes == 1)
     {
         return(true); // next fast check
     }
     // we're typed, so now we have to check our type compatibility
     for (var x = 0; x < node.Constraints(initializer).ChildTypes.Length - 1; x++)
     {
         for (var y = x + 1; y < node.Constraints(initializer).ChildTypes.Length; y++)
         {
             if (node.Children[x].Constraints(initializer).ReturnType
                 .CompatibleWith(initializer, node.Constraints(initializer).ChildTypes[y]) &&
                 node.Children[y].Constraints(initializer).ReturnType
                 .CompatibleWith(initializer, node.Constraints(initializer).ChildTypes[x]))
             {
                 // whew!
                 return(true);
             }
         }
     }
     return(false);
 }
Example #5
0
        internal virtual GPNode CreateTreeOfType(IEvolutionState state, int thread, GPInitializer initializer,
                                                 int functionset, int type, int size, IMersenneTwister mt)
        {
            //System.out.PrintLn("" + functionset + " " + type + " " + size);
            var choice = RandomChoice.PickFromDistribution(ROOT_D[functionset][type][size], ROOT_D[functionset][type][size][0], mt.NextDouble());
            var node   = ROOT_D[functionset][type][size][choice].Node.LightClone();

            node.ResetNode(state, thread); // give ERCs a chance to randomize
            //System.out.PrintLn("Size: " + size + "Rooted: " + node);
            if (node.Children.Length == 0 && size != 1)
            // uh oh
            {
                Console.Out.WriteLine("Size: " + size + " Node: " + node);
                for (var x = 0; x < ROOT_D[functionset][type][size].Length; x++)
                {
                    Console.Out.WriteLine("" + x + (ROOT_D[functionset][type][size][x].Node) + " " + ROOT_D[functionset][type][size][x].Prob);
                }
            }
            if (size > 1)
            {
                // nonterminal
                FillNodeWithChildren(state, thread, initializer, functionset, node, ROOT_D[functionset][type][size][choice].Node, 0, size - 1, mt);
            }
            return(node);
        }
Example #6
0
        public virtual BigInteger NumChildPermutations(GPInitializer initializer, int functionset, GPNode parent, int size, int outof, int pickchild)
        {
            if (NUMCHILDPERMUTATIONS[functionset][IntForNode(parent)][size][outof][pickchild] == 0)
            {
                var count = BigInteger.Zero;
                if (pickchild == parent.Children.Length - 1 && size == outof)
                {
                    count = NumTreesOfType(initializer, functionset, parent.Constraints(initializer).ChildTypes[pickchild].Type, size);
                }

                else if (pickchild < parent.Children.Length - 1 && outof - size >= (parent.Children.Length - pickchild - 1))
                {
                    var cval = NumTreesOfType(initializer, functionset, parent.Constraints(initializer).ChildTypes[pickchild].Type, size);
                    var tot  = BigInteger.Zero;
                    for (var s = 1; s <= outof - size; s++)
                    {
                        tot = BigInteger.Add(tot, NumChildPermutations(initializer, functionset, parent, s, outof - size, pickchild + 1));
                    }
                    count = BigInteger.Multiply(cval, tot);
                }
                // out.PrintLn("Parent: " + parent + " Size: " + size + " OutOf: " + outof +
                //       " PickChild: " + pickchild + " Count: " +count);
                NUMCHILDPERMUTATIONS[functionset][IntForNode(parent)][size][outof][pickchild] = count;
            }
            return(NUMCHILDPERMUTATIONS[functionset][IntForNode(parent)][size][outof][pickchild]);
        }
Example #7
0
        private static bool Demotable(GPInitializer initializer, GPNode node, GPFunctionSet funcs)
        {
            GPType t;

            if (node.Parent is GPNode)
            {
                // ugh, expensive
                t = ((GPNode)(node.Parent)).Constraints(initializer).ChildTypes[node.ArgPosition];
            }
            else
            {
                t = ((GPTree)(node.Parent)).Constraints(initializer).TreeType;
            }

            // Now, out of the nonterminals compatible with that return type,
            // do any also have a child compatible with that return type?  This
            // will be VERY expensive

            for (var x = 0; x < funcs.Nonterminals[t.Type].Length; x++)
            {
                if (funcs.Nonterminals[t.Type][x].Constraints(initializer).ChildTypes
                    .Any(t1 => t1.CompatibleWith(initializer, node.Constraints(initializer).ReturnType)))
                {
                    return(true);
                }
            }
            return(false);
        }
Example #8
0
 private static int NumSwappableNodes(GPInitializer initializer, GPNode root, int soFar)
 {
     if (Swappable(initializer, root))
     {
         soFar++;
     }
     return(root.Children.Aggregate(soFar, (current, t) => NumSwappableNodes(initializer, t, current)));
 }
Example #9
0
 private static int NumDemotableNodesDirtyWork(GPInitializer initializer, GPNode root, int soFar, GPFunctionSet funcs)
 {
     if (Demotable(initializer, root, funcs))
     {
         soFar++;
     }
     return(root.Children.Aggregate(soFar, (current, t) => NumDemotableNodesDirtyWork(initializer, t, current, funcs)));
 }
Example #10
0
        public void GPIndividualWriteAndRead()
        {
            // First we'll set up a Fitness for the Individual
            var rand = new MersenneTwisterFast(0);

            // Initialize some required context
            var state       = new SimpleEvolutionState();
            var initializer = new GPInitializer();

            state.Initializer = initializer; // Required for GPTree.WriteTree(...)
            var constraints = new GPTreeConstraints {
                Name = "TestTreeConstraints"
            };
            //initializer.TreeConstraints
            var tree = new GPTree();

            var f = new KozaFitness();

            f.SetStandardizedFitness(null, float.MaxValue);

            const int n = 10;

            f.Trials = new List <double>(n);
            for (var i = 0; i < n; i++)
            {
                f.Trials.Add(rand.NextDouble());
            }

            // Now we can create and initialize the Individual
            var ind  = new GPIndividual();
            var ind2 = new GPIndividual(); // We'll read back into this instance

            ind.Trees = new GPTree[1];     // This is the set of genes

            ind.Trees[0] = new GPTree();

            ind.Fitness   = f;
            ind.Evaluated = true;

            using (var ms = new MemoryStream())
            {
                var writer = new BinaryWriter(ms);
                ind.WriteIndividual(null, writer);

                ms.Position = 0;
                var reader = new BinaryReader(ms);

                ind2.Fitness = new SimpleFitness();
                ind2.ReadIndividual(null, reader);

                Assert.IsTrue(ind.Fitness.EquivalentTo(ind2.Fitness));
                Assert.IsTrue(ind2.Fitness.IsIdeal);
                Assert.IsTrue(ind.Equals(ind2)); // Genetically equivalent

                Assert.AreEqual(ind.Trees.Length, ind2.Trees.Length);
            }
        }
Example #11
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));
        }
Example #12
0
        private int PickDemotableNode(GPInitializer initializer, GPNode root, int num, GPFunctionSet funcs)
        {
            // if I have just one type, skip this and just
            // the num-th nonterminal
            if (initializer.NumAtomicTypes + initializer.NumSetTypes == 1)
            {
                _demotableNode = root.NodeInPosition(num, GPNode.NODESEARCH_ALL);
                return(-1); // what PickDemotableNodeDirtyWork() returns...
            }

            // otherwise, I gotta do the dirty work
            return(PickDemotableNodeDirtyWork(initializer, root, num, funcs));
        }
Example #13
0
 public virtual BigInteger NumTreesOfType(GPInitializer initializer, int functionset, int type, int size)
 {
     if (NUMTREESOFTYPE[functionset][type][size] == BigInteger.Zero)
     {
         var nodes = FunctionSets[functionset].Nodes[type];
         var count = BigInteger.Zero;
         for (var x = 0; x < nodes.Length; x++)
         {
             count = BigInteger.Add(count, NumTreesRootedByNode(initializer, functionset, nodes[x], size));
         }
         NUMTREESOFTYPE[functionset][type][size] = count;
     }
     return(NUMTREESOFTYPE[functionset][type][size]);
 }
        /// <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 #15
0
 /// <summary>
 /// sticks the node in
 /// </summary>
 private int PickSwappableNode(GPInitializer initializer, GPNode root, int num)
 {
     if (Swappable(initializer, root))
     {
         num--;
         if (num == -1)
         // found it
         {
             _swappableNode = root;
             return(num);
         }
     }
     foreach (var t in root.Children)
     {
         num = PickSwappableNode(initializer, t, num);
         if (num == -1)
         {
             break; // someone found it
         }
     }
     return(num);
 }
Example #16
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 #17
0
 /// <summary>
 /// sticks the node in
 /// </summary>
 private int PickDemotableNodeDirtyWork(GPInitializer initializer, GPNode root, int num, GPFunctionSet funcs)
 {
     if (Demotable(initializer, root, funcs))
     {
         num--;
         if (num == -1)
         // found it
         {
             _demotableNode = root;
             return(num);
         }
     }
     foreach (var t in root.Children)
     {
         num = PickDemotableNodeDirtyWork(initializer, t, num, funcs);
         if (num == -1)
         {
             break; // someone found it
         }
     }
     return(num);
 }
Example #18
0
        internal virtual void FillNodeWithChildren(IEvolutionState state, int thread, GPInitializer initializer, int functionset,
                                                   GPNode parent, GPNode parentc, int pickchild, int outof, IMersenneTwister mt)
        {
            if (pickchild == parent.Children.Length - 1)
            {
                parent.Children[pickchild] = CreateTreeOfType(state, thread, initializer, functionset,
                                                              parent.Constraints(initializer).ChildTypes[pickchild].Type, outof, mt);
            }
            else
            {
                var size = RandomChoice.PickFromDistribution(CHILD_D[functionset][IntForNode(parentc)][outof][pickchild], mt.NextDouble());

                parent.Children[pickchild] = CreateTreeOfType(state, thread, initializer, functionset,
                                                              parent.Constraints(initializer).ChildTypes[pickchild].Type, size, mt);

                FillNodeWithChildren(state, thread, initializer, functionset, parent, parentc, pickchild + 1, outof - size, mt);
            }
            parent.Children[pickchild].Parent      = parent;
            parent.Children[pickchild].ArgPosition = (sbyte)pickchild;
        }
Example #19
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);
        }
Example #20
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;

            // how many individuals should we make?
            int n = TypicalIndsProduced;

            if (n < min)
            {
                n = min;
            }
            if (n > max)
            {
                n = max;
            }

            // should we bother?
            if (!state.Random[thread].NextBoolean(Likelihood))
            {
                // just load from source 0 and clone 'em
                Sources[0].Produce(n, n, subpop, inds, state, thread, misc);
                return(n);
            }

            IntBag[] parentparents   = null;
            IntBag[] preserveParents = null;
            if (misc != null && misc.ContainsKey(KEY_PARENTS))
            {
                preserveParents   = (IntBag[])misc[KEY_PARENTS];
                parentparents     = new IntBag[2];
                misc[KEY_PARENTS] = parentparents;
            }

            GPInitializer initializer = (GPInitializer)state.Initializer;

            for (int q = start; q < n + start; /* no increment */) // keep on going until we're filled up
            {
                Parents.Clear();

                // grab two individuals from our sources
                if (Sources[0] == Sources[1]) // grab from the same source
                {
                    Sources[0].Produce(2, 2, subpop, Parents, state, thread, misc);
                }
                else // grab from different sources
                {
                    Sources[0].Produce(1, 1, subpop, Parents, state, thread, misc);
                    Sources[1].Produce(1, 1, subpop, Parents, state, thread, misc);
                }


                // at this point, Parents[] contains our two selected individuals

                // are our tree values valid?
                if (Tree1 != TREE_UNFIXED && (Tree1 < 0 || Tree1 >= ((GPIndividual)Parents[0]).Trees.Length))
                {
                    // uh oh
                    state.Output.Fatal(
                        "GP Crossover 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");
                }
                if (Tree2 != TREE_UNFIXED && (Tree2 < 0 || Tree2 >= ((GPIndividual)Parents[1]).Trees.Length))
                {
                    // uh oh
                    state.Output.Fatal(
                        "GP Crossover Pipeline attempted to fix tree.1 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 t1;
                int t2;
                if (Tree1 == TREE_UNFIXED || Tree2 == TREE_UNFIXED)
                {
                    do
                    // pick random trees -- their GPTreeConstraints must be the same
                    {
                        if (Tree1 == TREE_UNFIXED)
                        {
                            if (((GPIndividual)Parents[0]).Trees.Length > 1)
                            {
                                t1 = state.Random[thread].NextInt(((GPIndividual)Parents[0]).Trees.Length);
                            }
                            else
                            {
                                t1 = 0;
                            }
                        }
                        else
                        {
                            t1 = Tree1;
                        }

                        if (Tree2 == TREE_UNFIXED)
                        {
                            if (((GPIndividual)Parents[1]).Trees.Length > 1)
                            {
                                t2 = state.Random[thread].NextInt(((GPIndividual)Parents[1]).Trees.Length);
                            }
                            else
                            {
                                t2 = 0;
                            }
                        }
                        else
                        {
                            t2 = Tree2;
                        }
                    } while (((GPIndividual)Parents[0]).Trees[t1].Constraints(initializer) !=
                             ((GPIndividual)Parents[1]).Trees[t2].Constraints(initializer));
                }
                else
                {
                    t1 = Tree1;
                    t2 = Tree2;
                    // make sure the constraints are okay
                    if (((GPIndividual)Parents[0]).Trees[t1].Constraints(initializer) !=
                        ((GPIndividual)Parents[1]).Trees[t2].Constraints(initializer)) // uh oh
                    {
                        state.Output.Fatal(
                            "GP Crossover Pipeline's two tree choices are both specified by the user -- but their GPTreeConstraints are not the same");
                    }
                }

                bool res1 = false;
                bool res2 = false;

                // BRS: This is kind of stupid to name it this way!
                GPTree currTree = ((GPIndividual)Parents[1]).Trees[t2];

                // pick some nodes
                GPNode p1 = null;
                GPNode p2 = null;

                // lets walk on parent2 all nodes to get subtrees for each node, doing it once for O(N) and not O(N^2)
                // because depth etc are computed and not stored
                ArrayList nodeToSubtrees = new ArrayList();
                // also Hashtable for size to List() of nodes in that size for O(1) lookup
                Hashtable sizeToNodes = new Hashtable();
                TraverseTreeForDepth(currTree.Child, nodeToSubtrees, sizeToNodes);
                // sort the ArrayList with comparator that sorts by subtrees
                nodeToSubtrees.Sort(new NodeComparator());

                for (int x = 0; x < NumTries; x++)
                {
                    // pick a node in individual 1
                    p1 = NodeSelect1.PickNode(state, subpop, thread, (GPIndividual)Parents[0], ((GPIndividual)Parents[0]).Trees[t1]);
                    // now lets find "similar" in parent 2
                    p2 = FindFairSizeNode(nodeToSubtrees, sizeToNodes, p1, currTree, state, thread);


                    // check for depth and swap-compatibility limits
                    res1 = VerifyPoints(initializer, p2, p1); // p2 can fill p1's spot -- order is important!
                    if (n - (q - start) < 2 || TossSecondParent)
                    {
                        res2 = true;
                    }
                    else
                    {
                        res2 = VerifyPoints(initializer, p1, p2); // p1 can fill p2's spot --  order is important!
                    }
                    // did we get something that had both nodes verified?
                    // we reject if EITHER of them is invalid. This is what lil-gp
                    // does.
                    // Koza only has numTries set to 1, so it's compatible as well.
                    if (res1 && res2)
                    {
                        break;
                    }
                }

                // at this point, res1 AND res2 are valid, OR
                // either res1 OR res2 is valid and we ran out of tries, OR
                // neither res1 nor res2 is valid and we rand out of tries.
                // So now we will transfer to a tree which has res1 or res2
                // valid, otherwise it'll just get replicated. This is
                // compatible with both Koza and lil-gp.

                // at this point I could check to see if my sources were breeding
                // pipelines -- but I'm too lazy to write that code (it's a little
                // complicated) to just swap one individual over or both over,
                // -- it might still entail some copying. Perhaps in the future.
                // It would make things faster perhaps, not requiring all that
                // cloning.

                // Create some new individuals based on the old ones -- since
                // GPTree doesn't deep-clone, this should be just fine. Perhaps we
                // should change this to proto off of the main species prototype,
                // but
                // we have to then copy so much stuff over; it's not worth it.

                GPIndividual j1 = ((GPIndividual)Parents[0]).LightClone();
                GPIndividual j2 = null;
                if (n - (q - start) >= 2 && !TossSecondParent)
                {
                    j2 = ((GPIndividual)Parents[1]).LightClone();
                }

                // Fill in various tree information that didn't get filled in there
                j1.Trees = new GPTree[((GPIndividual)Parents[0]).Trees.Length];
                if (n - (q - start) >= 2 && !TossSecondParent)
                {
                    j2.Trees = new GPTree[((GPIndividual)Parents[1]).Trees.Length];
                }

                // at this point, p1 or p2, or both, may be null.
                // If not, swap one in. Else just copy the parent.

                for (int x = 0; x < j1.Trees.Length; x++)
                {
                    if (x == t1 && res1) // we've got a tree with a kicking cross
                    // position!
                    {
                        j1.Trees[x]                   = ((GPIndividual)Parents[0]).Trees[x].LightClone();
                        j1.Trees[x].Owner             = j1;
                        j1.Trees[x].Child             = ((GPIndividual)Parents[0]).Trees[x].Child.CloneReplacing(p2, p1);
                        j1.Trees[x].Child.Parent      = j1.Trees[x];
                        j1.Trees[x].Child.ArgPosition = 0;
                        j1.Evaluated                  = false;
                    } // it's changed
                    else
                    {
                        j1.Trees[x]                   = ((GPIndividual)Parents[0]).Trees[x].LightClone();
                        j1.Trees[x].Owner             = j1;
                        j1.Trees[x].Child             = (GPNode)((GPIndividual)Parents[0]).Trees[x].Child.Clone();
                        j1.Trees[x].Child.Parent      = j1.Trees[x];
                        j1.Trees[x].Child.ArgPosition = 0;
                    }
                }

                if (n - (q - start) >= 2 && !TossSecondParent)
                {
                    for (int x = 0; x < j2.Trees.Length; x++)
                    {
                        if (x == t2 && res2) // we've got a tree with a kicking
                        // cross position!
                        {
                            j2.Trees[x]                   = ((GPIndividual)Parents[1]).Trees[x].LightClone();
                            j2.Trees[x].Owner             = j2;
                            j2.Trees[x].Child             = ((GPIndividual)Parents[1]).Trees[x].Child.CloneReplacing(p1, p2);
                            j2.Trees[x].Child.Parent      = j2.Trees[x];
                            j2.Trees[x].Child.ArgPosition = 0;
                            j2.Evaluated                  = false;
                        } // it's changed
                        else
                        {
                            j2.Trees[x]                   = ((GPIndividual)Parents[1]).Trees[x].LightClone();
                            j2.Trees[x].Owner             = j2;
                            j2.Trees[x].Child             = (GPNode)((GPIndividual)Parents[1]).Trees[x].Child.Clone();
                            j2.Trees[x].Child.Parent      = j2.Trees[x];
                            j2.Trees[x].Child.ArgPosition = 0;
                        }
                    }
                }

                // add the individuals to the population
                // by Ermo. I think this should be add
                // inds.set(q,j1);
                // Yes -- Sean
                inds.Add(j1);
                if (preserveParents != null)
                {
                    parentparents[0].AddAll(parentparents[1]);
                    preserveParents[q] = parentparents[0];
                }

                q++;
                if (q < n + start && !TossSecondParent)
                {
                    // by Ermo. Same reason, should changed to add
                    //inds[q] = j2;
                    inds.Add(j2);
                    if (preserveParents != null)
                    {
                        preserveParents[q] = parentparents[0];
                    }
                    q++;
                }
            }
            return(n);
        }
Example #21
0
 public override bool CompatibleWith(GPInitializer initializer, GPType t)
 {
     return(t.Type == Type ? true : false);
 }