public void GPNodeWriteAndRead() { var state = new SimpleEvolutionState(); var initializer = new GPInitializer(); state.Initializer = initializer; // Ensure that our initializer is accessible var treeConstraints = new GPTreeConstraints(); initializer.TreeConstraints = new List <GPTreeConstraints>(); initializer.TreeConstraints.Add(treeConstraints); // Ensure that our constraints are accessible var nodeConstraints = new GPNodeConstraints(); var rootType = new GPAtomicType("MyRootType"); treeConstraints.TreeType = rootType; var root = new MyRootNode(); var tree = new GPTree { Child = root }; root.Parent = tree; root.ArgPosition = 0; // This is the root, so there is only one position (0) }
/// <summary> /// MakeTree, edits the tree that its given by adding a root (and all subtrees attached) /// </summary> /// <returns>The number of chromosomes used, or an BIG_TREE_ERROR sentinel value.</returns> public int MakeTree(IEvolutionState state, int[] genome, GPTree tree, int position, int treeNum, int threadnum, IDictionary <int, GPNode> ercMapsForFancyPrint) { // hack, use an array to pass an extra value int[] countNumberOfChromosomesUsed = { position }; // hack, use an array to pass an extra value var gpfs = tree.Constraints((GPInitializer)state.Initializer).FunctionSet; GPNode root; try // get the tree, or return an error. { root = MakeSubtree(countNumberOfChromosomesUsed, genome, state, gpfs, Grammar[treeNum], treeNum, threadnum, ercMapsForFancyPrint, tree, (byte)0); } catch (BigTreeException) { return(BIG_TREE_ERROR); } if (root == null) { state.Output.Fatal("Invalid tree: tree #" + treeNum); } root.Parent = tree; tree.Child = root; return(countNumberOfChromosomesUsed[0]); }
/** * @param t Tree to be "executed" * @return expressed output */ ArrayList GetSemanticOutput(GPTree t) { ArrayList p = new ArrayList(); ArrayList nodes = new ArrayList(); // Is there a better way to get all the nodes in a depth-first // traversal? Note that the paper specifies inorder traversal, // but since we're only getting the terminals, preorder, // inorder, and postorder are equivalent. int nterminals = t.Child.NumNodes(GPNode.NODESEARCH_TERMINALS); for (int i = 0; i < nterminals; i++) { GPNodeGatherer g = new GPNodeGatherer(); t.Child.NodeInPosition(i, g, GPNode.NODESEARCH_TERMINALS); nodes.Add(g.Node); } if (_problemName.Equals(P_ORDER)) { // Order: first occurence counts for (int i = 0; i < nodes.Count; i++) { SemanticNode node = (SemanticNode)nodes[i]; if (!NodeSameIndexExists(p, node.Index)) { p.Add(node); } } } else { // Majority: most common counts for (int n = 0; n < _problemSize; n++) { int xCount = 0; int nCount = 0; int lastXNode = -1; for (int i = 0; i < nodes.Count; i++) { SemanticNode node = (SemanticNode)nodes[i]; if (node.Value == 'X' && node.Index == n) { xCount += 1; lastXNode = i; } else if (node.Value == 'N' && node.Index == n) { nCount += 1; } } if (xCount >= nCount && xCount > 0) { p.Add((SemanticNode)nodes[lastXNode]); } } } return(p); }
public static string PrintCodeFromTree(GPTree tree) { code = ""; var startNode = tree.Child; EvalNode(startNode); return(code); }
public void GPIndividualWriteAndRead() { // First we'll set up a Fitness for the Individual var rand = new MersenneTwisterFast(0); // Initialize some required context var state = new SimpleEvolutionState(); var initializer = new GPInitializer(); state.Initializer = initializer; // Required for GPTree.WriteTree(...) var constraints = new GPTreeConstraints { Name = "TestTreeConstraints" }; //initializer.TreeConstraints var tree = new GPTree(); var f = new KozaFitness(); f.SetStandardizedFitness(null, float.MaxValue); const int n = 10; f.Trials = new List <double>(n); for (var i = 0; i < n; i++) { f.Trials.Add(rand.NextDouble()); } // Now we can create and initialize the Individual var ind = new GPIndividual(); var ind2 = new GPIndividual(); // We'll read back into this instance ind.Trees = new GPTree[1]; // This is the set of genes ind.Trees[0] = new GPTree(); ind.Fitness = f; ind.Evaluated = true; using (var ms = new MemoryStream()) { var writer = new BinaryWriter(ms); ind.WriteIndividual(null, writer); ms.Position = 0; var reader = new BinaryReader(ms); ind2.Fitness = new SimpleFitness(); ind2.ReadIndividual(null, reader); Assert.IsTrue(ind.Fitness.EquivalentTo(ind2.Fitness)); Assert.IsTrue(ind2.Fitness.IsIdeal); Assert.IsTrue(ind.Equals(ind2)); // Genetically equivalent Assert.AreEqual(ind.Trees.Length, ind2.Trees.Length); } }
public void TestMethod1() { var tree = new GPTree(); var root = new ADF { FunctionName = "ADF0", Children = new GPNode[2] }; tree.Child = root; var c1 = new ADM { FunctionName = "ADM1", Parent = root, Children = new GPNode[2] }; var c11 = new ADF { FunctionName = "ADF11", Parent = c1 }; var c12 = new DummyERC { FunctionName = "ERC12", Parent = c1 }; c1.Children[0] = c11; c1.Children[1] = c12; var c2 = new ADM { FunctionName = "ADM2", Parent = root, Children = new GPNode[1] }; var c21 = new ADF { FunctionName = "ADF21", Parent = c2 }; c2.Children[0] = c21; root.Children = new GPNode[3]; root.Children[0] = c1; root.Children[1] = c2; root.Children[2] = new DummyERC { Parent = root }; // nodesearch (0=All, 1=Terminals, 2=Nonterminals) foreach (GPNode node in tree.Descendants(nodesearch: GPNode.NODESEARCH_ALL)) { var nodeName = node.Name; var t1 = node.Parent != null; var t2 = ((GPNode)node.Parent)?.Parent != null; var tabs = t2 ? 2 : t1 ? 1 : 0; var s = (tabs == 2 ? "\t\t" : tabs == 1 ? "\t" : "") + $"{nodeName}"; Console.WriteLine(s); } }
private static void TestCode() { ECActivator.AddSourceAssemblies(new[] { Assembly.GetAssembly(typeof(IEvolutionState)), Assembly.GetAssembly(typeof(ClassificationProblem)) }); var parameters = Evolve.LoadParameterDatabase(new[] { "-file", @"Params\App\Iris\koza.params" }); IEvolutionState state = Evolve.Initialize(parameters, 0); state.Setup(state, new Parameter(new string[] { "a" })); //state.Run(EvolutionState.C_STARTED_FRESH); // var individual = (GPIndividual)((SimpleStatistics)state.Statistics).BestOfRun[0]; var tree = new GPTree(); var reader = new System.IO.StreamReader("single_cl_ecj_graph.txt"); tree.ReadTree(state, reader); var writer = new System.IO.StreamWriter("testcode.txt"); var code = TreeReader.PrintCodeFromTree(tree); writer.Write(code); writer.Close(); }
private static void CheckTreeFromFile() { ECActivator.AddSourceAssemblies(new[] { Assembly.GetAssembly(typeof(IEvolutionState)), Assembly.GetAssembly(typeof(ClassificationProblem)) }); var parameters = Evolve.LoadParameterDatabase(new[] { "-file", @"Params\App\Iris\koza.params" }); IEvolutionState state = Evolve.Initialize(parameters, 0); state.Setup(state, new Parameter(new string[] { "a" })); //state.Run(EvolutionState.C_STARTED_FRESH); var individual = (GPIndividual)((SimpleStatistics)state.Statistics).BestOfRun[0]; var tree = new GPTree(); var reader = new System.IO.StreamReader("single_cl_ecj_graph.txt"); tree.ReadTree(state, reader); // individual.Setup(state, new Parameter(new string[] { "numtrees = 1", "1" })); individual.Trees[0] = tree; // CheckClassifierOnTestData(new[] { individual }, state, (int)ClassifierType.SINGLE_CLASSIFIER, directoryName); }
/** * This method finds a node using the logic given in the langdon paper. * @param nodeToSubtrees For Tree of Parent2 all precomputed stats about depth,subtrees etc * @param sizeToNodes Quick lookup for LinkedList of size to Nodes * @param parent1SelectedNode Node selected in parent1 * @param Tree2 Tree of parent2 * @param state Evolution State passed for getting access to Random Object of MersenneTwiser * @param thread thread number */ protected GPNode FindFairSizeNode(ArrayList nodeToSubtrees, Hashtable sizeToNodes, GPNode parent1SelectedNode, GPTree tree2, IEvolutionState state, int thread) { GPNode selectedNode = null; // get the size of subtrees of parent1 int parent1SubTrees = parent1SelectedNode.NumNodes(GPNode.NODESEARCH_NONTERMINALS); // the maximum length in mate we are looking for int maxmatesublen = parent1SubTrees == 0 ? 0 : 2 * parent1SubTrees + 1; // lets see if for all lengths we have trees corresponding bool[] mateSizeAvailable = new bool[maxmatesublen + 1]; // initialize the array to false for (int i = 0; i < maxmatesublen; i++) { mateSizeAvailable[i] = false; } // check for ones we have for (int i = 0; i < nodeToSubtrees.Count; i++) { NodeInfo nodeInfo = (NodeInfo)nodeToSubtrees[i]; // get the length of trees int subtree = nodeInfo.NumberOfSubTreesBeneath; if (subtree <= maxmatesublen) { mateSizeAvailable[subtree] = true; } } // choose matesublen so mean size change=0 if possible int countOfPositives = 0; int countOfNegatives = 0; int sumOfPositives = 0; int sumOfNegatives = 0; int l; for (l = 1; l < parent1SubTrees; l++) { if (mateSizeAvailable[l]) { countOfNegatives++; sumOfNegatives += parent1SubTrees - l; } } for (l = parent1SubTrees + 1; l <= maxmatesublen; l++) { if (mateSizeAvailable[l]) { countOfPositives++; sumOfPositives += l - parent1SubTrees; } } // if they are missing use the same int mateSublengthSelected = 0; if (sumOfPositives == 0 || sumOfNegatives == 0) { //if so then check if mate has the length and use that if (mateSizeAvailable[parent1SubTrees]) { mateSublengthSelected = parent1SubTrees; } //else we go with zero } else { // probability of same is dependent on do we find same sub trees // else 0.0 double pzero = (mateSizeAvailable[parent1SubTrees]) ? 1.0 / parent1SubTrees : 0.0; // positive probability double ppositive = (1.0 - pzero) / (countOfPositives + ((double)(countOfNegatives * sumOfPositives) / (sumOfNegatives))); // negative probability double pnegative = (1.0 - pzero) / (countOfNegatives + ((double)(countOfPositives * sumOfNegatives) / (sumOfPositives))); // total probability, just for making sure math is right ;-) double total = countOfNegatives * pnegative + pzero + countOfPositives * ppositive; // putting an assert for floating point calculations, similar to what langdon does // assert(total<1.01&&total>.99); // now create a Roulette Wheel RouletteWheelSelector wheel = new RouletteWheelSelector(maxmatesublen); // add probabilities to the wheel // all below the length of parent node get pnegative // all above get ppositive and one on node gets pzero for (l = 1; l < parent1SubTrees; l++) { if (mateSizeAvailable[l]) { wheel.Add(pnegative, l); } } if (mateSizeAvailable[parent1SubTrees]) { wheel.Add(pzero, parent1SubTrees); } for (l = parent1SubTrees + 1; l <= maxmatesublen; l++) { if (mateSizeAvailable[l]) { wheel.Add(ppositive, l); } } // spin the wheel mateSublengthSelected = wheel.Roulette(state, thread); } // now we have length chosen, but there can be many nodes with that // LinkedList <NodeInfo> listOfNodes = (LinkedList <NodeInfo>)sizeToNodes[mateSublengthSelected]; if (listOfNodes == null) { state.Output.Fatal("In SizeFairCrossoverPipeline, nodes for tree length " + mateSublengthSelected + " is null, indicates some serious error"); } // in size fair we choose the elements at random for given length int chosenNode = 0; // if using fair size get random from the list if (!Homologous) { chosenNode = state.Random[thread].NextInt(listOfNodes.Count); } // if Homologous else { if (listOfNodes.Count > 1) { GPInitializer initializer = ((GPInitializer)state.Initializer); int currentMinDistance = int.MaxValue; for (int i = 0; i < listOfNodes.Count; i++) { // get the GP node GPNode selectedMateNode = listOfNodes.ElementAt(i).Node; // now lets traverse selected and parent 1 to see divergence GPNode currentMateNode = selectedMateNode; GPNode currentParent1Node = parent1SelectedNode; // found a match? bool foundAMatchInAncestor = false; int distance = 0; while (currentMateNode.Parent != null && currentMateNode.Parent is GPNode && currentParent1Node.Parent != null && currentParent1Node.Parent is GPNode && !foundAMatchInAncestor) { GPNode parent1 = (GPNode)currentParent1Node.Parent; GPNode parent2 = (GPNode)currentMateNode.Parent; // if there is match between compatibility of Parents break if (parent1.SwapCompatibleWith(initializer, parent2)) { foundAMatchInAncestor = true; break; } else { // need to go one level above of both currentMateNode = parent2; currentParent1Node = parent1; //increment the distance distance = distance + 1; } } // find the one with least distance if (distance < currentMinDistance) { currentMinDistance = distance; chosenNode = i; } } } // else take the first node, no choice } NodeInfo nodeInfoSelected = listOfNodes.ElementAt(chosenNode); selectedNode = nodeInfoSelected.Node; return(selectedNode); }
public override int Produce( int min, int max, int subpop, IList <Individual> inds, IEvolutionState state, int thread, IDictionary <string, object> misc) { int start = inds.Count; // how many individuals should we make? int n = TypicalIndsProduced; if (n < min) { n = min; } if (n > max) { n = max; } // should we bother? if (!state.Random[thread].NextBoolean(Likelihood)) { // just load from source 0 and clone 'em Sources[0].Produce(n, n, subpop, inds, state, thread, misc); return(n); } IntBag[] parentparents = null; IntBag[] preserveParents = null; if (misc != null && misc.ContainsKey(KEY_PARENTS)) { preserveParents = (IntBag[])misc[KEY_PARENTS]; parentparents = new IntBag[2]; misc[KEY_PARENTS] = parentparents; } GPInitializer initializer = (GPInitializer)state.Initializer; for (int q = start; q < n + start; /* no increment */) // keep on going until we're filled up { Parents.Clear(); // grab two individuals from our sources if (Sources[0] == Sources[1]) // grab from the same source { Sources[0].Produce(2, 2, subpop, Parents, state, thread, misc); } else // grab from different sources { Sources[0].Produce(1, 1, subpop, Parents, state, thread, misc); Sources[1].Produce(1, 1, subpop, Parents, state, thread, misc); } // at this point, Parents[] contains our two selected individuals // are our tree values valid? if (Tree1 != TREE_UNFIXED && (Tree1 < 0 || Tree1 >= ((GPIndividual)Parents[0]).Trees.Length)) { // uh oh state.Output.Fatal( "GP Crossover Pipeline attempted to fix tree.0 to a value which was out of bounds of the array of the individual's trees. Check the pipeline's fixed tree values -- they may be negative or greater than the number of trees in an individual"); } if (Tree2 != TREE_UNFIXED && (Tree2 < 0 || Tree2 >= ((GPIndividual)Parents[1]).Trees.Length)) { // uh oh state.Output.Fatal( "GP Crossover Pipeline attempted to fix tree.1 to a value which was out of bounds of the array of the individual's trees. Check the pipeline's fixed tree values -- they may be negative or greater than the number of trees in an individual"); } int t1; int t2; if (Tree1 == TREE_UNFIXED || Tree2 == TREE_UNFIXED) { do // pick random trees -- their GPTreeConstraints must be the same { if (Tree1 == TREE_UNFIXED) { if (((GPIndividual)Parents[0]).Trees.Length > 1) { t1 = state.Random[thread].NextInt(((GPIndividual)Parents[0]).Trees.Length); } else { t1 = 0; } } else { t1 = Tree1; } if (Tree2 == TREE_UNFIXED) { if (((GPIndividual)Parents[1]).Trees.Length > 1) { t2 = state.Random[thread].NextInt(((GPIndividual)Parents[1]).Trees.Length); } else { t2 = 0; } } else { t2 = Tree2; } } while (((GPIndividual)Parents[0]).Trees[t1].Constraints(initializer) != ((GPIndividual)Parents[1]).Trees[t2].Constraints(initializer)); } else { t1 = Tree1; t2 = Tree2; // make sure the constraints are okay if (((GPIndividual)Parents[0]).Trees[t1].Constraints(initializer) != ((GPIndividual)Parents[1]).Trees[t2].Constraints(initializer)) // uh oh { state.Output.Fatal( "GP Crossover Pipeline's two tree choices are both specified by the user -- but their GPTreeConstraints are not the same"); } } bool res1 = false; bool res2 = false; // BRS: This is kind of stupid to name it this way! GPTree currTree = ((GPIndividual)Parents[1]).Trees[t2]; // pick some nodes GPNode p1 = null; GPNode p2 = null; // lets walk on parent2 all nodes to get subtrees for each node, doing it once for O(N) and not O(N^2) // because depth etc are computed and not stored ArrayList nodeToSubtrees = new ArrayList(); // also Hashtable for size to List() of nodes in that size for O(1) lookup Hashtable sizeToNodes = new Hashtable(); TraverseTreeForDepth(currTree.Child, nodeToSubtrees, sizeToNodes); // sort the ArrayList with comparator that sorts by subtrees nodeToSubtrees.Sort(new NodeComparator()); for (int x = 0; x < NumTries; x++) { // pick a node in individual 1 p1 = NodeSelect1.PickNode(state, subpop, thread, (GPIndividual)Parents[0], ((GPIndividual)Parents[0]).Trees[t1]); // now lets find "similar" in parent 2 p2 = FindFairSizeNode(nodeToSubtrees, sizeToNodes, p1, currTree, state, thread); // check for depth and swap-compatibility limits res1 = VerifyPoints(initializer, p2, p1); // p2 can fill p1's spot -- order is important! if (n - (q - start) < 2 || TossSecondParent) { res2 = true; } else { res2 = VerifyPoints(initializer, p1, p2); // p1 can fill p2's spot -- order is important! } // did we get something that had both nodes verified? // we reject if EITHER of them is invalid. This is what lil-gp // does. // Koza only has numTries set to 1, so it's compatible as well. if (res1 && res2) { break; } } // at this point, res1 AND res2 are valid, OR // either res1 OR res2 is valid and we ran out of tries, OR // neither res1 nor res2 is valid and we rand out of tries. // So now we will transfer to a tree which has res1 or res2 // valid, otherwise it'll just get replicated. This is // compatible with both Koza and lil-gp. // at this point I could check to see if my sources were breeding // pipelines -- but I'm too lazy to write that code (it's a little // complicated) to just swap one individual over or both over, // -- it might still entail some copying. Perhaps in the future. // It would make things faster perhaps, not requiring all that // cloning. // Create some new individuals based on the old ones -- since // GPTree doesn't deep-clone, this should be just fine. Perhaps we // should change this to proto off of the main species prototype, // but // we have to then copy so much stuff over; it's not worth it. GPIndividual j1 = ((GPIndividual)Parents[0]).LightClone(); GPIndividual j2 = null; if (n - (q - start) >= 2 && !TossSecondParent) { j2 = ((GPIndividual)Parents[1]).LightClone(); } // Fill in various tree information that didn't get filled in there j1.Trees = new GPTree[((GPIndividual)Parents[0]).Trees.Length]; if (n - (q - start) >= 2 && !TossSecondParent) { j2.Trees = new GPTree[((GPIndividual)Parents[1]).Trees.Length]; } // at this point, p1 or p2, or both, may be null. // If not, swap one in. Else just copy the parent. for (int x = 0; x < j1.Trees.Length; x++) { if (x == t1 && res1) // we've got a tree with a kicking cross // position! { j1.Trees[x] = ((GPIndividual)Parents[0]).Trees[x].LightClone(); j1.Trees[x].Owner = j1; j1.Trees[x].Child = ((GPIndividual)Parents[0]).Trees[x].Child.CloneReplacing(p2, p1); j1.Trees[x].Child.Parent = j1.Trees[x]; j1.Trees[x].Child.ArgPosition = 0; j1.Evaluated = false; } // it's changed else { j1.Trees[x] = ((GPIndividual)Parents[0]).Trees[x].LightClone(); j1.Trees[x].Owner = j1; j1.Trees[x].Child = (GPNode)((GPIndividual)Parents[0]).Trees[x].Child.Clone(); j1.Trees[x].Child.Parent = j1.Trees[x]; j1.Trees[x].Child.ArgPosition = 0; } } if (n - (q - start) >= 2 && !TossSecondParent) { for (int x = 0; x < j2.Trees.Length; x++) { if (x == t2 && res2) // we've got a tree with a kicking // cross position! { j2.Trees[x] = ((GPIndividual)Parents[1]).Trees[x].LightClone(); j2.Trees[x].Owner = j2; j2.Trees[x].Child = ((GPIndividual)Parents[1]).Trees[x].Child.CloneReplacing(p1, p2); j2.Trees[x].Child.Parent = j2.Trees[x]; j2.Trees[x].Child.ArgPosition = 0; j2.Evaluated = false; } // it's changed else { j2.Trees[x] = ((GPIndividual)Parents[1]).Trees[x].LightClone(); j2.Trees[x].Owner = j2; j2.Trees[x].Child = (GPNode)((GPIndividual)Parents[1]).Trees[x].Child.Clone(); j2.Trees[x].Child.Parent = j2.Trees[x]; j2.Trees[x].Child.ArgPosition = 0; } } } // add the individuals to the population // by Ermo. I think this should be add // inds.set(q,j1); // Yes -- Sean inds.Add(j1); if (preserveParents != null) { parentparents[0].AddAll(parentparents[1]); preserveParents[q] = parentparents[0]; } q++; if (q < n + start && !TossSecondParent) { // by Ermo. Same reason, should changed to add //inds[q] = j2; inds.Add(j2); if (preserveParents != null) { preserveParents[q] = parentparents[0]; } q++; } } return(n); }
/** Flattens an S-expression */ public IList FlattenSexp(IEvolutionState state, int threadnum, GPTree tree) { IList nodeList = GatherNodeString(state, threadnum, tree.Child, 0); return(nodeList); }
public virtual GPNode PickNode(IEvolutionState s, int subpop, int thread, GPIndividual ind, GPTree tree) { var rnd = s.Random[thread].NextDouble(); if (rnd > NonterminalProbability + TerminalProbability + RootProbability) // pick anyone { if (Nodes == -1) { Nodes = tree.Child.NumNodes(GPNode.NODESEARCH_ALL); } { return(tree.Child.NodeInPosition(s.Random[thread].NextInt(Nodes), GPNode.NODESEARCH_ALL)); } } if (rnd > NonterminalProbability + TerminalProbability) // pick the root { return(tree.Child); } if (rnd > NonterminalProbability) // pick terminals { if (Terminals == -1) { Terminals = tree.Child.NumNodes(GPNode.NODESEARCH_TERMINALS); } return(tree.Child.NodeInPosition(s.Random[thread].NextInt(Terminals), GPNode.NODESEARCH_TERMINALS)); } // pick nonterminals if you can if (Nonterminals == -1) { Nonterminals = tree.Child.NumNodes(GPNode.NODESEARCH_NONTERMINALS); } if (Nonterminals > 0) // there are some nonterminals { return(tree.Child.NodeInPosition(s.Random[thread].NextInt(Nonterminals), GPNode.NODESEARCH_NONTERMINALS)); } // there ARE no nonterminals! It must be the root node return(tree.Child); }