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> /// Returns true if inner1 can feasibly be swapped into inner2's position /// </summary> private bool VerifyPoints(GPNode inner1, GPNode inner2) { // We know they're swap-compatible since we generated inner1 // to be exactly that. So don't bother. // next check to see if inner1 can fit in inner2's spot if (inner1.Depth + inner2.AtDepth() > MaxDepth) { return(false); } // check for size 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 GPNode 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); }
private void Enqueue(GPNode n, int argpos, int depth) { if (s_node == null) { s_node = new GPNode[MIN_QUEUE_SIZE]; s_argpos = new int[MIN_QUEUE_SIZE]; s_depth = new int[MIN_QUEUE_SIZE]; s_size = 0; } else if (s_size == s_node.Length) // need to double them { var newSNode = new GPNode[s_size * 2]; Array.Copy(s_node, 0, newSNode, 0, s_size); s_node = newSNode; var newSArgpos = new int[s_size * 2]; Array.Copy(s_argpos, 0, newSArgpos, 0, s_size); s_argpos = newSArgpos; var newSDepth = new int[s_size * 2]; Array.Copy(s_depth, 0, newSDepth, 0, s_size); s_depth = newSDepth; } // okay, let's boogie! s_node[s_size] = n; s_argpos[s_size] = argpos; s_depth[s_size] = depth; s_size++; }
double Fitness(GPNode root) { // Compute the penality (it increases with the difference in depth between the tree and k. double penalty = 1 / (1 + Math.Abs(k + 1 - root.Depth)); return(penalty * FitnessHelper(root) / _bestFitness); }
void NodeCal(GPNode p, IEvolutionState state) { int pval = ((OrderTreeNode)p).Value; for (int i = 0; i < p.Children.Length; i++) { GPNode c = p.Children[i]; int cval = ((OrderTreeNode)c).Value; if (pval < cval) { // direct fitness contribution _fitness += FitnessContribution(cval, state); NodeCal(c, state); } else if (pval == cval) { // neutral-left-walk bool found = false; while (c.Children.Length > 0 && cval == pval && !found) { c = c.Children[0]; cval = ((OrderTreeNode)c).Value; if (pval < cval) { found = true; } } if (found) { _fitness += FitnessContribution(cval, state); NodeCal(c, state); } } } }
/** Used by the above function */ public IList GatherNodeString(IEvolutionState state, int threadnum, GPNode node, int index) { ArrayList list = new ArrayList(); if (node is ERC) { // Now, get the "key" from the "node", NOTE: the "node" is inside an ArrayList, // since the ERCBank is mapped as key --> ArrayList of GPNodes. // The "key" is the corresponding int value for the ERC. list.Add(node.Name.Trim()); // add "ERC" // then add the ERC key (original genome value) list.Add(GetKeyFromNode(state, threadnum, node, index).Trim()); } else { list.Add(node.ToString().Trim()); } if (node.Children.Length > 0) { for (int i = 0; i < node.Children.Length; i++) { index++; IList sublist = GatherNodeString(state, threadnum, node.Children[i], index); list.AddRange(sublist); } } return(list); }
/** * Recursively travel the tree so that depth and subtree below are computed * only once and can be reused later. * * @param node * @param nodeToDepth */ public void TraverseTreeForDepth(GPNode node, ArrayList nodeToDepth, Hashtable sizeToNodes) { GPNode[] children = node.Children; NodeInfo nodeInfo = new NodeInfo(node, node.NumNodes(GP.GPNode.NODESEARCH_NONTERMINALS)); nodeToDepth.Add(nodeInfo); // check to see if there is list in map for that size LinkedList <NodeInfo> listForSize = (LinkedList <NodeInfo>)sizeToNodes[nodeInfo.NumberOfSubTreesBeneath]; if (listForSize == null) { listForSize = new LinkedList <NodeInfo>(); sizeToNodes[nodeInfo.NumberOfSubTreesBeneath] = listForSize; } // add it to the list no matter what listForSize.AddLast(nodeInfo); // recurse if (children.Length > 0) { foreach (GPNode t in children) { TraverseTreeForDepth(t, nodeToDepth, sizeToNodes); } } }
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); }
public void Mutate(GPNode root, int index1, int maxLevels) { //We dont want to crossover root if (index1 == 1) { throw new Exception("Wrong index number for Mutate operation!"); } //start counter from 0 int count = 0; //Collection holds tree nodes Queue <Tuple <int, GPNode> > dataTree = new Queue <Tuple <int, GPNode> >(); //current node Tuple <int, GPNode> tuplenode = null; //Add tail recursion dataTree.Enqueue(new Tuple <int, GPNode>(0, root)); while (dataTree.Count > 0) { //get next node tuplenode = dataTree.Dequeue(); //count node count++; //perform mutation if (count == index1) { int level = maxLevels - tuplenode.Item1; if (level < 0) { throw new Exception("Level is not a correct number!"); } int rnd = Globals.radn.Next(level + 1); if (level <= 1 || rnd == 0) { tuplenode.Item2.value = Globals.GenerateNodeValue(false); GPNode.DestroyNodes(tuplenode.Item2.children); tuplenode.Item2.children = null; } else { var node = GenerateTreeStructure(rnd); tuplenode.Item2.value = node.value; tuplenode.Item2.children = node.children; } break; } if (tuplenode.Item2.children != null) { for (int i = tuplenode.Item2.children.Length - 1; i >= 0; i--) { dataTree.Enqueue(new Tuple <int, GPNode>(tuplenode.Item1 + 1, tuplenode.Item2.children[i])); } } } }
/// <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); }
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))); }
private static int NumRehangableNodesDirtyWork(GPNode root, int soFar) { if (root.Children.Length > 0) { soFar++; // rehangable } return(root.Children.Aggregate(soFar, (current, t) => NumRehangableNodesDirtyWork(t, current))); }
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))); }
public string GetKeyFromNode(IEvolutionState state, int threadnum, GPNode node, int index) { throw new NotImplementedException(); /* * string str = null; * // ERCBank has some contents at least. * if (ERCBank != null && ERCBank.Count != 0) * { * Iterator iter = ERCBank.EntrySet().iterator(); * while (iter.hasNext()) * { * Map.Entry pairs = (Map.Entry)iter.next(); * ArrayList nodeList = (ArrayList)pairs.getValue(); * if (Collections.binarySearch( * nodeList, * node, * new Comparator() * { * public int compare(Object o1, Object o2) * { * if (o1 is GPNode && o2 is GPNode) * return ((GPNode)o1).ToString(). * CompareTo(((GPNode)o2).ToString()); * return 0; * } * }) >= 0 ) * { * // a match found, save the key, break loop. * str = ((Int32)pairs.getKey()).ToString(); * break; * } * } * } * * // If a suitable match is not found in the above loop, * // Add the node in a new list and add it to the ERCBank * // with a new random value as a key. * if (str == null) * { * // if the hash-map is not created yet * if (ERCBank == null) ERCBank = new Hashtable(); * // if the index is still in the range of minGene.Length, use it. * // otherwise use the minGene[0] value. * int minIndex = 0; * if (index < MinGenes.Length) minIndex = index; * // now generate a new key * Int32 key = Integer.valueOf((int) MinGenes[minIndex] + state.Random[threadnum] + .NextInt((int) (MaxGenes[minIndex] - MinGenes[minIndex] + 1))); + ArrayList list = new ArrayList(); + list.Add(node.LightClone()); + ERCBank.Put(key, list); + str = key.ToString(); + } + return str; */ }
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 virtual void ReadTree(IEvolutionState state, BinaryReader reader) { var initializer = ((GPInitializer)state.Initializer); Child = GPNode.ReadRootedTree(state, reader, Constraints(initializer).TreeType, Constraints(initializer).FunctionSet, this, 0); }
private static bool Test(GPNode node, GPNodeGatherer filter) { if (node == null || filter == null) { return(false); } // use the GPNodeGatherer if available return(filter.Test(node)); }
/// <summary> /// Determines node equality by comparing the class, associated tree, and /// function name of the nodes. /// </summary> public override bool NodeEquals(GPNode node) { if (!GetType().Equals(node.GetType()) || Children.Length != node.Children.Length) { return(false); } var adf = (ADF)node; return(AssociatedTree == adf.AssociatedTree && FunctionName.Equals(adf.FunctionName)); }
/** * Calculate whether the tree rooted at n is a perfect subtree * of the appropriate type given the current parent. * @param parent * @param n root of the sub-tree to be tested. * @return whether it is a perfect subtree of the right type. */ bool IsPerfect(char parent, GPNode node, IEvolutionState state) { char nodeFn = ((RoyalTreeNode)node).Value; if (!IsSuccessor(parent, nodeFn, state)) { return(false); } return(node.Children.All(child => IsPerfect(nodeFn, child, state))); }
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 static void DemoteSomethingTypeless(GPNode node, IEvolutionState state, int thread, GPFunctionSet funcs) { var numDemotable = 0; // since we're typeless, we can demote under any nonterminal numDemotable = funcs.Nonterminals[0].Length; // pick a random item to demote -- numDemotable is assumed to be > 0 var demoteItem = state.Random[thread].NextInt(numDemotable); numDemotable = 0; // find it // clone the node var cnode = funcs.Nonterminals[0][demoteItem].LightClone(); var chityp = cnode.Constraints(((GPInitializer)state.Initializer)).ChildTypes; // choose a spot to hang the old parent under var choice = state.Random[thread].NextInt(cnode.Children.Length); for (var z = 0; z < cnode.Children.Length; z++) { if (z == choice) { // demote the parent, inserting cnode cnode.Parent = node.Parent; cnode.ArgPosition = node.ArgPosition; cnode.Children[z] = node; node.Parent = cnode; node.ArgPosition = (sbyte)z; if (cnode.Parent is GPNode) { ((GPNode)(cnode.Parent)).Children[cnode.ArgPosition] = cnode; } else { ((GPTree)(cnode.Parent)).Child = cnode; } } else { // hang a randomly-generated terminal off of cnode var term = funcs.Terminals [chityp[z].Type][state.Random[thread].NextInt(funcs.Terminals[chityp[z].Type].Length)].LightClone(); cnode.Children[z] = term; term.Parent = cnode; // just in case term.ArgPosition = (sbyte)z; // just in case term.ResetNode(state, thread); // let it randomize itself if necessary } } }
public override bool NodeEquals(GPNode node) { // check first to see if we're the same kind of ERC -- // won't work for subclasses; in that case you'll need // to change this to isAssignableTo(...) if (GetType() != node.GetType()) { return(false); } // now check to see if the ERCs hold the same value return(((RegERC)node).value == value); }
private static bool Test(GPNode node, int nodesearch) { if (node == null) { return(false); } // use the specified nodesearch return(nodesearch == GPNode.NODESEARCH_ALL || nodesearch == GPNode.NODESEARCH_TERMINALS && (node.Children == null || node.Children.Length == 0) || nodesearch == GPNode.NODESEARCH_NONTERMINALS && (node.Children != null && node.Children.Length > 0)); }
private static void SwapSomething(GPNode node, IEvolutionState state, int thread) { if (((GPInitializer)state.Initializer).NumAtomicTypes + ((GPInitializer)state.Initializer).NumSetTypes == 1) { // typeless SwapSomethingTypeless(node, state, thread); } else { SwapSomethingDirtyWork(node, state, thread); } }
private static void SwapSomethingDirtyWork(GPNode node, IEvolutionState state, int thread) { var numSwappable = 0; var initializer = ((GPInitializer)state.Initializer); 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! numSwappable++; } } } // pick a random item to swap -- numSwappable is assumed to be > 0 var swapItem = state.Random[thread].NextInt(numSwappable); numSwappable = 0; // find it 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])) { if (numSwappable == swapItem) // found it { // swap the children var tmp = node.Children[x]; node.Children[x] = node.Children[y]; node.Children[y] = tmp; node.Children[x].ArgPosition = (sbyte)x; node.Children[y].ArgPosition = (sbyte)y; // no need to set parent -- it's the same parent of course return; } numSwappable++; } } } }
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)); }
private static void DemoteSomething(GPNode node, IEvolutionState state, int thread, GPFunctionSet funcs) { // if I have just one type, do it the easy way if (((GPInitializer)state.Initializer).NumAtomicTypes + ((GPInitializer)state.Initializer).NumSetTypes == 1) { DemoteSomethingTypeless(node, state, thread, funcs); } // otherwise, I gotta do the dirty work else { DemoteSomethingDirtyWork(node, state, thread, funcs); } }
private int PickRehangableNode(GPNode root, int num) { // we don't include the tree root foreach (var t in root.Children) { num = PickRehangableNodeDirtyWork(t, num); if (num == -1) { break; // someone found it } } return(num); }
public string DecodeExpression(GPNode treeExpression, int langOption) { //Prepare chromoseme for evaluation var tokens = treeExpression.ToList(); int countT = tokens.Count; //Stack fr evaluation Stack <string> expression = new Stack <string>(); for (int i = countT - 1; i >= 0; i--) { if (tokens[i] >= 1000 && tokens[i] < 2000) { string varaiable = terminals[tokens[i] - 1000].Name; expression.Push(varaiable); } else { //prepare function arguments for evaluation int count = functions[tokens[i] - 2000].Aritry; string function = ""; if (langOption == 1) { function = functions[tokens[i] - 2000].MathematicaDefinition; } else if (langOption == 2) { function = functions[tokens[i] - 2000].ExcelDefinition; } else { function = functions[tokens[i] - 2000].Definition; } for (int j = 1; j <= count; j++) { string oldStr = "x" + (j).ToString(); string newStr = expression.Pop(); function = function.Replace(oldStr, newStr); } //Izracunavanje rezultata expression.Push("(" + function + ")"); } } // return the only value from stack Debug.Assert(expression.Count == 1); // return arguments.Pop(); return(expression.Pop()); }
/// <summary> /// Returns true if inner1's depth + atdepth +1 is within the depth bounds /// </summary> private bool VerifyPoint(GPNode inner1) { // We know they're swap-compatible since we generated inner1 // to be exactly that. So don't bother. // next check to see if inner1 can be demoted if (inner1.Depth + inner1.AtDepth() + 1 > MaxDepth) { return(false); } // checks done! return(true); }