//ramped half-and-half: grow method public BehaviourNode innerGrowTree(int maxDepth, List <System.Type> Functions, List <System.Type> terminals, bool isTerminal) { if (maxDepth < 0) { return(null); } if (maxDepth == 0) { isTerminal = true; } int nextNode = UnityEngine.Random.Range(0, (isTerminal == true? terminals.Count : Functions.Count)); List <BehaviourNode> l = new List <BehaviourNode>(); BehaviourNode rootNode = (BehaviourNode)System.Activator.CreateInstance(isTerminal == true? terminals[nextNode] : Functions[nextNode]); if (!isTerminal) { int numberOfBranches = ((IFunction)rootNode).parameters; for (int i = 0; i < Mathf.Max(numberOfBranches, 2); i++) { bool isTerm = UnityEngine.Random.Range(0, 100) > depthIncreaseProb; l.Add(innerGrowTree(maxDepth - 1, Functions, terminals, isTerm)); } } rootNode.setNextNodes(l); return(rootNode); }
//Recursive method used by constructRandom() //full method private BehaviourNode constructRandomInner(int depth, List <System.Type> types, int branchingFactor) { if (depth <= 0) { return(null); } List <BehaviourNode> l = new List <BehaviourNode>(); int nextNode = Random.Range(0, types.Count); BehaviourNode newNode = (BehaviourNode)System.Activator.CreateInstance(types[nextNode]); //Debug.Log("created node: " + types[nextNode]); for (int i = 0; i < branchingFactor; i++) { l.Add(constructRandomInner(depth - 1, types, branchingFactor)); } newNode.setNextNodes(l); return(newNode); }
public void mutate(BehaviourNode current, BehaviourNode parent, int i) { if (current is IFunction && Random.Range(0, 1) < functionMutationRate && parent != null) { int randomFunction = Random.Range(0, functions.Count - 1); BehaviourNode function = (BehaviourNode)System.Activator.CreateInstance(functions[randomFunction]); function.setNextNodes(current.getNextNodes()); parent.getNextNodes()[i] = function; } else if (Random.Range(0, 1) < terminalMutationRate) { current.mutate(); } int index = 0; foreach (BehaviourNode child in current.getNextNodes()) { index++; mutate(child, current, index); } }