Free cookie consent management tool by TermsFeed Policy Generator

Ignore:
Timestamp:
04/13/10 20:44:31 (14 years ago)
Author:
gkronber
Message:

Fixed bugs related to dynamic symbol constraints with ADFs. #290 (Implement ADFs)

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/sources/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.3/ArchitectureAlteringOperators/ArgumentCreater.cs

    r3294 r3338  
    6060      var functionDefiningBranches = symbolicExpressionTree.IterateNodesPrefix().OfType<DefunTreeNode>();
    6161
    62       var allowedArgumentIndexes = Enumerable.Range(0, maxFunctionArguments);
    63 
    6462      if (functionDefiningBranches.Count() == 0)
    6563        // no function defining branch found => abort
    6664        return false;
     65
    6766      // select a random function defining branch
    68       var selectedDefunBranch = SelectRandomBranch(random, functionDefiningBranches);
     67      var selectedDefunBranch = functionDefiningBranches.SelectRandom(random);
     68      var definedArguments = (from symbol in selectedDefunBranch.Grammar.Symbols.OfType<Argument>()
     69                              select symbol.ArgumentIndex).Distinct();
     70      if (definedArguments.Count() >= maxFunctionArguments)
     71        // max number of arguments reached => abort
     72        return false;
    6973      // select a random cut point in the function defining branch
    7074      // the branch at the cut point is to be replaced by a new argument node
    71       var cutPoints = (from node in IterateNodesPrefix(selectedDefunBranch)
     75      var cutPoints = (from node in selectedDefunBranch.IterateNodesPrefix()
    7276                       where node.SubTrees.Count > 0
    7377                       from subtree in node.SubTrees
     
    7882        return false;
    7983      var selectedCutPoint = cutPoints[random.Next(cutPoints.Count)];
    80       var existingArguments = from node in IterateNodesPrefix(selectedDefunBranch)
    81                               let argNode = node as ArgumentTreeNode
    82                               where argNode != null
    83                               select argNode;
    84       var newArgumentIndex = allowedArgumentIndexes.Except(existingArguments.Select(x => x.ArgumentIndex)).First();
     84      var allowedArgumentIndexes = Enumerable.Range(0, maxFunctionArguments);
     85      var newArgumentIndex = allowedArgumentIndexes.Except(definedArguments).First();
    8586      // replace the branch at the cut point with an argument node
    8687      var newArgNode = MakeArgumentNode(newArgumentIndex);
     
    8889      selectedCutPoint.Parent.RemoveSubTree(selectedCutPoint.ReplacedChildIndex);
    8990      selectedCutPoint.Parent.InsertSubTree(selectedCutPoint.ReplacedChildIndex, newArgNode);
    90       // find all invokations of the selected ADF and attach a cloned version of the originally cut out branch
     91      // find all invocations of the selected ADF and attach a cloned version of the replaced branch (with all argument-nodes expanded)
    9192      var invocationNodes = from node in symbolicExpressionTree.IterateNodesPrefix().OfType<InvokeFunctionTreeNode>()
    92                             where node.InvokedFunctionName == selectedDefunBranch.Name
     93                            where node.Symbol.FunctionName == selectedDefunBranch.FunctionName
    9394                            select node;
    94       // append a new argument branch after preprocessing
    9595      foreach (var invocationNode in invocationNodes) {
     96        // append a new argument branch after expanding all argument nodes
    9697        var clonedBranch = (SymbolicExpressionTreeNode)replacedBranch.Clone();
    9798        ReplaceArgumentsInBranch(clonedBranch, invocationNode.SubTrees);
    9899        invocationNode.InsertSubTree(newArgumentIndex, clonedBranch);
    99100      }
    100       // adapt the known functions informations
     101      // increase expected number of arguments of function defining branch
     102      // it's possible that the number of actually referenced arguments was reduced (all references were replaced by a single new argument)
     103      // but the number of expected arguments is increased anyway
    101104      selectedDefunBranch.NumberOfArguments++;
    102       selectedDefunBranch.AddDynamicSymbol("ARG" + newArgumentIndex, 0);
     105      selectedDefunBranch.Grammar.AddSymbol(newArgNode.Symbol);
     106      selectedDefunBranch.Grammar.SetMinSubtreeCount(newArgNode.Symbol, 0);
     107      selectedDefunBranch.Grammar.SetMaxSubtreeCount(newArgNode.Symbol, 0);
     108      // allow the argument as child of any other symbol
     109      foreach (var symb in selectedDefunBranch.Grammar.Symbols)
     110        for (int i = 0; i < selectedDefunBranch.Grammar.GetMaxSubtreeCount(symb); i++) {
     111          selectedDefunBranch.Grammar.SetAllowedChild(symb, newArgNode.Symbol, i);
     112        }
    103113      foreach (var subtree in symbolicExpressionTree.Root.SubTrees) {
    104         if (subtree.DynamicSymbols.Contains(selectedDefunBranch.Name)) {
    105           subtree.SetDynamicSymbolArgumentCount(selectedDefunBranch.Name, selectedDefunBranch.NumberOfArguments);
     114        // when the changed function is known in the branch then update the number of arguments
     115        var matchingSymbol = subtree.Grammar.Symbols.Where(s => s.Name == selectedDefunBranch.FunctionName).SingleOrDefault();
     116        if (matchingSymbol != null) {
     117          subtree.Grammar.SetMinSubtreeCount(matchingSymbol, selectedDefunBranch.NumberOfArguments);
     118          subtree.Grammar.SetMaxSubtreeCount(matchingSymbol, selectedDefunBranch.NumberOfArguments);
    106119        }
    107120      }
    108       Debug.Assert(grammar.IsValidExpression(symbolicExpressionTree));
    109121      return true;
    110122    }
     
    117129        if (argNode != null) {
    118130          // replace argument nodes by a clone of the original subtree that provided the result for the argument node
    119           branch.SubTrees[subtreeIndex] = (SymbolicExpressionTreeNode)argumentTrees[argNode.ArgumentIndex].Clone();
     131          branch.SubTrees[subtreeIndex] = (SymbolicExpressionTreeNode)argumentTrees[argNode.Symbol.ArgumentIndex].Clone();
    120132        } else {
    121133          // recursively replace arguments in all branches
     
    125137    }
    126138
    127     private static IEnumerable<SymbolicExpressionTreeNode> IterateNodesPrefix(SymbolicExpressionTreeNode tree) {
    128       yield return tree;
    129       foreach (var subTree in tree.SubTrees) {
    130         foreach (var node in IterateNodesPrefix(subTree)) {
    131           yield return node;
    132         }
    133       }
    134     }
    135 
    136     private static T SelectRandomBranch<T>(IRandom random, IEnumerable<T> branches) {
    137       var list = branches.ToList();
    138       return list[random.Next(list.Count)];
    139     }
    140 
    141139    private static SymbolicExpressionTreeNode MakeArgumentNode(int argIndex) {
    142       var node = (ArgumentTreeNode)(new Argument()).CreateTreeNode();
    143       node.ArgumentIndex = argIndex;
     140      var node = (ArgumentTreeNode)(new Argument(argIndex)).CreateTreeNode();
    144141      return node;
    145142    }
Note: See TracChangeset for help on using the changeset viewer.