/// <summary> /// A private recursive method which builds a FULL-style tree for NewRootedTree(...) /// </summary> protected internal virtual GPNode FullNode(IEvolutionState state, int current, int max, GPType type, int thread, IGPNodeParent parent, int argPosition, GPFunctionSet funcs) { // fullNode can mess up if there are no available terminals for a given type. If this occurs, // and we find ourselves unable to pick a terminal when we want to do so, we will issue a warning, // and pick a nonterminal, violating the "FULL" contract. This can lead to pathological situations // where the system will continue to go on and on unable to stop because it can't pick a terminal, // resulting in running out of memory or some such. But there are cases where we'd want to let // this work itself out. var triedTerminals = false; // did we try -- and fail -- to fetch a terminal? var t = type.Type; var terminals = funcs.Terminals[t]; var nonterminals = funcs.Nonterminals[t]; var nodes = funcs.Nodes[t]; if (nodes.Length == 0) { ErrorAboutNoNodeWithType(type, state); // total failure } // pick a terminal when we're at max depth or if there are NO nonterminals if ((current + 1 >= max || WarnAboutNonterminal(nonterminals.Length == 0, type, false, state)) // this will freak out the static checkers && (triedTerminals = true) && // [first set triedTerminals] terminals.Length != 0) // AND if there are available terminals { var n = terminals[state.Random[thread].NextInt(terminals.Length)].LightClone(); n.ResetNode(state, thread); // give ERCs a chance to randomize n.ArgPosition = (sbyte)argPosition; n.Parent = parent; return(n); } // else force a nonterminal unless we have no choice else { if (triedTerminals) { WarnAboutNoTerminalWithType(type, false, state); // we tried terminals and we're here because there were none! } var nodesToPick = funcs.Nonterminals[type.Type]; if (nodesToPick == null || nodesToPick.Length == 0) { // no nonterminals, hope the guy knows what he's doing! nodesToPick = funcs.Terminals[type.Type]; // this can only happen with the warning about nonterminals above } var n = nodesToPick[state.Random[thread].NextInt(nodesToPick.Length)].LightClone(); n.ResetNode(state, thread); // give ERCs a chance to randomize n.ArgPosition = (sbyte)argPosition; n.Parent = parent; // Populate the node... var childtypes = n.Constraints(((GPInitializer)state.Initializer)).ChildTypes; for (var x = 0; x < childtypes.Length; x++) { n.Children[x] = FullNode(state, current + 1, max, childtypes[x], thread, n, x, funcs); } return(n); } }
public override GPNode NewRootedTree(IEvolutionState state, GPType type, int thread, IGPNodeParent parent, GPFunctionSet set, int argPosition, int requestedSize) { int t = type.Type; GPNode[] terminals = set.Terminals[t]; GPNode[] nonterminals = set.Nonterminals[t]; if (requestedSize == NOSIZEGIVEN) { requestedSize = PickSize(state, thread); } GPNode n; if (requestedSize == 1) { // pick a random terminal n = terminals[state.Random[thread].NextInt(terminals.Length)].LightClone(); } else { n = nonterminals[state.Random[thread].NextInt(nonterminals.Length)] .LightClone(); // it's always going to be the Dummy // do decomposition byte pos = 0; // THIS WILL HAVE TO BE MODIFIED TO AN INT LATER ON AND THIS WILL AFFECT ARGPOSITIONS!!! IList <GPNode> list = new List <GPNode>(); // dunno if this is too expensive while (requestedSize >= 1) { int amount = state.Random[thread].NextInt(requestedSize) + 1; requestedSize -= amount; GPNode f = NewRootedTree(state, type, thread, parent, set, pos, amount); list.Add(f); } // shuffle and reassign argument position n.Children = list.ToArray(); n.Children = Shuffle(n.Children, state, thread); for (int i = 0; i < n.Children.Length; i++) { n.Children[i].ArgPosition = (byte)i; } } n.ResetNode(state, thread); // give ERCs a chance to randomize n.ArgPosition = (byte)argPosition; n.Parent = parent; return(n); }
/// <summary> /// Returns true if inner1 and inner2 do not contain one another /// </summary> private static bool NoContainment(GPNode inner1, GPNode inner2) { IGPNodeParent current = inner1; while (current != null && current is GPNode) { if (current == inner2) { return(false); // inner2 contains inner1 } current = ((GPNode)current).Parent; } current = inner2; while (current != null && current is GPNode) { if (current == inner1) { return(false); // inner1 contains inner2 } current = ((GPNode)current).Parent; } return(true); }
public override GPNode NewRootedTree(IEvolutionState state, GPType type, int thread, IGPNodeParent parent, GPFunctionSet funcs, int argPosition, int requestedSize) { return(FullNode(state, 0, state.Random[thread].NextInt(MaxDepth - MinDepth + 1) + MinDepth, type, thread, parent, argPosition, funcs)); }
/// <summary> /// A private function which recursively returns a GROW tree to NewRootedTree(...) /// </summary> private GPNode Ptc1(IEvolutionState state, int current, GPType type, int thread, IGPNodeParent parent, int argPosition, GPFunctionSet funcs, IPTCFunctionSet pfuncs, double[] nonterminalSelectProbs) { // ptc1 can mess up if there are no available terminals for a given type. If this occurs, // and we find ourselves unable to pick a terminal when we want to do so, we will issue a warning, // and pick a nonterminal, violating the PTC1 size and depth contracts. This can lead to pathological situations // where the system will continue to go on and on unable to stop because it can't pick a terminal, // resulting in running out of memory or some such. But there are cases where we'd want to let // this work itself out. var triedTerminals = false; var t = type.Type; var terminals = funcs.Terminals[t]; var nonterminals = funcs.Nonterminals[t]; var nodes = funcs.Nodes[t]; if (nodes.Length == 0) { ErrorAboutNoNodeWithType(type, state); // total failure } // Now pick if we're at max depth // OR if we're below p_y // OR if there are NO nonterminals! // [first set triedTerminals] // AND if there are available terminals if (((current + 1 >= MaxDepth) || !(state.Random[thread].NextBoolean(nonterminalSelectProbs[t])) || WarnAboutNonterminal(nonterminals.Length == 0, type, false, state)) && (triedTerminals = true) && terminals.Length != 0) { var n = terminals[RandomChoice.PickFromDistribution(pfuncs.TerminalProbabilities(t), state.Random[thread].NextDouble())].LightClone(); n.ResetNode(state, thread); // give ERCs a chance to randomize n.ArgPosition = (sbyte)argPosition; n.Parent = parent; return(n); } // above p_y, pick a nonterminal by q_ny probabilities else { if (triedTerminals) { WarnAboutNoTerminalWithType(type, false, state); // we tried terminals and we're here because there were none! } var n = nonterminals[RandomChoice.PickFromDistribution(pfuncs.NonterminalProbabilities(t), state.Random[thread].NextDouble())].LightClone(); n.ResetNode(state, thread); // give ERCs a chance to randomize n.ArgPosition = (sbyte)argPosition; n.Parent = parent; // Populate the node... var childtypes = n.Constraints((GPInitializer)state.Initializer).ChildTypes; for (var x = 0; x < childtypes.Length; x++) { n.Children[x] = Ptc1(state, current + 1, childtypes[x], thread, n, x, funcs, pfuncs, nonterminalSelectProbs); } return(n); } }
public override GPNode NewRootedTree(IEvolutionState state, GPType type, int thread, IGPNodeParent parent, GPFunctionSet funcs, int ArgPosition, int requestedSize) { if (!(funcs is IPTCFunctionSet)) { state.Output.Fatal("Set " + funcs.Name + " is not of the form ec.gp.build.IPTCFunctionSet, and so cannot be used with PTC Nodebuilders."); } // build the tree if (requestedSize == NOSIZEGIVEN) // use the default { return(Ptc1(state, 0, type, thread, parent, ArgPosition, funcs, (IPTCFunctionSet)funcs, ((IPTCFunctionSet)funcs).NonterminalSelectionProbabilities(ExpectedSize))); } if (requestedSize < 1) { state.Output.Fatal("ec.gp.build.PTC1 was requested to build a tree, but a requested size was given that is < 1."); } return(Ptc1(state, 0, type, thread, parent, ArgPosition, funcs, (IPTCFunctionSet)funcs, ((IPTCFunctionSet)funcs).NonterminalSelectionProbabilities(requestedSize))); }
/// <summary> /// Produces a new rooted tree of GPNodes whose root's return type is /// swap-compatible with <i>type</i>. When you build a brand-new /// tree out of GPNodes cloned from the /// prototypes stored in the GPNode[] arrays, you must remember /// to call resetNode() on each cloned GPNode. This gives ERCs a chance /// to randomize themselves and set themselves up. /// <p/>requestedSize is an /// optional argument which differs based on the GPNodeBuilder used. /// Typically it is set to a tree size that the calling method wants /// the GPNodeBuilder to produce; the GPNodeBuilder is not obligated to /// produce a tree of this size, but it should attempt to interpret this /// argument as appropriate for the given algorithm. To indicate that /// you don't care what size the tree should be, you can pass NOSIZEGIVEN. /// However if the algorithm <i>requires</i> you to provide a size, it /// will generate a fatal error to let you know. /// </summary> public abstract GPNode NewRootedTree(IEvolutionState state, GPType type, int thread, IGPNodeParent parent, GPFunctionSet funcs, int argPosition, int requestedSize);
public override GPNode NewRootedTree(IEvolutionState state, GPType type, int thread, IGPNodeParent parent, GPFunctionSet funcs, int argPosition, int requestedSize) { // ptc2 can mess up if there are no available terminals for a given type. If this occurs, // and we find ourselves unable to pick a terminal when we want to do so, we will issue a warning, // and pick a nonterminal, violating the ptc2 size and depth contracts. This can lead to pathological situations // where the system will continue to go on and on unable to stop because it can't pick a terminal, // resulting in running out of memory or some such. But there are cases where we'd want to let // this work itself out. var triedTerminals = false; if (!(funcs is IPTCFunctionSet)) { state.Output.Fatal("Set " + funcs.Name + " is not of the class ec.gp.build.IPTCFunctionSet, and so cannot be used with PTC Nodebuilders."); } var pfuncs = (IPTCFunctionSet)funcs; // pick a size from the distribution if (requestedSize == NOSIZEGIVEN) { requestedSize = PickSize(state, thread); } GPNode root; var t = type.Type; var terminals = funcs.Terminals[t]; var nonterminals = funcs.Nonterminals[t]; var nodes = funcs.Nodes[t]; if (nodes.Length == 0) { ErrorAboutNoNodeWithType(type, state); // total failure } // return a terminal // Now pick a terminal if our size is 1 // OR if there are NO nonterminals! // [first set triedTerminals] // AND if there are available terminals if ((requestedSize == 1 || WarnAboutNonterminal(nonterminals.Length == 0, type, false, state)) && (triedTerminals = true) && terminals.Length != 0) { root = terminals[RandomChoice.PickFromDistribution(pfuncs.TerminalProbabilities(t), state.Random[thread].NextDouble())].LightClone(); root.ResetNode(state, thread); // give ERCs a chance to randomize root.ArgPosition = (sbyte)argPosition; root.Parent = parent; } // return a nonterminal-rooted tree else { if (triedTerminals) { WarnAboutNoTerminalWithType(type, false, state); // we tried terminals and we're here because there were none! } // pick a nonterminal root = nonterminals[RandomChoice.PickFromDistribution(pfuncs.NonterminalProbabilities(t), state.Random[thread].NextDouble())].LightClone(); root.ResetNode(state, thread); // give ERCs a chance to randomize root.ArgPosition = (sbyte)argPosition; root.Parent = parent; // set the depth, size, and enqueuing, and reset the random dequeue s_size = 0; // pretty critical! var s = 1; var initializer = ((GPInitializer)state.Initializer); var childtypes = root.Constraints(initializer).ChildTypes; for (var x = 0; x < childtypes.Length; x++) { Enqueue(root, x, 1); /* depth 1 */ } while (s_size > 0) { triedTerminals = false; RandomDequeue(state, thread); type = DequeueNode.Constraints(initializer).ChildTypes[DequeueArgpos]; var y = type.Type; terminals = funcs.Terminals[y]; nonterminals = funcs.Nonterminals[y]; nodes = funcs.Nodes[y]; if (nodes.Length == 0) { ErrorAboutNoNodeWithType(type, state); // total failure } // pick a terminal // if we need no nonterminal nodes // OR if we're at max depth and must pick a terminal // OR if there are NO nonterminals! // [first set triedTerminals] // AND if there are available terminals if ((s_size + s >= requestedSize || DequeueDepth == MaxDepth || WarnAboutNonterminal(nonterminals.Length == 0, type, false, state)) && (triedTerminals = true) && terminals.Length != 0) { var n = terminals[RandomChoice.PickFromDistribution(pfuncs.TerminalProbabilities(y), state.Random[thread].NextDouble())].LightClone(); DequeueNode.Children[DequeueArgpos] = n; n.ResetNode(state, thread); // give ERCs a chance to randomize n.ArgPosition = (sbyte)DequeueArgpos; n.Parent = DequeueNode; } // pick a nonterminal and enqueue its children else { if (triedTerminals) { WarnAboutNoTerminalWithType(type, false, state); // we tried terminals and we're here because there were none! } var n = nonterminals[RandomChoice.PickFromDistribution(pfuncs.NonterminalProbabilities(y), state.Random[thread].NextDouble())].LightClone(); DequeueNode.Children[DequeueArgpos] = n; n.ResetNode(state, thread); // give ERCs a chance to randomize n.ArgPosition = (sbyte)DequeueArgpos; n.Parent = DequeueNode; childtypes = n.Constraints(initializer).ChildTypes; for (var x = 0; x < childtypes.Length; x++) { Enqueue(n, x, DequeueDepth + 1); } } s++; } } return(root); }
GPNode MakeSubtree(IList <int> index, IList <int> genome, IEvolutionState es, GPFunctionSet gpfs, GrammarRuleNode rule, int treeNum, int threadNum, IDictionary <int, GPNode> ercMapsForFancyPrint, IGPNodeParent parent, byte argPosition) { //have we exceeded the length of the genome? No point in going further. if (index[0] >= genome.Count) { throw new BigTreeException(); } //expand the rule with the chromosome to get a body element int i; //non existant rule got passed in if (rule == null) { es.Output.Fatal("An undefined rule exists within the grammar."); } //more than one rule to consider, pick one based off the genome, and consume the current gene // avoid mod operation as much as possible if (rule.GetNumChoices() > 1) { i = (genome[index[0]] - (int)GetMinGene(index[0])) % rule.GetNumChoices(); } else { i = 0; } index[0]++; GrammarNode choice = rule.GetChoice(i); // if body is another rule head //look up rule if (choice is GrammarRuleNode) { var nextrule = (GrammarRuleNode)choice; return(MakeSubtree(index, genome, es, gpfs, nextrule, treeNum, threadNum, ercMapsForFancyPrint, parent, argPosition)); } else //handle functions { GrammarFunctionNode funcgrammarnode = (GrammarFunctionNode)choice; GPNode validNode = funcgrammarnode.GetGPNodePrototype(); int numChildren = validNode.Children.Length; //index 0 is the node itself int numChildrenInGrammar = funcgrammarnode.GetNumArguments(); //does the grammar contain the correct amount of children that the GPNode requires if (numChildren != numChildrenInGrammar) { es.Output.Fatal("GPNode " + validNode.ToStringForHumans() + " requires " + numChildren + " children. " + numChildrenInGrammar + " children found in the grammar."); } //check to see if it is an ERC node if (validNode is ERC) { // have we exceeded the length of the genome? No point in going further. if (index[0] >= genome.Count) { throw new BigTreeException(); } // ** do we actually need to maintain two vlaues ? key and originalVal ? // ** there is no problem if we use the originalVal for both ERCBank and // ** ercMapsForFancyPrint, moreover, this will also make the reverse-mapping case // ** easier -- khaled // these below two lines are from the original code -- // key for ERC hashtable look ups is the current index within the genome. Consume it. //int key = genome[index[0]] - (int)GetMinGene(index[0]); //int originalVal = genome[index[0]]; // this single line is khaled's mod -- int genomeVal = genome[index[0]]; index[0]++; validNode = ObtainERC(es, genomeVal, threadNum, validNode, ercMapsForFancyPrint); } //non ERC node else { validNode = validNode.LightClone(); } //get the rest. for (int j = 0, childNumber = 0; j < funcgrammarnode.GetNumArguments(); j++) { //get and link children to the current GPNode validNode.Children[childNumber] = MakeSubtree(index, genome, es, gpfs, (GrammarRuleNode)funcgrammarnode.GetArgument(j), treeNum, threadNum, ercMapsForFancyPrint, validNode, (byte)childNumber); if (validNode.Children[childNumber] == null) { return(null); } childNumber++; } validNode.ArgPosition = argPosition; validNode.Parent = parent; return(validNode); } }
public override GPNode NewRootedTree(IEvolutionState state, GPType type, int thread, IGPNodeParent parent, GPFunctionSet funcs, int argPosition, int requestedSize) { var valid = false; var treeSize = PickSize(state, thread); if (!AritySetupDone) { SetupArities(state, funcs); } var temp = new int[Arities.Length]; Permutations = new List <int[]>(); Permute(0, temp, treeSize - 1); if (Permutations.Count == 0) { state.Output.Fatal("Not able to build combination of nodes."); } var scheme = Select(Permutations, treeSize); var word = BuildDyckWord(treeSize, Arities, scheme, state, thread); var cycle = 0; while (!valid) { valid = CheckDyckWord(word); if (!valid) { word = String.Concat(word.Substring(word.Length - 1, word.Length), word.Substring(0, word.Length - 1)); cycle++; if (cycle >= (treeSize * 2) - 1) { state.Output.Fatal("Not able to find valid permutation for generated Dyck word: " + word); } } } return(BuildTree(state, thread, parent, argPosition, funcs, word)); }
/// <summary> /// This function parses the dyck word and puts random nodes into their slots. /// </summary> private static GPNode BuildTree(IEvolutionState state, int thread, IGPNodeParent parent, int argPosition, GPFunctionSet funcs, string dyckWord) { var s = new List <GPNode>(); // Parsing dyck word from left to right and building tree for (var counter = 0; counter < dyckWord.Length; counter++) { char nextChar; if (counter < dyckWord.Length - 1) { nextChar = dyckWord[counter + 1]; } else { nextChar = '*'; } if ((nextChar == 'x') || (nextChar == '*')) /* terminal node */ { var nn = funcs.Terminals[0]; var n = nn[state.Random[thread].NextInt(nn.Length)].LightClone(); n.ResetNode(state, thread); // give ERCs a chance to randomize s.Add(n); } else if (nextChar == 'y') /* non-terminal */ { // finding arity of connection var ycount = 0; /* arity */ var nextCharY = (nextChar == 'y'); counter++; while ((counter < dyckWord.Length) && (nextCharY)) { if (dyckWord[counter] == 'y') { ycount++; } if (counter < dyckWord.Length - 1) { nextCharY = (dyckWord[counter + 1] == 'y'); } counter++; } //Arity found. Now just choose non terminal at random. var nonTerms = funcs.NodesByArity[0][ycount]; var nT = nonTerms[state.Random[thread].NextInt(nonTerms.Length)].LightClone(); // Non terminal chosen, now attaching children var childcount = ycount; while (childcount > 0) { childcount--; if (s.Count == 0) { state.Output.Fatal("Stack underflow when building tree."); } var child = Pop(s); child.Parent = nT; child.ArgPosition = (sbyte)childcount; nT.Children[childcount] = child; } nT.ArgPosition = 0; nT.Parent = null; s.Add(nT); if (counter != dyckWord.Length) { counter--; } } } return(Pop(s)); }
public override GPNode NewRootedTree(IEvolutionState state, GPType type, int thread, IGPNodeParent parent, GPFunctionSet funcs, int argPosition, int requestedSize) { var initializer = ((GPInitializer)state.Initializer); if (requestedSize == NOSIZEGIVEN) // pick from the distribution { var BOUNDARY = 20; // if we try 20 times and fail, check to see if it's possible to succeed var bound = 0; var fset = (int)FunctionSetsHash[funcs]; var siz = PickSize(state, thread, fset, type.Type); var typ = type.Type; // this code is confusing. The idea is: // if the number of trees of our arbitrarily-picked size is zero, we try BOUNDARY // number of times to find a tree which will work, picking new sizes each // time. If we still haven't found anything, we will continue to search // for a working tree only if we know for sure that one exists in the distribution. var checkState = false; // BRS : Can't call this "checked" as in ECJ because of the compiler keyword while (ROOT_D_ZERO[fset][typ][siz]) { if (++bound == BOUNDARY) { if (!checkState) { checkState = true; for (var x = 0; x < ROOT_D_ZERO[fset][typ].Length; x++) { if (!ROOT_D_ZERO[fset][typ][x]) { goto check_brk; // BRS : TODO : This is different from ECJ "break check;" Is it equivalent? } // found a non-zero } // uh oh, we're all zeroes state.Output.Fatal("ec.gp.build.Uniform was asked to build a tree with functionset " + funcs + " rooted with type " + type + ", but cannot because for some reason there are no trees" + " of any valid size (within the specified size range) which exist for this function set and type."); } check_brk :; } siz = PickSize(state, thread, fset, typ); } // okay, now we have a valid size. var n = CreateTreeOfType(state, thread, initializer, fset, typ, siz, state.Random[thread]); n.Parent = parent; n.ArgPosition = (sbyte)argPosition; return(n); } else if (requestedSize < 1) { state.Output.Fatal("ec.gp.build.Uniform requested to build a tree, but a requested size was given that is < 1."); return(null); // never happens } else { var fset = (int)FunctionSetsHash[funcs]; var typ = type.Type; var siz = requestedSize; // if the number of trees of the requested size is zero, we first march up until we // find a tree size with non-zero numbers of trees. Failing that, we march down to // find one. If that still fails, we issue an error. Otherwise we use the size // we discovered. if (ROOT_D_ZERO[fset][typ][siz]) { // march up for (var x = siz + 1; x < ROOT_D_ZERO[fset][typ].Length; x++) { if (ROOT_D_ZERO[fset][typ][siz]) { siz = x; goto determineSize_brk; } } // march down for (var x = siz - 1; x >= 0; x--) { if (ROOT_D_ZERO[fset][typ][siz]) { siz = x; goto determineSize_brk; } } // issue an error state.Output.Fatal("ec.gp.build.Uniform was asked to build a tree with functionset " + funcs + " rooted with type " + type + ", and of size " + requestedSize + ", but cannot because for some reason there are no trees of any" + " valid size (within the specified size range) which exist for this function set and type."); } determineSize_brk :; var n = CreateTreeOfType(state, thread, initializer, fset, typ, siz, state.Random[thread]); n.Parent = parent; n.ArgPosition = (sbyte)argPosition; return(n); } }
private GPNode randomBranch(IEvolutionState state, GPType type, int maxLength, int thread, IGPNodeParent parent, int argPosition, GPFunctionSet funcs) { // randomBranch can mess up if there are no available terminals for a given type. If this occurs, // and we find ourselves unable to pick a terminal when we want to do so, we will issue a warning, // and pick a nonterminal, violating the maximum-size contract. This can lead to pathological situations // where the system will continue to go on and on unable to stop because it can't pick a terminal, // resulting in running out of memory or some such. But there are cases where we'd want to let // this work itself out. var triedTerminals = false; var t = type.Type; var terminals = funcs.Terminals[t]; var nonterminals = funcs.Nonterminals[t]; var nodes = funcs.Nodes[t]; if (nodes.Length == 0) { ErrorAboutNoNodeWithType(type, state); // total failure } // if the desired length is 1 // OR if there are NO nonterminals! // [first set triedTerminals] // AND if there are available terminals if ((maxLength == 1 || WarnAboutNonterminal(nonterminals.Length == 0, type, false, state)) // this will freak out the static checkers && (triedTerminals = true) && terminals.Length != 0) { var n = terminals[state.Random[thread].NextInt(terminals.Length)].LightClone(); n.ResetNode(state, thread); // give ERCs a chance to randomize n.ArgPosition = (sbyte)argPosition; n.Parent = parent; return(n); } if (triedTerminals) { WarnAboutNoTerminalWithType(type, false, state); // we tried terminals and we're here because there were none! } // grab all the nodes whose arity is <= maxlength-1 var len = funcs.NonterminalsUnderArity[type.Type].Length - 1; if (len > maxLength - 1) { len = maxLength - 1; } var okayNonterms = funcs.NonterminalsUnderArity[type.Type][len]; if (okayNonterms.Length == 0) // no nodes, pick a terminal { if (terminals.Length == 0) { ErrorAboutNoNodeWithType(type, state); // total failure } var n = terminals[state.Random[thread].NextInt(terminals.Length)].LightClone(); n.ResetNode(state, thread); // give ERCs a chance to randomize n.ArgPosition = (sbyte)argPosition; n.Parent = parent; return(n); } // we've got nonterminals, pick one at random else { var n = okayNonterms[state.Random[thread].NextInt(okayNonterms.Length)].LightClone(); n.ResetNode(state, thread); // give ERCs a chance to randomize n.ArgPosition = (sbyte)argPosition; n.Parent = parent; // Populate the node... var childtypes = n.Constraints((GPInitializer)state.Initializer).ChildTypes; for (var x = 0; x < childtypes.Length; x++) { n.Children[x] = randomBranch(state, childtypes[x], (maxLength - 1) / childtypes.Length, thread, n, x, funcs); } return(n); } }
public override GPNode NewRootedTree(IEvolutionState state, GPType type, int thread, IGPNodeParent parent, GPFunctionSet funcs, int argPosition, int requestedSize) { if (requestedSize == NOSIZEGIVEN) { // pick from the distribution return(randomBranch(state, type, PickSize(state, thread), thread, parent, argPosition, funcs)); } if (requestedSize < 1) { state.Output.Fatal("ec.gp.build.RandomBranch requested to build a tree, but a requested size was given that is < 1."); } return(randomBranch(state, type, requestedSize, thread, parent, argPosition, funcs)); }