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) }
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]); }
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)); }
/// <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); }
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); }
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]); }
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); }
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))); }
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))); }
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); } }
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)); }
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)); }
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); }
/// <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); }
/// <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); }
/// <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); }
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; }
/** * 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); }
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); }
public override bool CompatibleWith(GPInitializer initializer, GPType t) { return(t.Type == Type ? true : false); }