Free cookie consent management tool by TermsFeed Policy Generator

Ignore:
Timestamp:
04/22/08 20:28:26 (16 years ago)
Author:
gkronber
Message:

fixed #119

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/sources/HeuristicLab.StructureIdentification/Manipulation/ChangeNodeTypeManipulation.cs

    r162 r163  
    4848      AddVariableInfo(new VariableInfo("MaxTreeHeight", "The maximal allowed height of the tree", typeof(IntData), VariableKind.In));
    4949      AddVariableInfo(new VariableInfo("MaxTreeSize", "The maximal allowed size (number of nodes) of the tree", typeof(IntData), VariableKind.In));
    50       AddVariableInfo(new VariableInfo("BalancedTreesRate", "Determines how many trees should be balanced", typeof(DoubleData), VariableKind.In));
    5150      AddVariableInfo(new VariableInfo("FunctionTree", "The tree to mutate", typeof(IFunctionTree), VariableKind.In | VariableKind.Out));
    5251      AddVariableInfo(new VariableInfo("TreeSize", "The size (number of nodes) of the tree", typeof(IntData), VariableKind.In | VariableKind.Out));
     
    5958      MersenneTwister random = GetVariableValue<MersenneTwister>("Random", scope, true);
    6059      GPOperatorLibrary library = GetVariableValue<GPOperatorLibrary>("OperatorLibrary", scope, true);
    61       double balancedTreesRate = GetVariableValue<DoubleData>("BalancedTreesRate", scope, true).Data;
    6260      IntData treeSize = GetVariableValue<IntData>("TreeSize", scope, false);
    6361      IntData treeHeight = GetVariableValue<IntData>("TreeHeight", scope, false);
    6462      int maxTreeSize = GetVariableValue<IntData>("MaxTreeSize", scope, true).Data;
    6563      int maxTreeHeight = GetVariableValue<IntData>("MaxTreeHeight", scope, true).Data;
    66 
    6764      TreeGardener gardener = new TreeGardener(random, library);
    6865      IFunctionTree parent = gardener.GetRandomParentNode(root);
    69 
    7066      IFunctionTree selectedChild;
    7167      int selectedChildIndex;
     
    8076      if (selectedChild.SubTrees.Count == 0) {
    8177        IFunctionTree newTerminal = ChangeTerminalType(parent, selectedChild, selectedChildIndex, gardener, random);
    82 
    8378        if (parent == null) {
    8479          // no parent means the new child is the initial operator
     
    9186        }
    9287        if(!gardener.IsValidTree(root)) throw new InvalidProgramException();
    93 
    9488        // size and height stays the same when changing a terminal so no need to update the variables
    9589        // schedule an operation to initialize the new terminal
     
    9791      } else {
    9892        List<IFunctionTree> uninitializedBranches;
    99         IFunctionTree newFunction = ChangeFunctionType(parent, selectedChild, selectedChildIndex, gardener, random, balancedTreesRate, out uninitializedBranches);
    100 
     93        IFunctionTree newFunction = ChangeFunctionType(parent, selectedChild, selectedChildIndex, gardener, random, out uninitializedBranches);
    10194        if (parent == null) {
    10295          // no parent means the new function is the initial operator
     
    110103          parent.InsertSubTree(selectedChildIndex, newFunction);
    111104        }
    112 
    113105        // recalculate size and height
    114106        treeSize.Data = gardener.GetTreeSize(root);
    115107        treeHeight.Data = gardener.GetTreeHeight(root);
    116 
    117108        // check if whole tree is ok
    118109        // check if the size of the new tree is still in the allowed bounds
     
    122113          throw new InvalidProgramException();
    123114        }
    124 
    125115        // return a composite operation that initializes all created sub-trees
    126116        return gardener.CreateInitializationOperation(uninitializedBranches, scope);
     
    139129        }
    140130      }
    141 
    142131      // selecting from the terminals should always work since the current child was also a terminal
    143132      // so in the worst case we will just create a new terminal of the same type again.
     
    146135
    147136    private IFunctionTree ChangeFunctionType(IFunctionTree parent, IFunctionTree child, int childIndex, TreeGardener gardener, MersenneTwister random,
    148       double balancedTreesRate, out List<IFunctionTree> uninitializedBranches) {
     137      out List<IFunctionTree> uninitializedBranches) {
    149138      // since there are subtrees, we have to check which
    150       // and how many of the existing subtrees we can reuse
    151 
    152       // let's choose the function we want to use instead of the old child. For this we have to determine the
     139      // and how many of the existing subtrees we can reuse.
     140      // first let's choose the function we want to use instead of the old child. For this we have to determine the
    153141      // pool of allowed functions based on constraints of the parent if there is one.
    154142      IList<IFunction> allowedFunctions = gardener.GetAllowedSubFunctions(parent!=null?parent.Function:null, childIndex);
    155 
    156143      // try to make a tree with the same arity as the old child.
    157144      int actualArity = child.SubTrees.Count;
     
    166153        return minArity <= actualArity;
    167154      }).ToList();
    168 
    169155      // create a new tree-node for a randomly selected function
    170156      IFunctionTree newTree = new FunctionTree(allowedFunctions[random.Next(allowedFunctions.Count)]);
    171 
    172157      gardener.GetMinMaxArity(newTree.Function, out minArity, out maxArity);
    173158      // if the old child had too many sub-trees then the new child should keep as many sub-trees as possible
    174159      if (actualArity > maxArity)
    175160        actualArity = maxArity;
    176 
    177161      // get the allowed size and height for new sub-trees
    178162      // use the size of the smallest subtree as the maximal allowed size for new subtrees to
     
    180164      int maxSubTreeSize = child.SubTrees.Select(subTree => gardener.GetTreeSize(subTree)).Min();
    181165      int maxSubTreeHeight = gardener.GetTreeHeight(child) - 1;
    182 
    183166      // create a list that holds old sub-trees that we can reuse in the new tree
    184167      List<IFunctionTree> availableSubTrees = new List<IFunctionTree>(child.SubTrees);
    185168      List<IFunctionTree> freshSubTrees = new List<IFunctionTree>() { newTree };
    186 
    187169      // randomly select the sub-trees that we keep
    188170      for (int i = 0; i < actualArity; i++) {
     
    193175        ICollection<IFunction> allowedSubFunctions = gardener.GetAllowedSubFunctions(newTree.Function, i);
    194176        var matchingSubTrees = availableSubTrees.Where(subTree => allowedSubFunctions.Contains(subTree.Function));
    195 
    196177        if (matchingSubTrees.Count() > 0) {
    197178          IFunctionTree selectedSubTree = matchingSubTrees.ElementAt(random.Next(matchingSubTrees.Count()));
     
    201182        } else {
    202183          // no existing matching tree found => create a new one
    203           IFunctionTree freshTree;
    204           if(random.NextDouble() <= balancedTreesRate) {
    205             freshTree = gardener.CreateRandomTree(allowedSubFunctions, maxSubTreeSize, maxSubTreeHeight, true);
    206           } else {
    207             freshTree = gardener.CreateRandomTree(allowedSubFunctions, maxSubTreeSize, maxSubTreeHeight, false);
    208           }
     184          IFunctionTree freshTree = gardener.CreateRandomTree(allowedSubFunctions, maxSubTreeSize, maxSubTreeHeight);
    209185          freshSubTrees.AddRange(gardener.GetAllSubTrees(freshTree));
    210 
    211186          newTree.InsertSubTree(i, freshTree);
    212187        }
Note: See TracChangeset for help on using the changeset viewer.