public override NodeBaseType <T, S> SelectRandom(ref int numNodesConsidered) { float selectPercentage = 1F / numNodesConsidered; // possibly pick myself NodeBaseType <T, S> selected = null; if (Randomizer.GetFloatFromZeroToOne() < selectPercentage) { selected = this; } // but also consider all of my children foreach (var child in Children) { numNodesConsidered++; var selectedFromChild = child.SelectRandom(ref numNodesConsidered); if (selectedFromChild != null) { selected = selectedFromChild; } } return(selected); }
internal static void SwapSubtrees( NodeBaseType <T, S> selectedNode1, NodeBaseType <T, S> selectedNode2, NodeBaseType <T, S> replacementNode1, NodeBaseType <T, S> replacementNode2) { // find the child we're going to replace var parent = (FunctionNode <T, S>)selectedNode1.Parent; for (int i = 0; i < parent.Children.Count; i++) { if (parent.Children[i] == selectedNode1) { parent.Children[i] = replacementNode2; replacementNode2.Parent = parent; selectedNode1.Parent = null; break; } } // find the child we're going to replace parent = (FunctionNode <T, S>)selectedNode2.Parent; for (int i = 0; i < parent.Children.Count; i++) { if (parent.Children[i] == selectedNode2) { parent.Children[i] = replacementNode1; replacementNode1.Parent = parent; selectedNode2.Parent = null; break; } } }
internal void Mutate() { // pick any node but the root (since that would be a replacement of the entire tree, not a mutation) NodeBaseType <T, S> randomNode = null; do { randomNode = SelectRandomNode(); } while (randomNode == Root); // build a random subtree bool buildFullTrees = Randomizer.GetFloatFromZeroToOne() < 0.5F; int depth = Randomizer.IntBetween(TreeMinDepth, TreeMaxDepth); var newSubtree = AddRandomNode(null, depth, buildFullTrees); // replace the randomly selected node with the new random one var parent = (FunctionNode <T, S>)randomNode.Parent; newSubtree.Parent = parent; // find the link from the parent to the old child, and replace it for (int i = 0; i < parent.Children.Count; i++) { if (parent.Children[i] == randomNode) { parent.Children[i] = newSubtree; break; } } }
public override NodeBaseType <T, S> Clone(NodeBaseType <T, S> parentNode) { var newNode = new TerminalFunctionNode <T, S>(functionMetadata, ownerCandidate); newNode.Parent = parentNode; return(newNode); }
public override NodeBaseType <T, S> Clone(NodeBaseType <T, S> parentNode) { // clone the node var newNode = new FunctionNode <T, S>(functionMetadata, ownerCandidate); newNode.Parent = parentNode; // clone the children foreach (var child in Children) { newNode.Children.Add(child.Clone(newNode)); } return(newNode); }
internal NodeBaseType <T, S> AddRandomNode(NodeBaseType <T, S> parentNode, int levelsToCreate, bool buildFullTrees) { // we're either adding a terminal node (const or var), or a function node (which has children) bool addingTerminal = false; // if we're at the max depth, add a terminal node if (levelsToCreate == 0) { addingTerminal = true; } else if (levelsToCreate >= TreeMinDepth) { // make sure we're at least a certain depth addingTerminal = false; } else { // we're somewhere between the min and max depth if (buildFullTrees) { addingTerminal = false; } else { // pick a random type, either function or terminal int numFuncs = primitiveSet.Functions.Count; int numTerminalFuncs = primitiveSet.TerminalFunctions.Count; int numVars = primitiveSet.VariableNames.Count; int numConsts = primitiveSet.Constants.Count; int random = Randomizer.IntLessThan(numFuncs + numTerminalFuncs + numVars + numConsts); if (random < numFuncs) { addingTerminal = false; } else { addingTerminal = true; } } } // Now that we know whether to add a function or terminal node, go ahead and do it if (addingTerminal) { var termNode = NewRandomTerminalNode(); termNode.Parent = parentNode; return(termNode); } else { var funcNode = NewRandomFunctionNode(); funcNode.Parent = parentNode; int numKids = funcNode.NumArguments; for (int i = 0; i < numKids; i++) { // recursively create descendent nodes funcNode.Children.Add(AddRandomNode(funcNode, levelsToCreate - 1, buildFullTrees)); } return(funcNode); } }