public override GPNode NewRootedTree(IEvolutionState state, GPType type, int thread, IGPNodeParent parent, GPFunctionSet funcs, int argPosition, int requestedSize) { var n = GrowNode(state, 0, state.Random[thread].NextInt(MaxDepth - MinDepth + 1) + MinDepth, type, thread, parent, argPosition, 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); }
public override GPNode NewRootedTree(IEvolutionState state, GPType type, int thread, IGPNodeParent parent, GPFunctionSet funcs, int argPosition, int requestedSize) { if (state.Random[thread].NextDouble() < PickGrowProbability) { return(GrowNode(state, 0, state.Random[thread].NextInt(MaxDepth - MinDepth + 1) + MinDepth, type, thread, parent, argPosition, funcs)); } return(FullNode(state, 0, state.Random[thread].NextInt(MaxDepth - MinDepth + 1) + MinDepth, type, thread, parent, argPosition, funcs)); }
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)); }
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))); }
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> /// Returns a node which is swap-compatible with returntype, /// and whose arguments are swap-compatible with the current children of original. /// You need to clone this node. /// </summary> private static GPNode PickCompatibleNode(GPNode original, GPFunctionSet funcs, IEvolutionState state, GPType returntype, int thread) { // an expensive procedure: we will linearly search for a valid node var numValidNodes = 0; var type = returntype.Type; var initializer = ((GPInitializer)state.Initializer); var len = original.Constraints(initializer).ChildTypes.Length; bool failed; if (initializer.NumAtomicTypes + initializer.NumSetTypes == 1) { // easy numValidNodes = funcs.NodesByArity[type][len].Length; } else { for (var x = 0; x < funcs.NodesByArity[type][len].Length; x++) // ugh, the hard way -- nodes swap-compatible with type, and of arity len { failed = funcs.NodesByArity[type][len][x].Constraints(initializer).ChildTypes .Where((t, y) => !t.CompatibleWith(initializer, original.Children[y].Constraints(initializer).ReturnType)).Any(); if (!failed) { numValidNodes++; } } } // we must have at least success -- the node itself. Otherwise we're // in deep doo-doo. // now pick a random node number var nodenum = state.Random[thread].NextInt(numValidNodes); // find and return that node var prosnode = 0; if (numValidNodes == funcs.NodesByArity[type][len].Length) { // easy return(funcs.NodesByArity[type][len][nodenum]); } for (var x = 0; x < funcs.NodesByArity[type][len].Length; x++) // ugh, the hard way -- nodes swap-compatible with type, and of arity len { failed = funcs.NodesByArity[type][len][x].Constraints(initializer).ChildTypes .Where((t, y) => !t.CompatibleWith(initializer, original.Children[y].Constraints(initializer).ReturnType)).Any(); if (failed) { continue; } if (prosnode == nodenum) { // got it! return(funcs.NodesByArity[type][len][x]); } prosnode++; } // should never be able to get here throw new ApplicationException("Invalid execution path!"); // whoops! }
/// <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 bool CompatibleWith(GPInitializer initializer, GPType t) { return(t.Type == Type ? true : false); }
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); }
/// <summary> /// Returns a brand-new tree which is swap-compatible with returntype, /// created by making nodes "compatible" with the equivalent nodes in the tree rooted at original. /// You need to set the parent and argumentposition of the root yourself. /// </summary> private static GPNode GenerateCompatibleTree(GPNode original, GPFunctionSet funcs, IEvolutionState state, GPType returntype, int thread) { // pick a new node and clone it var node = PickCompatibleNode(original, funcs, state, returntype, thread).LightClone(); // reset it node.ResetNode(state, thread); // fill in its children var initializer = ((GPInitializer)state.Initializer); for (var x = 0; x < node.Children.Length; x++) { node.Children[x] = GenerateCompatibleTree(original.Children[x], funcs, state, original.Constraints(initializer).ChildTypes[x], thread); node.Children[x].Parent = node; node.Children[x].ArgPosition = (sbyte)x; } return(node); }
/// <summary> /// A private function which recursively returns a GROW tree to NewRootedTree(...) /// </summary> protected internal virtual GPNode GrowNode(IEvolutionState state, int current, int max, GPType type, int thread, IGPNodeParent parent, int argPosition, GPFunctionSet funcs) { // growNode 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-depth 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; GPNode[] terminals = funcs.Terminals[t]; //GPNode[] nonterminals = funcs.Nonterminals[t]; GPNode[] 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 // 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 pick a random node else { if (triedTerminals) { WarnAboutNoTerminalWithType(type, false, state); // we tried terminals and we're here because there were none! } var n = nodes[state.Random[thread].NextInt(nodes.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] = GrowNode(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 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); } }