public static ISymbolicExpressionTree CreateExpressionTree(IRandom random, ISymbolicExpressionGrammar grammar, int targetLength, int maxTreeDepth) { SymbolicExpressionTree tree = new SymbolicExpressionTree(); var rootNode = (SymbolicExpressionTreeTopLevelNode)grammar.ProgramRootSymbol.CreateTreeNode(); if (rootNode.HasLocalParameters) { rootNode.ResetLocalParameters(random); } rootNode.SetGrammar(grammar.CreateExpressionTreeGrammar()); var startNode = (SymbolicExpressionTreeTopLevelNode)grammar.StartSymbol.CreateTreeNode(); if (startNode.HasLocalParameters) { startNode.ResetLocalParameters(random); } startNode.SetGrammar(grammar.CreateExpressionTreeGrammar()); rootNode.AddSubtree(startNode); bool success = TryCreateFullTreeFromSeed(random, startNode, targetLength - 2, maxTreeDepth - 1); if (!success) { throw new InvalidOperationException(string.Format("Could not create a tree with target length {0} and max depth {1}", targetLength, maxTreeDepth)); } tree.Root = rootNode; return(tree); }
/// <summary> /// Returns a randomly chosen child node for the given <paramref name="parentNode"/>. /// </summary> /// <param name="parentNode">parent node to find a child node randomly for</param> /// <param name="genotype">integer vector, which should be mapped to a tree</param> /// <param name="grammar">grammar used to define the allowed child symbols</param> /// <param name="genotypeIndex">index in the integer vector; can be greater than vector length</param> /// <param name="random">random number generator</param> /// <returns>randomly chosen child node or null, if no child node exits</returns> protected ISymbolicExpressionTreeNode GetNewChildNode(ISymbolicExpressionTreeNode parentNode, IntegerVector genotype, ISymbolicExpressionGrammar grammar, int genotypeIndex, IRandom random) { // only select specific symbols, which can be interpreted ... IEnumerable <ISymbol> symbolList = (from s in grammar.GetAllowedChildSymbols(parentNode.Symbol) where s.InitialFrequency > 0.0 select s).ToList(); int prodRuleCount = symbolList.Count(); // no child node exists for the given parent node if (prodRuleCount < 1) { return(null); } // genotypeIndex % genotype.Length, if wrapping is allowed int prodRuleIndex = genotype[genotypeIndex] % prodRuleCount; var newNode = symbolList.ElementAt(prodRuleIndex).CreateTreeNode(); if (newNode.HasLocalParameters) { newNode.ResetLocalParameters(random); } return(newNode); }
/// <summary> /// Create a symbolic expression tree using 'RampedHalfAndHalf' strategy. /// Half the trees are created with the 'Grow' method, and the other half are created with the 'Full' method. /// </summary> /// <param name="random">Random generator</param> /// <param name="grammar">Available tree grammar</param> /// <param name="maxTreeLength">Maximum tree length (this parameter is ignored)</param> /// <param name="maxTreeDepth">Maximum tree depth</param> /// <returns></returns> public static ISymbolicExpressionTree Create(IRandom random, ISymbolicExpressionGrammar grammar, int maxTreeLength, int maxTreeDepth) { var tree = new SymbolicExpressionTree(); var rootNode = (SymbolicExpressionTreeTopLevelNode)grammar.ProgramRootSymbol.CreateTreeNode(); if (rootNode.HasLocalParameters) { rootNode.ResetLocalParameters(random); } rootNode.SetGrammar(grammar.CreateExpressionTreeGrammar()); var startNode = (SymbolicExpressionTreeTopLevelNode)grammar.StartSymbol.CreateTreeNode(); if (startNode.HasLocalParameters) { startNode.ResetLocalParameters(random); } startNode.SetGrammar(grammar.CreateExpressionTreeGrammar()); rootNode.AddSubtree(startNode); double p = random.NextDouble(); if (p < 0.5) { GrowTreeCreator.Create(random, startNode, maxTreeDepth - 2); } else { FullTreeCreator.Create(random, startNode, maxTreeDepth - 2); } tree.Root = rootNode; return(tree); }
/// <summary> /// Randomly returns a terminal node for the given <paramref name="parentNode"/>. /// (A terminal has got a minimum and maximum arity of 0.) /// </summary> /// <param name="parentNode">parent node for which a child node is returned randomly</param> /// <param name="grammar">grammar to determine the allowed child symbols for parentNode</param> /// <param name="random">random number generator</param> /// <returns>randomly chosen terminal node with arity 0 or null, if no terminal node exists</returns> protected ISymbolicExpressionTreeNode GetRandomTerminalNode(ISymbolicExpressionTreeNode parentNode, ISymbolicExpressionGrammar grammar, IRandom random) { // only select specific symbols, which can be interpreted ... var possibleSymbolsList = (from s in grammar.GetAllowedChildSymbols(parentNode.Symbol) where s.InitialFrequency > 0.0 where s.MaximumArity == 0 where s.MinimumArity == 0 select s).ToList(); // no terminal node exists for the given parent node if (!possibleSymbolsList.Any()) { return(null); } var newNode = possibleSymbolsList.SampleRandom(random).CreateTreeNode(); if (newNode.HasLocalParameters) { newNode.ResetLocalParameters(random); } return(newNode); }
internal EmptySymbolicExpressionTreeGrammar(ISymbolicExpressionGrammar grammar) : base() { if (grammar == null) { throw new ArgumentNullException(); } this.grammar = grammar; }
public SymbolicExpressionTreeGrammar(ISymbolicExpressionGrammar grammar) : base("SymbolicExpressionTreeGrammar", "A grammar that is used held by symbolic expression trees and allows extensions to the wrapped grammar.") { if (grammar == null) { throw new ArgumentNullException(); } this.grammar = grammar; }
public static ISymbolicExpressionTree[] CreateRandomTrees(MersenneTwister twister, Dataset dataset, ISymbolicExpressionGrammar grammar, int popSize, int minSize, int maxSize, int maxFunctionDefinitions, int maxFunctionArguments) { foreach (Variable variableSymbol in grammar.Symbols.OfType<Variable>()) { variableSymbol.VariableNames = dataset.VariableNames.Skip(1); } ISymbolicExpressionTree[] randomTrees = new ISymbolicExpressionTree[popSize]; for (int i = 0; i < randomTrees.Length; i++) { randomTrees[i] = ProbabilisticTreeCreator.Create(twister, grammar, maxSize, 10); } return randomTrees; }
/// <summary> /// Randomly determines an arity for the given node. /// </summary> /// <param name="random">random number generator</param> /// <param name="node">node, for which a random arity is determined</param> /// <param name="grammar">symbolic expression grammar to use</param> /// <returns>random arity in the interval [minArity, maxArity]</returns> protected int SampleArity(IRandom random, ISymbolicExpressionTreeNode node, ISymbolicExpressionGrammar grammar) { int minArity = grammar.GetMinimumSubtreeCount(node.Symbol); int maxArity = grammar.GetMaximumSubtreeCount(node.Symbol); if (minArity == maxArity) { return(minArity); } return(random.Next(minArity, maxArity)); }
public static ISymbolicExpressionTree Create(IRandom random, ISymbolicExpressionGrammar grammar, int maxTreeLength, int maxTreeDepth) { SymbolicExpressionTree tree = new SymbolicExpressionTree(); var rootNode = (SymbolicExpressionTreeTopLevelNode)grammar.ProgramRootSymbol.CreateTreeNode(); if (rootNode.HasLocalParameters) rootNode.ResetLocalParameters(random); rootNode.SetGrammar(grammar.CreateExpressionTreeGrammar()); var startNode = (SymbolicExpressionTreeTopLevelNode)grammar.StartSymbol.CreateTreeNode(); if (startNode.HasLocalParameters) startNode.ResetLocalParameters(random); startNode.SetGrammar(grammar.CreateExpressionTreeGrammar()); rootNode.AddSubtree(startNode); PTC2(random, startNode, maxTreeLength, maxTreeDepth); tree.Root = rootNode; return tree; }
/// <summary> /// Maps a genotype (an integer vector) to a phenotype (a symbolic expression tree). /// Random approach. /// </summary> /// <param name="random">random number generator</param> /// <param name="bounds">only used for PIGEMapper (ignore here)</param> /// <param name="length">only used for PIGEMapper (ignore here)</param> /// <param name="grammar">grammar definition</param> /// <param name="genotype">integer vector, which should be mapped to a tree</param> /// <returns>phenotype (a symbolic expression tree)</returns> public override SymbolicExpressionTree Map(IRandom random, IntMatrix bounds, int length, ISymbolicExpressionGrammar grammar, IntegerVector genotype) { SymbolicExpressionTree tree = new SymbolicExpressionTree(); var rootNode = (SymbolicExpressionTreeTopLevelNode)grammar.ProgramRootSymbol.CreateTreeNode(); var startNode = (SymbolicExpressionTreeTopLevelNode)grammar.StartSymbol.CreateTreeNode(); rootNode.AddSubtree(startNode); tree.Root = rootNode; MapRandomIteratively(startNode, genotype, grammar, genotype.Length, random); return tree; }
/// <summary> /// Maps a genotype (an integer vector) to a phenotype (a symbolic expression tree). /// Random approach. /// </summary> /// <param name="random">random number generator</param> /// <param name="bounds">only used for PIGEMapper (ignore here)</param> /// <param name="length">only used for PIGEMapper (ignore here)</param> /// <param name="grammar">grammar definition</param> /// <param name="genotype">integer vector, which should be mapped to a tree</param> /// <returns>phenotype (a symbolic expression tree)</returns> public override ISymbolicExpressionTree Map(IRandom random, IntMatrix bounds, int length, ISymbolicExpressionGrammar grammar, IntegerVector genotype) { SymbolicExpressionTree tree = new SymbolicExpressionTree(); var rootNode = (SymbolicExpressionTreeTopLevelNode)grammar.ProgramRootSymbol.CreateTreeNode(); var startNode = (SymbolicExpressionTreeTopLevelNode)grammar.StartSymbol.CreateTreeNode(); rootNode.AddSubtree(startNode); tree.Root = rootNode; MapRandomIteratively(startNode, genotype, grammar, genotype.Length, random); return(tree); }
private void SetInitialProbabilities() { ISymbolicExpressionGrammar grammar = SymbolicExpressionTreeGrammarParameter.Value; var symbols = grammar.AllowedSymbols.Where(x => x != grammar.ProgramRootSymbol).OrderBy(x => x.Name).Select(x => x.Name); double[,] props = new double[symbols.Count(), 1]; for (int i = 0; i < props.Length; i++) { props[i, 0] = 1.0; } ProbabilitiesParameter.Value = new PercentMatrix(props, new List <string>() { "Probability" }, symbols); }
/// <summary> /// Randomly returns a terminal node for the given <paramref name="parentNode"/>. /// (A terminal has got a minimum and maximum arity of 0.) /// </summary> /// <param name="parentNode">parent node for which a child node is returned randomly</param> /// <param name="grammar">grammar to determine the allowed child symbols for parentNode</param> /// <param name="random">random number generator</param> /// <returns>randomly chosen terminal node with arity 0 or null, if no terminal node exists</returns> protected ISymbolicExpressionTreeNode GetRandomTerminalNode(ISymbolicExpressionTreeNode parentNode, ISymbolicExpressionGrammar grammar, IRandom random) { // only select specific symbols, which can be interpreted ... var possibleSymbolsList = (from s in grammar.GetAllowedChildSymbols(parentNode.Symbol) where s.InitialFrequency > 0.0 where s.MaximumArity == 0 where s.MinimumArity == 0 select s).ToList(); // no terminal node exists for the given parent node if (!possibleSymbolsList.Any()) return null; var newNode = possibleSymbolsList.SampleRandom(random).CreateTreeNode(); if (newNode.HasLocalParameters) newNode.ResetLocalParameters(random); return newNode; }
public SymbolicExpressionTreeEncoding(string name, ISymbolicExpressionGrammar grammar, int maximumLength, int maximumDepth) : base(name) { treeLengthParameter = new FixedValueParameter <IntValue>(Name + ".Maximum Tree Length", "Maximal length of the symbolic expression.", new IntValue(maximumLength)); treeDepthParameter = new FixedValueParameter <IntValue>(Name + ".Maximum Tree Depth", "Maximal depth of the symbolic expression. The minimum depth needed for the algorithm is 3 because two levels are reserved for the ProgramRoot and the Start symbol.", new IntValue(maximumDepth)); grammarParameter = new ValueParameter <ISymbolicExpressionGrammar>(Name + ".Grammar", "The grammar that should be used for symbolic expression tree.", grammar); functionDefinitionsParameter = new FixedValueParameter <IntValue>(Name + ".Function Definitions", "Maximal number of automatically defined functions", new IntValue(0)); functionArgumentsParameter = new FixedValueParameter <IntValue>(Name + ".Function Arguments", "Maximal number of arguments of automatically defined functions.", new IntValue(0)); Parameters.Add(treeLengthParameter); Parameters.Add(treeDepthParameter); Parameters.Add(grammarParameter); Parameters.Add(functionDefinitionsParameter); Parameters.Add(functionArgumentsParameter); SolutionCreator = new ProbabilisticTreeCreator(); RegisterParameterEvents(); DiscoverOperators(); }
public static ISymbolicExpressionTree CreateExpressionTree(IRandom random, ISymbolicExpressionGrammar grammar, int targetLength, int maxTreeDepth) { SymbolicExpressionTree tree = new SymbolicExpressionTree(); var rootNode = (SymbolicExpressionTreeTopLevelNode)grammar.ProgramRootSymbol.CreateTreeNode(); if (rootNode.HasLocalParameters) rootNode.ResetLocalParameters(random); rootNode.SetGrammar(grammar.CreateExpressionTreeGrammar()); var startNode = (SymbolicExpressionTreeTopLevelNode)grammar.StartSymbol.CreateTreeNode(); if (startNode.HasLocalParameters) startNode.ResetLocalParameters(random); startNode.SetGrammar(grammar.CreateExpressionTreeGrammar()); rootNode.AddSubtree(startNode); bool success = TryCreateFullTreeFromSeed(random, startNode, targetLength - 2, maxTreeDepth - 1); if (!success) throw new InvalidOperationException(string.Format("Could not create a tree with target length {0} and max depth {1}", targetLength, maxTreeDepth)); tree.Root = rootNode; return tree; }
/// <summary> /// Genotype-to-Phenotype mapper (iterative 𝜋GE approach, using a list of not expanded nonTerminals). /// </summary> /// <param name="startNode">first node of the tree with arity 1</param> /// <param name="genotype">integer vector, which should be mapped to a tree</param> /// <param name="grammar">grammar to determine the allowed child symbols for each node</param> /// <param name="maxSubtreeCount">maximum allowed subtrees (= number of used genomes)</param> /// <param name="random">random number generator</param> private void MapPIGEIteratively(ISymbolicExpressionTreeNode startNode, IntegerVector genotype, ISymbolicExpressionGrammar grammar, int maxSubtreeCount, IRandom random) { List <ISymbolicExpressionTreeNode> nonTerminals = new List <ISymbolicExpressionTreeNode>(); int genotypeIndex = 0; nonTerminals.Add(startNode); while (nonTerminals.Count > 0) { if (genotypeIndex >= maxSubtreeCount) { // if all genomes were used, only add terminal nodes to the remaining subtrees ISymbolicExpressionTreeNode current = nonTerminals[0]; nonTerminals.RemoveAt(0); current.AddSubtree(GetRandomTerminalNode(current, grammar, random)); } else { // Order: NT = nont % Num. NT int nt = NontVector[genotypeIndex] % nonTerminals.Count; ISymbolicExpressionTreeNode current = nonTerminals[nt]; nonTerminals.RemoveAt(nt); // Content: Rule = rule % Num. Rules ISymbolicExpressionTreeNode newNode = GetNewChildNode(current, genotype, grammar, genotypeIndex, random); int arity = SampleArity(random, newNode, grammar); current.AddSubtree(newNode); genotypeIndex++; // new node has subtrees, so add "arity" number of copies of this node to the nonTerminals list for (int i = 0; i < arity; ++i) { nonTerminals.Add(newNode); } } } }
/// <summary> /// Genotype-to-Phenotype mapper (iterative depth-first approach, by using a stack -> LIFO). /// </summary> /// <param name="startNode">first node of the tree with arity 1</param> /// <param name="genotype">integer vector, which should be mapped to a tree</param> /// <param name="grammar">grammar to determine the allowed child symbols for each node</param> /// <param name="maxSubtreeCount">maximum allowed subtrees (= number of used genomes)</param> /// <param name="random">random number generator</param> private void MapDepthFirstIteratively(ISymbolicExpressionTreeNode startNode, IntegerVector genotype, ISymbolicExpressionGrammar grammar, int maxSubtreeCount, IRandom random) { Stack <Tuple <ISymbolicExpressionTreeNode, int> > stack = new Stack <Tuple <ISymbolicExpressionTreeNode, int> >(); // tuples of <node, arity> int genotypeIndex = 0; stack.Push(new Tuple <ISymbolicExpressionTreeNode, int>(startNode, 1)); while (stack.Count > 0) { // get next node from stack and re-push it, if this node still has unhandled subtrees ... Tuple <ISymbolicExpressionTreeNode, int> current = stack.Pop(); if (current.Item2 > 1) { stack.Push(new Tuple <ISymbolicExpressionTreeNode, int>(current.Item1, current.Item2 - 1)); } if (genotypeIndex >= maxSubtreeCount) { // if all genomes were used, only add terminal nodes to the remaining subtrees current.Item1.AddSubtree(GetRandomTerminalNode(current.Item1, grammar, random)); } else { var newNode = GetNewChildNode(current.Item1, genotype, grammar, genotypeIndex, random); int arity = SampleArity(random, newNode, grammar); current.Item1.AddSubtree(newNode); genotypeIndex++; if (arity > 0) { // new node has subtrees so push it onto the stack stack.Push(new Tuple <ISymbolicExpressionTreeNode, int>(newNode, arity)); } } } }
/// <summary> /// Genotype-to-Phenotype mapper (iterative breath-first approach, by using a queue -> FIFO). /// </summary> /// <param name="startNode">first node of the tree with arity 1</param> /// <param name="genotype">integer vector, which should be mapped to a tree</param> /// <param name="grammar">grammar to determine the allowed child symbols for each node</param> /// <param name="maxSubtreeCount">maximum allowed subtrees (= number of used genomes)</param> /// <param name="random">random number generator</param> private void MapBreathFirstIteratively(ISymbolicExpressionTreeNode startNode, IntegerVector genotype, ISymbolicExpressionGrammar grammar, int maxSubtreeCount, IRandom random) { Queue <Tuple <ISymbolicExpressionTreeNode, int> > queue = new Queue <Tuple <ISymbolicExpressionTreeNode, int> >(); // tuples of <node, arity> int genotypeIndex = 0; queue.Enqueue(new Tuple <ISymbolicExpressionTreeNode, int>(startNode, 1)); while (queue.Count > 0) { Tuple <ISymbolicExpressionTreeNode, int> current = queue.Dequeue(); // foreach subtree of the current node, create a new node and enqueue it, if it is no terminal node for (int i = 0; i < current.Item2; ++i) { if (genotypeIndex >= maxSubtreeCount) { // if all genomes were used, only add terminal nodes to the remaining subtrees current.Item1.AddSubtree(GetRandomTerminalNode(current.Item1, grammar, random)); } else { var newNode = GetNewChildNode(current.Item1, genotype, grammar, genotypeIndex, random); int arity = SampleArity(random, newNode, grammar); current.Item1.AddSubtree(newNode); genotypeIndex++; if (arity > 0) { // new node has subtrees so enqueue the node queue.Enqueue(new Tuple <ISymbolicExpressionTreeNode, int>(newNode, arity)); } } } } }
/// <summary> /// Create a symbolic expression tree using 'RampedHalfAndHalf' strategy. /// Half the trees are created with the 'Grow' method, and the other half are created with the 'Full' method. /// </summary> /// <param name="random">Random generator</param> /// <param name="grammar">Available tree grammar</param> /// <param name="maxTreeLength">Maximum tree length (this parameter is ignored)</param> /// <param name="maxTreeDepth">Maximum tree depth</param> /// <returns></returns> public static ISymbolicExpressionTree Create(IRandom random, ISymbolicExpressionGrammar grammar, int maxTreeLength, int maxTreeDepth) { var tree = new SymbolicExpressionTree(); var rootNode = (SymbolicExpressionTreeTopLevelNode)grammar.ProgramRootSymbol.CreateTreeNode(); if (rootNode.HasLocalParameters) rootNode.ResetLocalParameters(random); rootNode.SetGrammar(grammar.CreateExpressionTreeGrammar()); var startNode = (SymbolicExpressionTreeTopLevelNode)grammar.StartSymbol.CreateTreeNode(); if (startNode.HasLocalParameters) startNode.ResetLocalParameters(random); startNode.SetGrammar(grammar.CreateExpressionTreeGrammar()); rootNode.AddSubtree(startNode); double p = random.NextDouble(); if (p < 0.5) GrowTreeCreator.Create(random, startNode, maxTreeDepth - 2); else FullTreeCreator.Create(random, startNode, maxTreeDepth - 2); tree.Root = rootNode; return tree; }
/// <summary> /// Genotype-to-Phenotype mapper (iterative random approach, where the next non-terminal /// symbol to expand is randomly determined). /// </summary> /// <param name="startNode">first node of the tree with arity 1</param> /// <param name="genotype">integer vector, which should be mapped to a tree</param> /// <param name="grammar">grammar to determine the allowed child symbols for each node</param> /// <param name="maxSubtreeCount">maximum allowed subtrees (= number of used genomes)</param> /// <param name="random">random number generator</param> private void MapRandomIteratively(ISymbolicExpressionTreeNode startNode, IntegerVector genotype, ISymbolicExpressionGrammar grammar, int maxSubtreeCount, IRandom random) { List <ISymbolicExpressionTreeNode> nonTerminals = new List <ISymbolicExpressionTreeNode>(); int genotypeIndex = 0; nonTerminals.Add(startNode); while (nonTerminals.Count > 0) { if (genotypeIndex >= maxSubtreeCount) { // if all genomes were used, only add terminal nodes to the remaining subtrees ISymbolicExpressionTreeNode current = nonTerminals[0]; nonTerminals.RemoveAt(0); current.AddSubtree(GetRandomTerminalNode(current, grammar, random)); } else { // similar to PIGEMapper, but here the current node is determined randomly ... ISymbolicExpressionTreeNode current = nonTerminals.SampleRandom(random); nonTerminals.Remove(current); ISymbolicExpressionTreeNode newNode = GetNewChildNode(current, genotype, grammar, genotypeIndex, random); int arity = SampleArity(random, newNode, grammar); current.AddSubtree(newNode); genotypeIndex++; // new node has subtrees, so add "arity" number of copies of this node to the nonTerminals list for (int i = 0; i < arity; ++i) { nonTerminals.Add(newNode); } } } }
public static ISymbolicExpressionTree Create(IRandom random, ISymbolicExpressionGrammar grammar, int maxTreeLength, int maxTreeDepth) { SymbolicExpressionTree tree = new SymbolicExpressionTree(); var rootNode = (SymbolicExpressionTreeTopLevelNode)grammar.ProgramRootSymbol.CreateTreeNode(); if (rootNode.HasLocalParameters) { rootNode.ResetLocalParameters(random); } rootNode.SetGrammar(grammar.CreateExpressionTreeGrammar()); var startNode = (SymbolicExpressionTreeTopLevelNode)grammar.StartSymbol.CreateTreeNode(); if (startNode.HasLocalParameters) { startNode.ResetLocalParameters(random); } startNode.SetGrammar(grammar.CreateExpressionTreeGrammar()); rootNode.AddSubtree(startNode); PTC2(random, startNode, maxTreeLength, maxTreeDepth); tree.Root = rootNode; return(tree); }
/// <summary> /// Maps a genotype (an integer vector) to a phenotype (a symbolic expression tree). /// Depth-first approach. /// </summary> /// <param name="random">random number generator</param> /// <param name="bounds">only used for PIGEMapper (ignore here)</param> /// <param name="length">only used for PIGEMapper (ignore here)</param> /// <param name="grammar">grammar definition</param> /// <param name="genotype">integer vector, which should be mapped to a tree</param> /// <returns>phenotype (a symbolic expression tree)</returns> public override SymbolicExpressionTree Map(IRandom random, IntMatrix bounds, int length, ISymbolicExpressionGrammar grammar, IntegerVector genotype) { SymbolicExpressionTree tree = new SymbolicExpressionTree(); var rootNode = (SymbolicExpressionTreeTopLevelNode)grammar.ProgramRootSymbol.CreateTreeNode(); if (rootNode.HasLocalParameters) { rootNode.ResetLocalParameters(random); } var startNode = (SymbolicExpressionTreeTopLevelNode)grammar.StartSymbol.CreateTreeNode(); if (startNode.HasLocalParameters) { startNode.ResetLocalParameters(random); } rootNode.AddSubtree(startNode); tree.Root = rootNode; MapDepthFirstIteratively(startNode, genotype, grammar, genotype.Length, random); return(tree); }
/// <summary> /// Maps a genotype (an integer vector) to a phenotype (a symbolic expression tree). /// PIGE approach. /// </summary> /// <param name="random">random number generator</param> /// <param name="bounds">integer number range for genomes (codons) of the nont vector</param> /// <param name="length">length of the nont vector to create</param> /// <param name="grammar">grammar definition</param> /// <param name="genotype">integer vector, which should be mapped to a tree</param> /// <returns>phenotype (a symbolic expression tree)</returns> public override ISymbolicExpressionTree Map(IRandom random, IntMatrix bounds, int length, ISymbolicExpressionGrammar grammar, IntegerVector genotype) { SymbolicExpressionTree tree = new SymbolicExpressionTree(); var rootNode = (SymbolicExpressionTreeTopLevelNode)grammar.ProgramRootSymbol.CreateTreeNode(); var startNode = (SymbolicExpressionTreeTopLevelNode)grammar.StartSymbol.CreateTreeNode(); rootNode.AddSubtree(startNode); tree.Root = rootNode; // Map can be called simultaniously on multiple threads lock (nontVectorLocker) { if (NontVector == null) { NontVector = GetNontVector(random, bounds, length); } } MapPIGEIteratively(startNode, genotype, grammar, genotype.Length, random); return(tree); }
public ISymbolicExpressionTree CreateTree(IRandom random, ISymbolicExpressionGrammar grammar, int maxTreeLength, int maxTreeDepth) { double sum = Operators.CheckedItems.Sum(o => Probabilities[o.Index]); if (sum.IsAlmost(0)) { throw new InvalidOperationException(Name + ": All selected operators have zero probability."); } double r = random.NextDouble() * sum; sum = 0; int index = -1; foreach (var indexedItem in Operators.CheckedItems) { sum += Probabilities[indexedItem.Index]; if (sum > r) { index = indexedItem.Index; break; } } return(Operators[index].CreateTree(random, grammar, maxTreeLength, maxTreeDepth)); }
public static ISymbolicExpressionTree[] CreateRandomTrees(MersenneTwister twister, Dataset dataset, ISymbolicExpressionGrammar grammar, int popSize) { return(CreateRandomTrees(twister, dataset, grammar, popSize, 1, 200, 3, 3)); }
public SymbolicExpressionTreeGrammar(ISymbolicExpressionGrammar grammar) : base("SymbolicExpressionTreeGrammar", "A grammar that is used held by symbolic expression trees and allows extensions to the wrapped grammar.") { if (grammar == null) throw new ArgumentNullException(); this.grammar = grammar; }
public override ISymbolicExpressionTree CreateTree(IRandom random, ISymbolicExpressionGrammar grammar, int maxTreeLength, int maxTreeDepth) { return(Create(random, grammar, maxTreeLength, maxTreeDepth)); }
public abstract ISymbolicExpressionTree CreateTree(IRandom random, ISymbolicExpressionGrammar grammar, int maxTreeLength, int maxTreeDepth);
/// <summary> /// Maps a genotype (an integer vector) to a phenotype (a symbolic expression tree). /// PIGE approach. /// </summary> /// <param name="random">random number generator</param> /// <param name="bounds">integer number range for genomes (codons) of the nont vector</param> /// <param name="length">length of the nont vector to create</param> /// <param name="grammar">grammar definition</param> /// <param name="genotype">integer vector, which should be mapped to a tree</param> /// <returns>phenotype (a symbolic expression tree)</returns> public override ISymbolicExpressionTree Map(IRandom random, IntMatrix bounds, int length, ISymbolicExpressionGrammar grammar, IntegerVector genotype) { SymbolicExpressionTree tree = new SymbolicExpressionTree(); var rootNode = (SymbolicExpressionTreeTopLevelNode)grammar.ProgramRootSymbol.CreateTreeNode(); var startNode = (SymbolicExpressionTreeTopLevelNode)grammar.StartSymbol.CreateTreeNode(); rootNode.AddSubtree(startNode); tree.Root = rootNode; // Map can be called simultaniously on multiple threads lock (nontVectorLocker) { if (NontVector == null) { NontVector = GetNontVector(random, bounds, length); } } MapPIGEIteratively(startNode, genotype, grammar, genotype.Length, random); return tree; }
public static ISymbolicExpressionTree[] CreateRandomTrees(MersenneTwister twister, Dataset dataset, ISymbolicExpressionGrammar grammar, int popSize) { return CreateRandomTrees(twister, dataset, grammar, popSize, 1, 200, 3, 3); }
public abstract SymbolicExpressionTree Map(IRandom random, IntMatrix bounds, int length, ISymbolicExpressionGrammar grammar, IntegerVector genotype);
/// <summary> /// Randomly determines an arity for the given node. /// </summary> /// <param name="random">random number generator</param> /// <param name="node">node, for which a random arity is determined</param> /// <param name="grammar">symbolic expression grammar to use</param> /// <returns>random arity in the interval [minArity, maxArity]</returns> protected int SampleArity(IRandom random, ISymbolicExpressionTreeNode node, ISymbolicExpressionGrammar grammar) { int minArity = grammar.GetMinimumSubtreeCount(node.Symbol); int maxArity = grammar.GetMaximumSubtreeCount(node.Symbol); if (minArity == maxArity) { return minArity; } return random.Next(minArity, maxArity); }
public SymbolicExpressionTreeEncoding(ISymbolicExpressionGrammar grammar) : this("SymbolicExpressionTree", grammar, 50, 50) { }
public SymbolicExpressionTreeEncoding(ISymbolicExpressionGrammar grammar, int maximumLength, int maximumDepth) : this("SymbolicExpressionTree", grammar, maximumLength, maximumDepth) { }
/// <summary> /// Genotype-to-Phenotype mapper (iterative random approach, where the next non-terminal /// symbol to expand is randomly determined). /// </summary> /// <param name="startNode">first node of the tree with arity 1</param> /// <param name="genotype">integer vector, which should be mapped to a tree</param> /// <param name="grammar">grammar to determine the allowed child symbols for each node</param> /// <param name="maxSubtreeCount">maximum allowed subtrees (= number of used genomes)</param> /// <param name="random">random number generator</param> private void MapRandomIteratively(ISymbolicExpressionTreeNode startNode, IntegerVector genotype, ISymbolicExpressionGrammar grammar, int maxSubtreeCount, IRandom random) { List<ISymbolicExpressionTreeNode> nonTerminals = new List<ISymbolicExpressionTreeNode>(); int genotypeIndex = 0; nonTerminals.Add(startNode); while (nonTerminals.Count > 0) { if (genotypeIndex >= maxSubtreeCount) { // if all genomes were used, only add terminal nodes to the remaining subtrees ISymbolicExpressionTreeNode current = nonTerminals[0]; nonTerminals.RemoveAt(0); current.AddSubtree(GetRandomTerminalNode(current, grammar, random)); } else { // similar to PIGEMapper, but here the current node is determined randomly ... ISymbolicExpressionTreeNode current = nonTerminals.SampleRandom(random); nonTerminals.Remove(current); ISymbolicExpressionTreeNode newNode = GetNewChildNode(current, genotype, grammar, genotypeIndex, random); int arity = SampleArity(random, newNode, grammar); current.AddSubtree(newNode); genotypeIndex++; // new node has subtrees, so add "arity" number of copies of this node to the nonTerminals list for (int i = 0; i < arity; ++i) { nonTerminals.Add(newNode); } } } }
/// <summary> /// Genotype-to-Phenotype mapper (iterative depth-first approach, by using a stack -> LIFO). /// </summary> /// <param name="startNode">first node of the tree with arity 1</param> /// <param name="genotype">integer vector, which should be mapped to a tree</param> /// <param name="grammar">grammar to determine the allowed child symbols for each node</param> /// <param name="maxSubtreeCount">maximum allowed subtrees (= number of used genomes)</param> /// <param name="random">random number generator</param> private void MapDepthFirstIteratively(ISymbolicExpressionTreeNode startNode, IntegerVector genotype, ISymbolicExpressionGrammar grammar, int maxSubtreeCount, IRandom random) { Stack<Tuple<ISymbolicExpressionTreeNode, int>> stack = new Stack<Tuple<ISymbolicExpressionTreeNode, int>>(); // tuples of <node, arity> int genotypeIndex = 0; stack.Push(new Tuple<ISymbolicExpressionTreeNode, int>(startNode, 1)); while (stack.Count > 0) { // get next node from stack and re-push it, if this node still has unhandled subtrees ... Tuple<ISymbolicExpressionTreeNode, int> current = stack.Pop(); if (current.Item2 > 1) { stack.Push(new Tuple<ISymbolicExpressionTreeNode, int>(current.Item1, current.Item2 - 1)); } if (genotypeIndex >= maxSubtreeCount) { // if all genomes were used, only add terminal nodes to the remaining subtrees current.Item1.AddSubtree(GetRandomTerminalNode(current.Item1, grammar, random)); } else { var newNode = GetNewChildNode(current.Item1, genotype, grammar, genotypeIndex, random); int arity = SampleArity(random, newNode, grammar); current.Item1.AddSubtree(newNode); genotypeIndex++; if (arity > 0) { // new node has subtrees so push it onto the stack stack.Push(new Tuple<ISymbolicExpressionTreeNode, int>(newNode, arity)); } } } }
public static ISymbolicExpressionTree[] CreateRandomTrees(MersenneTwister twister, Dataset dataset, ISymbolicExpressionGrammar grammar, int popSize, int minSize, int maxSize, int maxFunctionDefinitions, int maxFunctionArguments) { foreach (Variable variableSymbol in grammar.Symbols.OfType <Variable>()) { variableSymbol.VariableNames = dataset.VariableNames.Skip(1); } ISymbolicExpressionTree[] randomTrees = new ISymbolicExpressionTree[popSize]; for (int i = 0; i < randomTrees.Length; i++) { randomTrees[i] = ProbabilisticTreeCreator.Create(twister, grammar, maxSize, 10); } return(randomTrees); }
/// <summary> /// Genotype-to-Phenotype mapper (iterative breath-first approach, by using a queue -> FIFO). /// </summary> /// <param name="startNode">first node of the tree with arity 1</param> /// <param name="genotype">integer vector, which should be mapped to a tree</param> /// <param name="grammar">grammar to determine the allowed child symbols for each node</param> /// <param name="maxSubtreeCount">maximum allowed subtrees (= number of used genomes)</param> /// <param name="random">random number generator</param> private void MapBreathFirstIteratively(ISymbolicExpressionTreeNode startNode, IntegerVector genotype, ISymbolicExpressionGrammar grammar, int maxSubtreeCount, IRandom random) { Queue<Tuple<ISymbolicExpressionTreeNode, int>> queue = new Queue<Tuple<ISymbolicExpressionTreeNode, int>>(); // tuples of <node, arity> int genotypeIndex = 0; queue.Enqueue(new Tuple<ISymbolicExpressionTreeNode, int>(startNode, 1)); while (queue.Count > 0) { Tuple<ISymbolicExpressionTreeNode, int> current = queue.Dequeue(); // foreach subtree of the current node, create a new node and enqueue it, if it is no terminal node for (int i = 0; i < current.Item2; ++i) { if (genotypeIndex >= maxSubtreeCount) { // if all genomes were used, only add terminal nodes to the remaining subtrees current.Item1.AddSubtree(GetRandomTerminalNode(current.Item1, grammar, random)); } else { var newNode = GetNewChildNode(current.Item1, genotype, grammar, genotypeIndex, random); int arity = SampleArity(random, newNode, grammar); current.Item1.AddSubtree(newNode); genotypeIndex++; if (arity > 0) { // new node has subtrees so enqueue the node queue.Enqueue(new Tuple<ISymbolicExpressionTreeNode, int>(newNode, arity)); } } } } }
internal EmptySymbolicExpressionTreeGrammar(ISymbolicExpressionGrammar grammar) : base() { if (grammar == null) throw new ArgumentNullException(); this.grammar = grammar; }
/// <summary> /// Returns a randomly chosen child node for the given <paramref name="parentNode"/>. /// </summary> /// <param name="parentNode">parent node to find a child node randomly for</param> /// <param name="genotype">integer vector, which should be mapped to a tree</param> /// <param name="grammar">grammar used to define the allowed child symbols</param> /// <param name="genotypeIndex">index in the integer vector; can be greater than vector length</param> /// <param name="random">random number generator</param> /// <returns>randomly chosen child node or null, if no child node exits</returns> protected ISymbolicExpressionTreeNode GetNewChildNode(ISymbolicExpressionTreeNode parentNode, IntegerVector genotype, ISymbolicExpressionGrammar grammar, int genotypeIndex, IRandom random) { // only select specific symbols, which can be interpreted ... IEnumerable<ISymbol> symbolList = (from s in grammar.GetAllowedChildSymbols(parentNode.Symbol) where s.InitialFrequency > 0.0 select s).ToList(); int prodRuleCount = symbolList.Count(); // no child node exists for the given parent node if (prodRuleCount < 1) return null; // genotypeIndex % genotype.Length, if wrapping is allowed int prodRuleIndex = genotype[genotypeIndex] % prodRuleCount; var newNode = symbolList.ElementAt(prodRuleIndex).CreateTreeNode(); if (newNode.HasLocalParameters) newNode.ResetLocalParameters(random); return newNode; }
public override ISymbolicExpressionTree CreateTree(IRandom random, ISymbolicExpressionGrammar grammar, int maxTreeLength, int maxTreeDepth) { return Create(random, grammar, maxTreeLength, maxTreeDepth); }
/// <summary> /// Genotype-to-Phenotype mapper (iterative 𝜋GE approach, using a list of not expanded nonTerminals). /// </summary> /// <param name="startNode">first node of the tree with arity 1</param> /// <param name="genotype">integer vector, which should be mapped to a tree</param> /// <param name="grammar">grammar to determine the allowed child symbols for each node</param> /// <param name="maxSubtreeCount">maximum allowed subtrees (= number of used genomes)</param> /// <param name="random">random number generator</param> private void MapPIGEIteratively(ISymbolicExpressionTreeNode startNode, IntegerVector genotype, ISymbolicExpressionGrammar grammar, int maxSubtreeCount, IRandom random) { List<ISymbolicExpressionTreeNode> nonTerminals = new List<ISymbolicExpressionTreeNode>(); int genotypeIndex = 0; nonTerminals.Add(startNode); while (nonTerminals.Count > 0) { if (genotypeIndex >= maxSubtreeCount) { // if all genomes were used, only add terminal nodes to the remaining subtrees ISymbolicExpressionTreeNode current = nonTerminals[0]; nonTerminals.RemoveAt(0); current.AddSubtree(GetRandomTerminalNode(current, grammar, random)); } else { // Order: NT = nont % Num. NT int nt = NontVector[genotypeIndex] % nonTerminals.Count; ISymbolicExpressionTreeNode current = nonTerminals[nt]; nonTerminals.RemoveAt(nt); // Content: Rule = rule % Num. Rules ISymbolicExpressionTreeNode newNode = GetNewChildNode(current, genotype, grammar, genotypeIndex, random); int arity = SampleArity(random, newNode, grammar); current.AddSubtree(newNode); genotypeIndex++; // new node has subtrees, so add "arity" number of copies of this node to the nonTerminals list for (int i = 0; i < arity; ++i) { nonTerminals.Add(newNode); } } } }