Free cookie consent management tool by TermsFeed Policy Generator

Ignore:
Timestamp:
03/26/10 19:34:29 (15 years ago)
Author:
gkronber
Message:

Added work in progress for the artificial ant problem #952 (Artificial Ant Problem for 3.3) and for the symbolic expression tree encoding #937 (Data types and operators for symbolic expression tree encoding).

Location:
trunk/sources/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding
Files:
1 edited
1 moved

Legend:

Unmodified
Added
Removed
  • trunk/sources/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.3/Creators/ProbabilisticTreeCreator.cs

    r3219 r3223  
    2424using HeuristicLab.Random;
    2525using System;
    26 
    27 namespace HeuristicLab.Encodings.SymbolicExpressionTree {
    28   public class ProbabilisticTreeCreator : OperatorBase {
    29     private static int MAX_TRIES { get { return 100; } }
    30 
    31     public override string Description {
    32       get { return @"Generates a new random operator tree."; }
    33     }
    34 
     26using System.Linq;
     27using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
     28using System.Collections.Generic;
     29
     30namespace HeuristicLab.Encodings.SymbolicExpressionTreeEncoding {
     31  [StorableClass]
     32  [Item("ProbabilisticTreeCreator", "An operator that creates new symbolic expression trees with uniformly distributed size")]
     33  public class ProbabilisticTreeCreator : SymbolicExpressionTreeCreator {
     34    private const int MAX_TRIES = 100;
    3535    public ProbabilisticTreeCreator()
    3636      : base() {
    37       AddVariableInfo(new VariableInfo("Random", "Uniform random number generator", typeof(MersenneTwister), VariableKind.In));
    38       AddVariableInfo(new VariableInfo("FunctionLibrary", "The function library containing all available functions", typeof(FunctionLibrary), VariableKind.In));
    39       AddVariableInfo(new VariableInfo("MinTreeSize", "The minimal allowed size of the tree", typeof(IntData), VariableKind.In));
    40       AddVariableInfo(new VariableInfo("MaxTreeSize", "The maximal allowed size of the tree", typeof(IntData), VariableKind.In));
    41       AddVariableInfo(new VariableInfo("MaxTreeHeight", "The maximal allowed height of the tree", typeof(IntData), VariableKind.In));
    42       AddVariableInfo(new VariableInfo("FunctionTree", "The created tree", typeof(IGeneticProgrammingModel), VariableKind.New | VariableKind.Out));
    43     }
    44 
    45     public override IOperation Apply(IScope scope) {
    46       IRandom random = GetVariableValue<IRandom>("Random", scope, true);
    47       FunctionLibrary funLibrary = GetVariableValue<FunctionLibrary>("FunctionLibrary", scope, true);
    48       int minTreeSize = GetVariableValue<IntData>("MinTreeSize", scope, true).Data;
    49       int maxTreeSize = GetVariableValue<IntData>("MaxTreeSize", scope, true).Data;
    50       int maxTreeHeight = GetVariableValue<IntData>("MaxTreeHeight", scope, true).Data;
    51 
    52       IFunctionTree root = Create(random, funLibrary, minTreeSize, maxTreeSize, maxTreeHeight);
    53       scope.AddVariable(new HeuristicLab.Core.Variable(scope.TranslateName("FunctionTree"), new GeneticProgrammingModel(root)));
    54       return Util.CreateInitializationOperation(TreeGardener.GetAllSubTrees(root), scope);
    55     }
    56 
    57 
    58     public static IFunctionTree Create(IRandom random, FunctionLibrary funLib, int minSize, int maxSize, int maxHeight) {
    59       int treeSize = random.Next(minSize, maxSize);
    60       IFunctionTree root = null;
     37    }
     38
     39    protected override SymbolicExpressionTree Create(IRandom random, ISymbolicExpressionGrammar grammar, IntValue maxTreeSize, IntValue maxTreeHeight) {
     40      return Apply(random, grammar, maxTreeSize.Value, maxTreeHeight.Value);
     41    }
     42
     43    public SymbolicExpressionTree Apply(IRandom random, ISymbolicExpressionGrammar grammar, int maxTreeSize, int maxTreeHeight) {
     44      // tree size is limited by the grammar and by the explicit size constraints
     45      int allowedMinSize = grammar.MinimalExpressionLength(grammar.StartSymbol);
     46      int allowedMaxSize = Math.Min(maxTreeSize, grammar.MaximalExpressionLength(grammar.StartSymbol));
     47      // select a target tree size uniformly in the possible range (as determined by explicit limits and limits of the grammar)
     48      int treeSize = random.Next(allowedMinSize, allowedMaxSize);
     49      SymbolicExpressionTree tree = new SymbolicExpressionTree();
    6150      int tries = 0;
    62       TreeGardener gardener = new TreeGardener(random, funLib);
    6351      do {
    6452        try {
    65           root = gardener.PTC2(treeSize, maxHeight);
     53          // determine possible root symbols to create a tree of the target size
     54          var possibleRootSymbols = from symbol in grammar.AllowedSymbols(grammar.StartSymbol, 0)
     55                                    where treeSize <= grammar.MaximalExpressionLength(symbol)
     56                                    where treeSize >= grammar.MinimalExpressionLength(symbol)
     57                                    select symbol;
     58          Symbol rootSymbol = SelectRandomSymbol(random, possibleRootSymbols);
     59          tree.Root = PTC2(random, grammar, rootSymbol, treeSize, maxTreeHeight);
    6660        }
    6761        catch (ArgumentException) {
    6862          // try a different size
    69           treeSize = random.Next(minSize, maxSize);
     63          treeSize = random.Next(allowedMinSize, allowedMaxSize);
    7064          tries = 0;
    7165        }
    7266        if (tries++ >= MAX_TRIES) {
    7367          // try a different size
    74           treeSize = random.Next(minSize, maxSize);
     68          treeSize = random.Next(allowedMinSize, allowedMaxSize);
    7569          tries = 0;
    7670        }
    77       } while (root == null || root.GetSize() > maxSize || root.GetHeight() > maxHeight);
     71      } while (tree.Root == null || tree.Size > maxTreeSize || tree.Height > maxTreeHeight);
     72      return tree;
     73    }
     74
     75    private Symbol SelectRandomSymbol(IRandom random, IEnumerable<Symbol> symbols) {
     76      var symbolList = symbols.ToList();
     77      return symbolList[random.Next(symbolList.Count)];
     78    }
     79
     80
     81    private SymbolicExpressionTreeNode PTC2(IRandom random, ISymbolicExpressionGrammar grammar, Symbol rootSymbol, int size, int maxDepth) {
     82      SymbolicExpressionTreeNode root = rootSymbol.CreateTreeNode();
     83      if (size <= 1 || maxDepth <= 1) return root;
     84      List<object[]> list = new List<object[]>();
     85      int currentSize = 1;
     86      int totalListMinSize = grammar.MinimalExpressionLength(rootSymbol) - 1;
     87
     88      int actualArity = SampleArity(random, grammar, rootSymbol, size);
     89      for (int i = 0; i < actualArity; i++) {
     90        // insert a dummy sub-tree and add the pending extension to the list
     91        root.AddSubTree(null);
     92        list.Add(new object[] { root, i, 2 });
     93      }
     94
     95      // while there are pending extension points and we have not reached the limit of adding new extension points
     96      while (list.Count > 0 && totalListMinSize + currentSize < size) {
     97        int randomIndex = random.Next(list.Count);
     98        object[] nextExtension = list[randomIndex];
     99        list.RemoveAt(randomIndex);
     100        SymbolicExpressionTreeNode parent = (SymbolicExpressionTreeNode)nextExtension[0];
     101        int argumentIndex = (int)nextExtension[1];
     102        int extensionDepth = (int)nextExtension[2];
     103        if (extensionDepth + grammar.MinimalExpressionDepth(parent.Symbol) >= maxDepth) {
     104          parent.RemoveSubTree(argumentIndex);
     105          SymbolicExpressionTreeNode branch = CreateMinimalTree(random, grammar, grammar.AllowedSymbols(parent.Symbol, argumentIndex));
     106          parent.InsertSubTree(argumentIndex, branch); // insert a smallest possible tree
     107          currentSize += branch.GetSize();
     108          totalListMinSize -= branch.GetSize();
     109        } else {
     110          var allowedSubFunctions = from s in grammar.AllowedSymbols(parent.Symbol, argumentIndex)
     111                                    where grammar.MinimalExpressionDepth(parent.Symbol) + extensionDepth - 1 < maxDepth
     112                                    where grammar.MaximalExpressionLength(s) > size - totalListMinSize - currentSize ||
     113                                          totalListMinSize + currentSize >= size * 0.9 // if the necessary size is almost reached then also allow
     114                                    // terminals or terminal-branches
     115                                    select s;
     116          Symbol selectedSymbol = SelectRandomSymbol(random, allowedSubFunctions);
     117          SymbolicExpressionTreeNode newTree = selectedSymbol.CreateTreeNode();
     118          parent.RemoveSubTree(argumentIndex);
     119          parent.InsertSubTree(argumentIndex, newTree);
     120          currentSize++;
     121          totalListMinSize--;
     122
     123          actualArity = SampleArity(random, grammar, selectedSymbol, size - currentSize);
     124          for (int i = 0; i < actualArity; i++) {
     125            // insert a dummy sub-tree and add the pending extension to the list
     126            newTree.AddSubTree(null);
     127            list.Add(new object[] { newTree, i, extensionDepth + 1 });
     128          }
     129          totalListMinSize += grammar.MinimalExpressionLength(selectedSymbol);
     130        }
     131      }
     132      // fill all pending extension points
     133      while (list.Count > 0) {
     134        int randomIndex = random.Next(list.Count);
     135        object[] nextExtension = list[randomIndex];
     136        list.RemoveAt(randomIndex);
     137        SymbolicExpressionTreeNode parent = (SymbolicExpressionTreeNode)nextExtension[0];
     138        int a = (int)nextExtension[1];
     139        int d = (int)nextExtension[2];
     140        parent.RemoveSubTree(a);
     141        parent.InsertSubTree(a,
     142          CreateMinimalTree(random, grammar, grammar.AllowedSymbols(parent.Symbol, a))); // append a tree with minimal possible height
     143      }
    78144      return root;
    79145    }
     146
     147    private int SampleArity(IRandom random, ISymbolicExpressionGrammar grammar, Symbol symbol, int targetSize) {
     148      // select actualArity randomly with the constraint that the sub-trees in the minimal arity can become large enough
     149      int minArity = grammar.MinSubTrees(symbol);
     150      int maxArity = grammar.MaxSubTrees(symbol);
     151      if (maxArity >= targetSize) {
     152        maxArity = targetSize;
     153      }
     154      // the min number of sub-trees has to be set to a value that is large enough so that the largest possible tree is at least tree size
     155      // if 1..3 trees are possible and the largest possible first sub-tree is smaller larger than the target size then minArity should be at least 2
     156      int aggregatedLongestExpressionLength = 1;
     157      for (int i = 0; i < maxArity; i++) {
     158        aggregatedLongestExpressionLength += (from s in grammar.AllowedSymbols(symbol, i)
     159                                              select grammar.MaximalExpressionLength(symbol)).Max();
     160        if (aggregatedLongestExpressionLength < targetSize) minArity = i;
     161        else break;
     162      }
     163
     164      // the max number of sub-trees has to be set to a value that is small enough so that the smallest possible tree is at most tree size
     165      // if 1..3 trees are possible and the smallest possible first sub-tree is already larger than the target size then maxArity should be at most 0
     166      int aggregatedShortestExpressionLength = 1;
     167      for (int i = 0; i < maxArity; i++) {
     168        aggregatedShortestExpressionLength += (from s in grammar.AllowedSymbols(symbol, i)
     169                                               select grammar.MinimalExpressionLength(symbol)).Min();
     170        if (aggregatedShortestExpressionLength > targetSize) {
     171          maxArity = i;
     172          break;
     173        }
     174      }
     175      if (minArity > maxArity) throw new ArgumentException();
     176      return random.Next(minArity, maxArity + 1);
     177    }
     178
     179    private SymbolicExpressionTreeNode CreateMinimalTree(IRandom random, ISymbolicExpressionGrammar grammar, IEnumerable<Symbol> symbols) {
     180      // determine possible symbols that will lead to the smallest possible tree
     181      var possibleSymbols = (from s in symbols
     182                             group s by grammar.MinimalExpressionLength(s) into g
     183                             orderby g.Key
     184                             select g).First();
     185      var selectedSymbol = SelectRandomSymbol(random, possibleSymbols);
     186      // build minimal tree by recursive application
     187      var tree = selectedSymbol.CreateTreeNode();
     188      for (int i = 0; i < grammar.MinSubTrees(selectedSymbol); i++)
     189        tree.AddSubTree(CreateMinimalTree(random, grammar, grammar.AllowedSymbols(selectedSymbol, i)));
     190      return tree;
     191    }
     192
     193    //private bool IsRecursiveExpansionPossible(Symbol symbol) {
     194    //  return FindCycle(function, new Stack<IFunction>());
     195    //}
     196
     197    //private Dictionary<IFunction, bool> inCycle = new Dictionary<IFunction, bool>();
     198    //private bool FindCycle(IFunction function, Stack<IFunction> functionChain) {
     199    //  if (inCycle.ContainsKey(function)) {
     200    //    return inCycle[function];
     201    //  } else if (IsTerminal(function)) {
     202    //    inCycle[function] = false;
     203    //    return false;
     204    //  } else if (functionChain.Contains(function)) {
     205    //    inCycle[function] = true;
     206    //    return true;
     207    //  } else {
     208    //    functionChain.Push(function);
     209    //    bool result = false;
     210    //    // all slot indexes
     211    //    for (int i = 0; i < function.MaxSubTrees; i++) {
     212    //      foreach (IFunction subFunction in GetAllowedSubFunctions(function, i)) {
     213    //        result |= FindCycle(subFunction, functionChain);
     214    //      }
     215    //    }
     216
     217    //    functionChain.Pop();
     218    //    inCycle[function] = result;
     219    //    return result;
     220    //  }
     221    //}
     222
    80223  }
    81224}
Note: See TracChangeset for help on using the changeset viewer.