Free cookie consent management tool by TermsFeed Policy Generator

Changeset 143


Ignore:
Timestamp:
04/21/08 15:31:41 (16 years ago)
Author:
gkronber
Message:

worked on #112 in the refactoring branch

Location:
branches/FunctionsAndStructIdRefactoring
Files:
12 edited

Legend:

Unmodified
Added
Removed
  • branches/FunctionsAndStructIdRefactoring/HeuristicLab.Functions/IFunctionTree.cs

    r142 r143  
    3737    void InsertSubTree(int index, IFunctionTree tree);
    3838    void RemoveSubTree(int index);
     39
    3940    double Evaluate(Dataset dataset, int sampleIndex);
    4041  }
  • branches/FunctionsAndStructIdRefactoring/HeuristicLab.StructureIdentification/Evaluation/MeanSquaredErrorEvaluator.cs

    r142 r143  
    4747      double targetMean = dataset.GetMean(targetVariable);
    4848      for(int sample = 0; sample < dataset.Rows; sample++) {
     49
    4950        double estimated = functionTree.Evaluate(dataset, sample);
    5051        double original = dataset.GetValue(sample, targetVariable);
  • branches/FunctionsAndStructIdRefactoring/HeuristicLab.StructureIdentification/Manipulation/ChangeNodeTypeManipulation.cs

    r142 r143  
    8484        // size and height stays the same when changing a terminal so no need to update the variables
    8585        // schedule an operation to initialize the new terminal
    86         return gardener.CreateInitializationOperation(gardener.GetAllOperators(newTerminal), scope);
     86        return gardener.CreateInitializationOperation(gardener.GetAllSubTrees(newTerminal), scope);
    8787      } else {
    8888        List<IFunctionTree> uninitializedBranches;
     
    147147      IList<IOperator> allowedSubOperators;
    148148      SubOperatorsConstraintAnalyser analyser = new SubOperatorsConstraintAnalyser();
    149       analyser.AllPossibleOperators = gardener.AllOperators;
     149      analyser.AllPossibleOperators = gardener.AllFunctions;
    150150      if (parent == null) {
    151         allowedSubOperators = gardener.AllOperators;
     151        allowedSubOperators = gardener.AllFunctions;
    152152      } else {
    153153        allowedSubOperators = analyser.GetAllowedOperators(parent, childIndex);
     
    203203            freshTree = gardener.CreateRandomTree(allowedOperators, maxSubTreeSize, maxSubTreeHeight, false);
    204204          }
    205           freshSubTrees.AddRange(gardener.GetAllOperators(freshTree));
     205          freshSubTrees.AddRange(gardener.GetAllSubTrees(freshTree));
    206206
    207207          newTree.InsertSubTree(i, freshTree);
  • branches/FunctionsAndStructIdRefactoring/HeuristicLab.StructureIdentification/Manipulation/CutOutNodeManipulation.cs

    r23 r143  
    2727using HeuristicLab.Random;
    2828using System;
     29using HeuristicLab.Functions;
    2930
    3031namespace HeuristicLab.StructureIdentification {
     
    3233    public override string Description {
    3334      get {
    34         return @"Takes a tree, selects a random node of the tree and then tries to replace a random child
     35        return @"Takes a tree, selects a random node of the tree and then tries to replace a random sub-tree
    3536of that node with one of the childs of the selected child.
    3637
     
    5354      AddVariableInfo(new VariableInfo("MaxTreeSize", "The maximal allowed size (number of nodes) of the tree", typeof(IntData), VariableKind.In));
    5455      AddVariableInfo(new VariableInfo("BalancedTreesRate", "Determines how many trees should be balanced", typeof(DoubleData), VariableKind.In));
    55       AddVariableInfo(new VariableInfo("OperatorTree", "The tree to mutate", typeof(IOperator), VariableKind.In));
    56       AddVariableInfo(new VariableInfo("TreeSize", "The size (number of nodes) of the tree", typeof(IntData), VariableKind.In));
    57       AddVariableInfo(new VariableInfo("TreeHeight", "The height of the tree", typeof(IntData), VariableKind.In));
     56      AddVariableInfo(new VariableInfo("FunctionTree", "The tree to mutate", typeof(IFunctionTree), VariableKind.In | VariableKind.Out));
     57      AddVariableInfo(new VariableInfo("TreeSize", "The size (number of nodes) of the tree", typeof(IntData), VariableKind.In | VariableKind.Out));
     58      AddVariableInfo(new VariableInfo("TreeHeight", "The height of the tree", typeof(IntData), VariableKind.In | VariableKind.Out));
    5859    }
    5960
    6061
    6162    public override IOperation Apply(IScope scope) {
    62       IOperator rootOperator = GetVariableValue<IOperator>("OperatorTree", scope, true);
     63      IFunctionTree root = GetVariableValue<IFunctionTree>("FunctionTree", scope, true);
    6364      MersenneTwister random = GetVariableValue<MersenneTwister>("Random", scope, true);
    6465      GPOperatorLibrary library = GetVariableValue<GPOperatorLibrary>("OperatorLibrary", scope, true);
     
    6869
    6970      TreeGardener gardener = new TreeGardener(random, library);
    70       IOperator parent = gardener.GetRandomParentNode(rootOperator);
     71      IFunctionTree parent = gardener.GetRandomParentNode(root);
    7172      // parent == null means we should cut out the root node
    72       // => return a random suboperator of the root
     73      // => return a random sub-tree of the root
    7374      if (parent == null) {
    74         // when there are suboperators then replace the old operator with a random suboperator
    75         if (rootOperator.SubOperators.Count > 0) {
    76           rootOperator = rootOperator.SubOperators[random.Next(rootOperator.SubOperators.Count)];
     75        // when there are sub-trees then replace the old tree with a random sub-tree
     76        if (root.SubTrees.Count > 0) {
     77          root = root.SubTrees[random.Next(root.SubTrees.Count)];
    7778
    78           GetVariableValue<IntData>("TreeSize", scope, true).Data = gardener.GetTreeSize(rootOperator);
    79           GetVariableValue<IntData>("TreeHeight", scope, true).Data = gardener.GetTreeHeight(rootOperator);
     79          GetVariableValue<IntData>("TreeSize", scope, true).Data = gardener.GetTreeSize(root);
     80          GetVariableValue<IntData>("TreeHeight", scope, true).Data = gardener.GetTreeHeight(root);
    8081
    81           // this is not really necessary (we can leave it in until the operator is stable)
    82           if (!gardener.IsValidTree(rootOperator)) {
     82          // this is not really necessary (we can leave it in until the tree is stable)
     83          if (!gardener.IsValidTree(root)) {
    8384            throw new InvalidProgramException();
    8485          }
    8586
    8687          // update the variable
    87           scope.GetVariable("OperatorTree").Value = rootOperator;
    88           if (!gardener.IsValidTree(rootOperator)) {
     88          scope.GetVariable(scope.TranslateName("FunctionTree")).Value = root;
     89          if (!gardener.IsValidTree(root)) {
    8990            throw new InvalidProgramException();
    9091          }
    91 
    92 
    9392          // the tree is already initialized so we don't have to schedule initialization operations
    9493          return null;
    9594        } else {
    9695          // create a new random tree
    97           IOperator newOperator;
     96          IFunctionTree newTree;
    9897          if(random.NextDouble() <= balancedTreesRate) {
    99             newOperator = gardener.CreateRandomTree(gardener.AllOperators, maxTreeSize, maxTreeHeight, true);
     98            newTree = gardener.CreateRandomTree(gardener.AllFunctions, maxTreeSize, maxTreeHeight, true);
    10099          } else {
    101             newOperator = gardener.CreateRandomTree(gardener.AllOperators, maxTreeSize, maxTreeHeight, false);
     100            newTree = gardener.CreateRandomTree(gardener.AllFunctions, maxTreeSize, maxTreeHeight, false);
    102101          }
    103102
    104           GetVariableValue<IntData>("TreeSize", scope, true).Data = gardener.GetTreeSize(newOperator);
    105           GetVariableValue<IntData>("TreeHeight", scope, true).Data = gardener.GetTreeHeight(newOperator);
     103          GetVariableValue<IntData>("TreeSize", scope, true).Data = gardener.GetTreeSize(newTree);
     104          GetVariableValue<IntData>("TreeHeight", scope, true).Data = gardener.GetTreeHeight(newTree);
    106105
    107           if (!gardener.IsValidTree(newOperator)) {
     106          // update the variable
     107          scope.GetVariable(scope.TranslateName("FunctionTree")).Value = newTree;
     108
     109          if (!gardener.IsValidTree(newTree)) {
    108110            throw new InvalidProgramException();
    109111          }
    110112
    111           // update the variable
    112           scope.GetVariable("OperatorTree").Value = newOperator;
    113 
    114           if (!gardener.IsValidTree(newOperator)) {
    115             throw new InvalidProgramException();
    116           }
    117 
    118           // schedule an operation to initialize the whole operator graph
    119           return gardener.CreateInitializationOperation(gardener.GetAllOperators(newOperator), scope);
     113          // schedule an operation to initialize the whole tree
     114          return gardener.CreateInitializationOperation(gardener.GetAllSubTrees(newTree), scope);
    120115        }
    121116      }
    122117
    123       int childIndex = random.Next(parent.SubOperators.Count);
    124       IOperator child = parent.SubOperators[childIndex];
     118      int childIndex = random.Next(parent.SubTrees.Count);
     119      IFunctionTree child = parent.SubTrees[childIndex];
    125120
    126       // match the suboperators of the child with the allowed suboperators of the parent
    127       IOperator[] possibleChilds = gardener.GetAllowedSubOperators(parent, childIndex).SelectMany(allowedOp => child.SubOperators
    128         .Where(subOp => ((StringData)subOp.GetVariable(GPOperatorLibrary.TYPE_ID).Value).Data ==
    129           ((StringData)allowedOp.GetVariable(GPOperatorLibrary.TYPE_ID).Value).Data)).ToArray();
    130 
     121      // match the sub-trees of the child with the allowed sub-trees of the parent
     122      IFunction[] possibleChilds = gardener.GetAllowedSubFunctions(parent.Function, childIndex).SelectMany(allowedFun => child.SubTrees
     123        .Where(subTree => allowedFun == subTree.Function)).Select(t=>t.Function).ToArray(); // Actually we should probably use OperatorEqualityComparer here (gkronber 21.04.08)
    131124
    132125      if (possibleChilds.Length > 0) {
    133126        // replace child with a random child of the child
    134         // make a clone to simplify removing obsolete operators from the operator-graph
    135         IOperator selectedChild = (IOperator)possibleChilds[random.Next(possibleChilds.Length)].Clone();       
    136         parent.RemoveSubOperator(childIndex);
    137         parent.AddSubOperator(selectedChild, childIndex);
     127        // make a clone to simplify removing obsolete branches from the function-tree
     128        IFunction selectedChild = possibleChilds[random.Next(possibleChilds.Length)];       
     129        parent.RemoveSubTree(childIndex);
     130        parent.InsertSubTree(childIndex, new FunctionTree(selectedChild));
    138131
    139         if (!gardener.IsValidTree(rootOperator)) {
     132        if (!gardener.IsValidTree(root)) {
    140133          throw new InvalidProgramException();
    141134        }
    142135
    143136        // update the size and height of our tree
    144         GetVariableValue<IntData>("TreeSize", scope, true).Data = gardener.GetTreeSize(rootOperator);
    145         GetVariableValue<IntData>("TreeHeight", scope, true).Data = gardener.GetTreeHeight(rootOperator);
     137        GetVariableValue<IntData>("TreeSize", scope, true).Data = gardener.GetTreeSize(root);
     138        GetVariableValue<IntData>("TreeHeight", scope, true).Data = gardener.GetTreeHeight(root);
    146139        // don't need to schedule initialization operations
    147140        return null;
    148141      } else {
    149142        // determine the level of the parent
    150         int parentLevel = gardener.GetNodeLevel(rootOperator, parent);
     143        int parentLevel = gardener.GetBranchLevel(root, parent);
    151144
    152145        // first remove the old child (first step essential!)
    153         parent.RemoveSubOperator(childIndex);
     146        parent.RemoveSubTree(childIndex);
    154147        // then determine the number of nodes left over after the child has been removed!
    155         int remainingNodes = gardener.GetTreeSize(rootOperator);
     148        int remainingNodes = gardener.GetTreeSize(root);
    156149
    157         IList<IOperator> allowedOperators = gardener.GetAllowedSubOperators(parent, childIndex);
    158         IOperator newOperatorTree = gardener.CreateRandomTree(allowedOperators, maxTreeSize - remainingNodes, maxTreeHeight - parentLevel, true);
     150        IList<IFunction> allowedFunctions = gardener.GetAllowedSubFunctions(parent.Function, childIndex);
     151        IFunctionTree newFunctionTree = gardener.CreateRandomTree(allowedFunctions, maxTreeSize - remainingNodes, maxTreeHeight - parentLevel, true);
    159152
    160         parent.AddSubOperator(newOperatorTree, childIndex);
     153        parent.InsertSubTree(childIndex, newFunctionTree);
    161154
    162         GetVariableValue<IntData>("TreeSize", scope, true).Data = gardener.GetTreeSize(rootOperator);
    163         GetVariableValue<IntData>("TreeHeight", scope, true).Data = gardener.GetTreeHeight(rootOperator);
     155        GetVariableValue<IntData>("TreeSize", scope, true).Data = gardener.GetTreeSize(root);
     156        GetVariableValue<IntData>("TreeHeight", scope, true).Data = gardener.GetTreeHeight(root);
    164157
    165         if (!gardener.IsValidTree(rootOperator)) {
     158        if (!gardener.IsValidTree(root)) {
    166159          throw new InvalidProgramException();
    167160        }
    168161
    169         // schedule an initialization operation for the new operator
    170         return gardener.CreateInitializationOperation(gardener.GetAllOperators(newOperatorTree), scope);
     162        // schedule an initialization operation for the new function-tree
     163        return gardener.CreateInitializationOperation(gardener.GetAllSubTrees(newFunctionTree), scope);
    171164      }
    172165    }
  • branches/FunctionsAndStructIdRefactoring/HeuristicLab.StructureIdentification/Manipulation/DeleteSubTreeManipulation.cs

    r23 r143  
    2626using HeuristicLab.Operators;
    2727using HeuristicLab.Random;
     28using HeuristicLab.Functions;
    2829
    2930namespace HeuristicLab.StructureIdentification {
     
    4243      AddVariableInfo(new VariableInfo("MaxTreeHeight", "The maximal allowed height of the tree", typeof(IntData), VariableKind.In));
    4344      AddVariableInfo(new VariableInfo("MaxTreeSize", "The maximal allowed size (number of nodes) of the tree", typeof(IntData), VariableKind.In));
    44       AddVariableInfo(new VariableInfo("OperatorTree", "The tree to mutate", typeof(IOperator), VariableKind.In | VariableKind.Out));
     45      AddVariableInfo(new VariableInfo("FunctionTree", "The tree to mutate", typeof(IFunctionTree), VariableKind.In | VariableKind.Out));
    4546      AddVariableInfo(new VariableInfo("TreeSize", "The size (number of nodes) of the tree", typeof(IntData), VariableKind.In | VariableKind.Out));
    4647      AddVariableInfo(new VariableInfo("TreeHeight", "The height of the tree", typeof(IntData), VariableKind.In | VariableKind.Out));
     
    4950
    5051    public override IOperation Apply(IScope scope) {
    51       IOperator rootOperator = GetVariableValue<IOperator>("OperatorTree", scope, true);
     52      IFunctionTree root = GetVariableValue<IFunctionTree>("FunctionTree", scope, true);
    5253      MersenneTwister random = GetVariableValue<MersenneTwister>("Random", scope, true);
    5354      GPOperatorLibrary library = GetVariableValue<GPOperatorLibrary>("OperatorLibrary", scope, true);
    54 
    5555      TreeGardener gardener = new TreeGardener(random, library);
    56 
    57       IOperator parent = gardener.GetRandomParentNode(rootOperator);
     56      IFunctionTree parent = gardener.GetRandomParentNode(root);
    5857
    5958      // parent==null means the whole tree should be deleted.
    6059      // => return a new minimal random tree
    6160      if(parent == null) {
    62         IOperator newTree = gardener.CreateRandomTree(1, 1, true);
     61        IFunctionTree newTree = gardener.CreateRandomTree(1, 1, true);
    6362
    6463        // check if the tree is ok
     
    7069        GetVariableValue<IntData>("TreeSize", scope, true).Data = gardener.GetTreeSize(newTree);
    7170        GetVariableValue<IntData>("TreeHeight", scope, true).Data = gardener.GetTreeHeight(newTree);
    72         scope.GetVariable("OperatorTree").Value = newTree;
     71        scope.GetVariable(scope.TranslateName("FunctionTree")).Value = newTree;
    7372
    7473        // schedule an operation to initialize the newly created operator
    75         return gardener.CreateInitializationOperation(gardener.GetAllOperators(newTree), scope);
     74        return gardener.CreateInitializationOperation(gardener.GetAllSubTrees(newTree), scope);
    7675      }
    7776
    78       int childIndex = random.Next(parent.SubOperators.Count);
     77      int childIndex = random.Next(parent.SubTrees.Count);
    7978
    8079      int min;
    8180      int max;
    82       gardener.GetMinMaxArity(parent, out min, out max);
    83       if(parent.SubOperators.Count > min) {
    84         parent.RemoveSubOperator(childIndex);
    85         // actually since the next suboperators are shifted in the place of the removed operator
    86         // it might be possible that these suboperators are not allowed in the place of the old operator
     81      gardener.GetMinMaxArity(parent.Function, out min, out max);
     82      if(parent.SubTrees.Count > min) {
     83        parent.RemoveSubTree(childIndex);
     84        // actually since the next sub-trees are shifted in the place of the removed branch
     85        // it might be possible that these sub-trees are not allowed in the place of the old branch
    8786        // we ignore this problem for now.
    88         // when this starts to become a problem a possible solution is to go through the shifted operators from the place of the shifted
     87        // when this starts to become a problem a possible solution is to go through the shifted branches from the place of the shifted
    8988        // and find the first one that doesn't fit. At this position we insert a new randomly initialized subtree of matching type (gkronber 25.12.07)
    9089
    91         if(!gardener.IsValidTree(rootOperator)) {
     90        if(!gardener.IsValidTree(root)) {
    9291          throw new InvalidOperationException();
    9392        }
    9493
    95         GetVariableValue<IntData>("TreeSize", scope, true).Data = gardener.GetTreeSize(rootOperator);
    96         GetVariableValue<IntData>("TreeHeight", scope, true).Data = gardener.GetTreeHeight(rootOperator);
    97         // root hasn't changed so don't need to update 'OperatorTree' variable
    98 
     94        GetVariableValue<IntData>("TreeSize", scope, true).Data = gardener.GetTreeSize(root);
     95        GetVariableValue<IntData>("TreeHeight", scope, true).Data = gardener.GetTreeHeight(root);
     96        // root hasn't changed so don't need to update 'FunctionTree' variable
    9997        return null;
    10098      } else {
    10199        // replace with a minimal random seedling
    102         parent.RemoveSubOperator(childIndex);
     100        parent.RemoveSubTree(childIndex);
    103101
    104         IList<IOperator> allowedOperators = gardener.GetAllowedSubOperators(parent, childIndex);
    105         IOperator newOperatorTree = gardener.CreateRandomTree(allowedOperators, 1, 1, true);
     102        IList<IFunction> allowedFunctions = gardener.GetAllowedSubFunctions(parent.Function, childIndex);
     103        IFunctionTree newFunctionTree = gardener.CreateRandomTree(allowedFunctions, 1, 1, true);
    106104
    107         parent.AddSubOperator(newOperatorTree, childIndex);
     105        parent.InsertSubTree(childIndex, newFunctionTree);
    108106
    109         if(!gardener.IsValidTree(rootOperator)) {
     107        if(!gardener.IsValidTree(root)) {
    110108          throw new InvalidProgramException();
    111109        }
    112110
    113         GetVariableValue<IntData>("TreeSize", scope, true).Data = gardener.GetTreeSize(rootOperator);
    114         GetVariableValue<IntData>("TreeHeight", scope, true).Data = gardener.GetTreeHeight(rootOperator);
    115         // again the root hasn't changed so we don't need to update the 'OperatorTree' variable
    116 
    117         return gardener.CreateInitializationOperation(gardener.GetAllOperators(newOperatorTree), scope);
     111        GetVariableValue<IntData>("TreeSize", scope, true).Data = gardener.GetTreeSize(root);
     112        GetVariableValue<IntData>("TreeHeight", scope, true).Data = gardener.GetTreeHeight(root);
     113        // again the root hasn't changed so we don't need to update the 'FunctionTree' variable
     114        return gardener.CreateInitializationOperation(gardener.GetAllSubTrees(newFunctionTree), scope);
    118115      }
    119116    }
  • branches/FunctionsAndStructIdRefactoring/HeuristicLab.StructureIdentification/Manipulation/FullTreeShaker.cs

    r88 r143  
    2929using HeuristicLab.Data;
    3030using HeuristicLab.Selection;
     31using HeuristicLab.Functions;
    3132
    3233namespace HeuristicLab.StructureIdentification {
     
    3839    public FullTreeShaker()
    3940      : base() {
     41      AddVariableInfo(new VariableInfo("Random", "A random generator (uniform)", typeof(MersenneTwister), VariableKind.In));
    4042      AddVariableInfo(new VariableInfo("OperatorLibrary", "Operator library that defines operator mutations", typeof(GPOperatorLibrary), VariableKind.In));
    41       AddVariableInfo(new VariableInfo("OperatorTree", "The operator tree that should be mutated", typeof(IOperator), VariableKind.In));
    42       AddVariableInfo(new VariableInfo("Random", "A random generator (uniform)", typeof(MersenneTwister), VariableKind.In));
    43       AddVariableInfo(new VariableInfo("ShakingFactor", "Variable that determines the force of the shakeing operation", typeof(DoubleData), VariableKind.In));
     43      AddVariableInfo(new VariableInfo("ShakingFactor", "Variable that determines the force of the shaking operation", typeof(DoubleData), VariableKind.In));
     44      AddVariableInfo(new VariableInfo("FunctionTree", "The function tree that should be mutated", typeof(IFunctionTree), VariableKind.In | VariableKind.Out));
    4445    }
    4546
    4647    public override IOperation Apply(IScope scope) {
    4748      GPOperatorLibrary library = GetVariableValue<GPOperatorLibrary>("OperatorLibrary", scope, true);
    48       IOperator op = GetVariableValue<IOperator>("OperatorTree", scope, false);
     49      IFunctionTree tree = GetVariableValue<IFunctionTree>("FunctionTree", scope, false);
    4950      MersenneTwister mt = GetVariableValue<MersenneTwister>("Random", scope, true);
    5051
     
    5657
    5758      TreeGardener gardener = new TreeGardener(mt, library);
    58       var parametricNodes = gardener.GetAllOperators(op).Where(o => o.GetVariable(GPOperatorLibrary.MANIPULATION) != null);
    59       foreach(IOperator subOperator in parametricNodes) {
    60         IOperator mutation =(IOperator)subOperator.GetVariable(GPOperatorLibrary.MANIPULATION).Value;
     59      var parametricBranches = gardener.GetAllSubTrees(tree).Where(branch => branch.Function.GetVariable(GPOperatorLibrary.MANIPULATION) != null);
     60      foreach(IFunctionTree subTree in parametricBranches) {
     61        IOperator mutation =(IOperator)subTree.Function.GetVariable(GPOperatorLibrary.MANIPULATION).Value;
    6162
    6263        // store all local variables into a temporary scope
    6364        Scope mutationScope = new Scope();
    64         foreach(IVariableInfo info in subOperator.VariableInfos) {
    65           if(info.Local) {
    66             mutationScope.AddVariable(subOperator.GetVariable(info.FormalName));
    67           }
     65        foreach(IVariable variable in subTree.LocalVariables) {
     66          mutationScope.AddVariable(variable);
    6867        }
    6968
  • branches/FunctionsAndStructIdRefactoring/HeuristicLab.StructureIdentification/Manipulation/OnePointShaker.cs

    r88 r143  
    2929using HeuristicLab.Data;
    3030using HeuristicLab.Selection;
     31using HeuristicLab.Functions;
    3132
    3233namespace HeuristicLab.StructureIdentification {
     
    3940      : base() {
    4041      AddVariableInfo(new VariableInfo("OperatorLibrary", "Operator library that defines mutation operations for operators", typeof(GPOperatorLibrary), VariableKind.In));
    41       AddVariableInfo(new VariableInfo("OperatorTree", "The operator tree that should be mutated", typeof(IOperator), VariableKind.In));
    4242      AddVariableInfo(new VariableInfo("Random", "A random generator (uniform)", typeof(MersenneTwister), VariableKind.In));
    4343      AddVariableInfo(new VariableInfo("ShakingFactor", "Factor that determines the force of the shaking operation", typeof(DoubleData), VariableKind.In));
     44      AddVariableInfo(new VariableInfo("FunctionTree", "The function tree that should be mutated", typeof(IFunctionTree), VariableKind.In | VariableKind.Out));
    4445    }
    4546
    4647    public override IOperation Apply(IScope scope) {
    4748      GPOperatorLibrary library = GetVariableValue<GPOperatorLibrary>("OperatorLibrary", scope, true);
    48       IOperator op = GetVariableValue<IOperator>("OperatorTree", scope, false);
     49      IFunctionTree tree = GetVariableValue<IFunctionTree>("FunctionTree", scope, false);
    4950      MersenneTwister mt = GetVariableValue<MersenneTwister>("Random", scope, true);
    5051      TreeGardener gardener = new TreeGardener(mt, library);
    5152
    5253      // get all nodes for which a manipulation is defined
    53       var parametricNodes = gardener.GetAllOperators(op).Where(o => o.GetVariable(GPOperatorLibrary.MANIPULATION) != null);
    54       IOperator selectedOp = parametricNodes.ElementAt(mt.Next(parametricNodes.Count()));
    55 
    56       IOperator mutation = (IOperator)selectedOp.GetVariable(GPOperatorLibrary.MANIPULATION).Value;
    57 
     54      var parametricBranches = gardener.GetAllSubTrees(tree).Where(branch => branch.Function.GetVariable(GPOperatorLibrary.MANIPULATION) != null);
     55      IFunctionTree selectedBranch = parametricBranches.ElementAt(mt.Next(parametricBranches.Count()));
     56      IOperator mutation = (IOperator)selectedBranch.Function.GetVariable(GPOperatorLibrary.MANIPULATION).Value;
    5857      CompositeOperation next = new CompositeOperation();
    5958
    6059      // store all local variables into a temporary scope
    6160      Scope tempScope = new Scope("Temp. manipulation scope");
    62       // add aliases
    63       foreach(IVariableInfo variableInfo in VariableInfos)
    64         tempScope.AddAlias(variableInfo.FormalName, variableInfo.ActualName);
    65 
    66       foreach(IVariableInfo info in selectedOp.VariableInfos) {
    67         if(info.Local) {
    68           tempScope.AddVariable(selectedOp.GetVariable(info.FormalName));
    69         }
     61      foreach(IVariable variable in selectedBranch.LocalVariables) {
     62        tempScope.AddVariable(variable);
    7063      }
    7164
  • branches/FunctionsAndStructIdRefactoring/HeuristicLab.StructureIdentification/Manipulation/SubstituteSubTreeManipulation.cs

    r23 r143  
    6969        IOperator newOperatorTree;
    7070        if(random.NextDouble() <= balancedTreesRate) {
    71           newOperatorTree = gardener.CreateRandomTree(gardener.AllOperators, maxTreeSize, maxTreeHeight, true);
     71          newOperatorTree = gardener.CreateRandomTree(gardener.AllFunctions, maxTreeSize, maxTreeHeight, true);
    7272        } else {
    73           newOperatorTree = gardener.CreateRandomTree(gardener.AllOperators, maxTreeSize, maxTreeHeight, false);
     73          newOperatorTree = gardener.CreateRandomTree(gardener.AllFunctions, maxTreeSize, maxTreeHeight, false);
    7474        }
    7575
     
    8484       
    8585        // return a CompositeOperation that randomly initializes the new operator
    86         return gardener.CreateInitializationOperation(gardener.GetAllOperators(newOperatorTree), scope);
     86        return gardener.CreateInitializationOperation(gardener.GetAllSubTrees(newOperatorTree), scope);
    8787      } else {
    8888        // determine a random child of the parent to be replaced
     
    9090
    9191        // get the list of allowed suboperators as the new child
    92         IList<IOperator> allowedOperators = gardener.GetAllowedSubOperators(parent, childIndex);
     92        IList<IOperator> allowedOperators = gardener.GetAllowedSubFunctions(parent, childIndex);
    9393
    9494        if(allowedOperators.Count == 0) {
     
    100100        // calculate the maximum size and height of the new sub-tree based on the location where
    101101        // it will be inserted
    102         int parentLevel = gardener.GetNodeLevel(rootOperator, parent);
     102        int parentLevel = gardener.GetBranchLevel(rootOperator, parent);
    103103
    104104        int maxSubTreeHeight = maxTreeHeight - parentLevel;
     
    127127
    128128        // return a CompositeOperation that randomly initializes all nodes of the new subtree
    129         return gardener.CreateInitializationOperation(gardener.GetAllOperators(newOperatorTree), scope);
     129        return gardener.CreateInitializationOperation(gardener.GetAllSubTrees(newOperatorTree), scope);
    130130      }
    131131    }
  • branches/FunctionsAndStructIdRefactoring/HeuristicLab.StructureIdentification/RandomTreeCreator.cs

    r142 r143  
    7878      }
    7979
    80       return gardener.CreateInitializationOperation(gardener.GetAllOperators(root), scope);
     80      return gardener.CreateInitializationOperation(gardener.GetAllSubTrees(root), scope);
    8181    }
    8282  }
  • branches/FunctionsAndStructIdRefactoring/HeuristicLab.StructureIdentification/Recombination/SinglePointCrossOver.cs

    r142 r143  
    8181    private IOperation Cross(TreeGardener gardener, int maxTreeSize, int maxTreeHeight,
    8282      IScope scope, MersenneTwister random, IScope parent1, IScope parent2, IScope child) {
    83       List<IOperator> newOperators;
    84       IOperator newTree = Cross(gardener, parent1, parent2,
    85         random, maxTreeSize, maxTreeHeight, out newOperators);
     83      List<IFunctionTree> newBranches;
     84      IFunctionTree newTree = Cross(gardener, parent1, parent2,
     85        random, maxTreeSize, maxTreeHeight, out newBranches);
    8686
    8787      if(!gardener.IsValidTree(newTree)) {
     
    9191      int newTreeSize = gardener.GetTreeSize(newTree);
    9292      int newTreeHeight = gardener.GetTreeHeight(newTree);
    93       child.AddVariable(new Variable("FunctionTree", newTree));
    94       child.AddVariable(new Variable("TreeSize", new IntData(newTreeSize)));
    95       child.AddVariable(new Variable("TreeHeight", new IntData(newTreeHeight)));
     93      child.AddVariable(new HeuristicLab.Core.Variable("FunctionTree", newTree));
     94      child.AddVariable(new HeuristicLab.Core.Variable("TreeSize", new IntData(newTreeSize)));
     95      child.AddVariable(new HeuristicLab.Core.Variable("TreeHeight", new IntData(newTreeHeight)));
    9696
    9797      // check if the size of the new tree is still in the allowed bounds
     
    100100        throw new InvalidProgramException();
    101101      }
    102 
    103 
    104       return gardener.CreateInitializationOperation(newOperators, child);
     102      return gardener.CreateInitializationOperation(newBranches, child);
    105103    }
    106104
     
    133131        int tree0Level = random.Next(tree0Height - 1); // since we checked before that the height of tree0 is > 1 this is OK
    134132        int tree1Level = random.Next(tree1Height);
    135         tree0 = gardener.GetRandomNode(tree0, tree0Level);
    136         tree1 = gardener.GetRandomNode(tree1, tree1Level);
     133        tree0 = gardener.GetRandomBranch(tree0, tree0Level);
     134        tree1 = gardener.GetRandomBranch(tree1, tree1Level);
    137135
    138136        // recalculate the size and height of tree1 (the one that we want to insert) because we need to check constraints later on
     
    141139
    142140        List<int> possibleChildIndices = new List<int>();
    143         TreeGardener.OperatorEqualityComparer comparer = new TreeGardener.OperatorEqualityComparer();
     141        TreeGardener.FunctionEqualityComparer comparer = new TreeGardener.FunctionEqualityComparer();
    144142
    145143        // Now tree0 is supposed to take tree1 as one if its children. If this is not possible,
     
    148146        // find the list of allowed indices (regarding allowed sub-operators, maxTreeSize and maxTreeHeight)
    149147        for(int i = 0; i < tree0.SubTrees.Count; i++) {
    150           int subOperatorSize = gardener.GetTreeSize(tree0.SubTrees[i]);
    151 
    152           // the index is ok when the operator is allowed as sub-operator and we don't violate the maxSize and maxHeight constraints
    153           if(GetAllowedOperators(tree0, i).Contains(tree1, comparer) &&
    154             rootSize - subOperatorSize + tree1Size < maxTreeSize &&
     148          int subTreeSize = gardener.GetTreeSize(tree0.SubTrees[i]);
     149
     150          // the index is ok when the function is allowed as sub-tree and we don't violate the maxSize and maxHeight constraints
     151          if(GetAllowedOperators(tree0.Function, i).Contains(tree1.Function, comparer) &&
     152            rootSize - subTreeSize + tree1Size < maxTreeSize &&
    155153            tree0Level + tree1Height < maxTreeHeight) {
    156154            possibleChildIndices.Add(i);
     
    171169            // go up in tree0
    172170            tree0Level--;
    173             tree0 = gardener.GetRandomNode(root, tree0Level);
     171            tree0 = gardener.GetRandomBranch(root, tree0Level);
    174172          } else if(tree1.SubTrees.Count > 0) {
    175173            // go down in node2:
     
    185183          possibleChildIndices.Clear();
    186184          for(int i = 0; i < tree0.SubTrees.Count; i++) {
    187             int subOperatorSize = gardener.GetTreeSize(tree0.SubTrees[i]);
    188 
    189             // when the operator is allowed as sub-operator and we don't violate the maxSize and maxHeight constraints
     185            int subTreeSize = gardener.GetTreeSize(tree0.SubTrees[i]);
     186
     187            // when the function is allowed as sub-tree and we don't violate the maxSize and maxHeight constraints
    190188            // the index is ok
    191             if(GetAllowedOperators(tree0, i).Contains(tree1, comparer) &&
    192               rootSize - subOperatorSize + tree1Size < maxTreeSize &&
     189            if(GetAllowedOperators(tree0.Function, i).Contains(tree1.Function, comparer) &&
     190              rootSize - subTreeSize + tree1Size < maxTreeSize &&
    193191              tree0Level + tree1Height < maxTreeHeight) {
    194192              possibleChildIndices.Add(i);
     
    205203        int selectedIndex = possibleChildIndices[random.Next(possibleChildIndices.Count)];
    206204        tree0.RemoveSubTree(selectedIndex);
    207         tree0.AddSubTree(tree1, selectedIndex);
     205        tree0.InsertSubTree(selectedIndex, tree1);
    208206
    209207        // no new operators where needed
     
    213211    }
    214212
    215     private ICollection<IOperator> GetAllowedOperators(IOperator tree0, int i) {
    216       ItemList slotList = (ItemList)tree0.GetVariable(GPOperatorLibrary.ALLOWED_SUBOPERATORS).Value;
    217       return ((ItemList)slotList[i]).OfType<IOperator>().ToArray();
     213    private ICollection<IFunction> GetAllowedOperators(IFunction f, int i) {
     214      ItemList slotList = (ItemList)f.GetVariable(GPOperatorLibrary.ALLOWED_SUBOPERATORS).Value;
     215      return ((ItemList)slotList[i]).Cast<IFunction>().ToArray();
    218216    }
    219217
    220218    private IFunctionTree CombineTerminals(TreeGardener gardener, IFunctionTree f, IFunctionTree g, MersenneTwister random, int maxTreeHeight, out List<IFunctionTree> newBranches) {
    221219      newBranches = new List<IFunctionTree>();
    222       ICollection<IOperator> possibleParents = gardener.GetPossibleParents(new List<IOperator>() { f.Function, g.Function });
     220      ICollection<IFunction> possibleParents = gardener.GetPossibleParents(new List<IFunction>() { f.Function, g.Function });
    223221      if(possibleParents.Count == 0) throw new InvalidProgramException();
    224222
    225       IOperator parent = (IOperator)possibleParents.ElementAt(random.Next(possibleParents.Count())).Clone();
     223      IFunctionTree parent = new FunctionTree(possibleParents.ElementAt(random.Next(possibleParents.Count())));
    226224
    227225      int minArity;
    228226      int maxArity;
    229       gardener.GetMinMaxArity(parent, out minArity, out maxArity);
     227      gardener.GetMinMaxArity(parent.Function, out minArity, out maxArity);
    230228
    231229      int nSlots = Math.Max(2, minArity);
    232230
    233       HashSet<IOperator>[] slotSets = new HashSet<IOperator>[nSlots];
     231      HashSet<IFunction>[] slotSets = new HashSet<IFunction>[nSlots];
    234232
    235233      SubOperatorsConstraintAnalyser analyser = new SubOperatorsConstraintAnalyser();
    236234      analyser.AllPossibleOperators = new List<IOperator>() { g.Function, f.Function };
    237235      for(int slot = 0; slot < nSlots; slot++) {
    238         HashSet<IOperator> slotSet = new HashSet<IOperator>(analyser.GetAllowedOperators(parent, slot));
     236        HashSet<IFunction> slotSet = new HashSet<IFunction>(analyser.GetAllowedOperators(parent.Function, slot).Cast<IFunction>());
    239237        slotSets[slot] = slotSet;
    240238      }
     
    242240      int[] slotSequence = Enumerable.Range(0, slotSets.Count()).OrderBy(slot => slotSets[slot].Count()).ToArray();
    243241
    244       IOperator[] selectedOperators = new IOperator[nSlots];
     242      IFunctionTree[] selectedFunctionTrees = new IFunctionTree[nSlots];
    245243      for(int i = 0; i < slotSequence.Length; i++) {
    246244        int slot = slotSequence[i];
    247         HashSet<IOperator> slotSet = slotSets[slot];
     245        HashSet<IFunction> slotSet = slotSets[slot];
    248246        if(slotSet.Count() == 0) {
    249           var allowedOperators = GetAllowedOperators(parent, slot);
    250           selectedOperators[slot] = gardener.CreateRandomTree(allowedOperators, 1, 1, true);
    251           newBranches.AddRange(gardener.GetAllOperators(selectedOperators[slot]));
     247          var allowedFunctions = GetAllowedOperators(parent.Function, slot);
     248          selectedFunctionTrees[slot] = gardener.CreateRandomTree(allowedFunctions, 1, 1, true);
     249          newBranches.AddRange(gardener.GetAllSubTrees(selectedFunctionTrees[slot]));
    252250        } else {
    253           IOperator selectedOperator = slotSet.ElementAt(random.Next(slotSet.Count()));
    254           selectedOperators[slot] = selectedOperator;
     251          IFunction selectedFunction = slotSet.ElementAt(random.Next(slotSet.Count()));
     252          selectedFunctionTrees[slot] = new FunctionTree(selectedFunction);
    255253          for(int j = i + 1; j < slotSequence.Length; j++) {
    256254            int otherSlot = slotSequence[j];
    257             slotSets[otherSlot].Remove(selectedOperator);
    258           }
    259         }
    260       }
    261 
    262       for(int i = 0; i < selectedOperators.Length; i++) {
    263         parent.AddSubOperator(selectedOperators[i], i);
     255            slotSets[otherSlot].Remove(selectedFunction);
     256          }
     257        }
     258      }
     259
     260      for(int i = 0; i < selectedFunctionTrees.Length; i++) {
     261        parent.InsertSubTree(i, selectedFunctionTrees[i]);
    264262      }
    265263
  • branches/FunctionsAndStructIdRefactoring/HeuristicLab.StructureIdentification/TreeGardener.cs

    r142 r143  
    3636  internal class TreeGardener {
    3737    private IRandom random;
    38     private IOperatorLibrary opLibrary;
    39     private List<IOperator> functions;
    40     private List<IOperator> terminals;
    41 
    42     internal IList<IOperator> Terminals {
     38    private IOperatorLibrary funLibrary;
     39    private List<IFunction> functions;
     40    private List<IFunction> terminals;
     41
     42    internal IList<IFunction> Terminals {
    4343      get { return terminals.AsReadOnly(); }
    4444    }
    45     private List<IOperator> allOperators;
    46 
    47     internal IList<IOperator> AllOperators {
    48       get { return allOperators.AsReadOnly(); }
    49     }
    50 
    51     internal TreeGardener(IRandom random, IOperatorLibrary opLibrary) {
     45    private List<IFunction> allFunctions;
     46
     47    internal IList<IFunction> AllFunctions {
     48      get { return allFunctions.AsReadOnly(); }
     49    }
     50
     51    internal TreeGardener(IRandom random, IOperatorLibrary funLibrary) {
    5252      this.random = random;
    53       this.opLibrary = opLibrary;
    54 
    55       this.allOperators = new List<IOperator>();
    56       terminals = new List<IOperator>();
    57       functions = new List<IOperator>();
     53      this.funLibrary = funLibrary;
     54
     55      this.allFunctions = new List<IFunction>();
     56      terminals = new List<IFunction>();
     57      functions = new List<IFunction>();
    5858
    5959      // init functions and terminals based on constraints
    60       foreach (IOperator op in opLibrary.Group.Operators) {
     60      foreach (IFunction fun in funLibrary.Group.Operators) {
    6161        int maxA, minA;
    62         GetMinMaxArity(op, out minA, out maxA);
     62        GetMinMaxArity(fun, out minA, out maxA);
    6363        if (maxA == 0) {
    64           terminals.Add(op);
     64          terminals.Add(fun);
    6565        } else {
    66           functions.Add(op);
    67         }
    68       }
    69 
    70       allOperators.AddRange(functions);
    71       allOperators.AddRange(terminals);
     66          functions.Add(fun);
     67        }
     68      }
     69
     70      allFunctions.AddRange(functions);
     71      allFunctions.AddRange(terminals);
    7272    }
    7373
    7474    #region random initialization
    75     internal IFunctionTree CreateRandomTree(ICollection<IOperator> allowedOperators, int maxTreeSize, int maxTreeHeight, bool balanceTrees) {
    76 
    77       int minTreeHeight = allowedOperators.Select(op => ((IntData)op.GetVariable(GPOperatorLibrary.MIN_TREE_HEIGHT).Value).Data).Min();
     75    internal IFunctionTree CreateRandomTree(ICollection<IFunction> allowedFunctions, int maxTreeSize, int maxTreeHeight, bool balanceTrees) {
     76
     77      int minTreeHeight = allowedFunctions.Select(f => ((IntData)f.GetVariable(GPOperatorLibrary.MIN_TREE_HEIGHT).Value).Data).Min();
    7878      if (minTreeHeight > maxTreeHeight)
    7979        maxTreeHeight = minTreeHeight;
    8080
    81       int minTreeSize = allowedOperators.Select(op => ((IntData)op.GetVariable(GPOperatorLibrary.MIN_TREE_SIZE).Value).Data).Min();
     81      int minTreeSize = allowedFunctions.Select(f => ((IntData)f.GetVariable(GPOperatorLibrary.MIN_TREE_SIZE).Value).Data).Min();
    8282      if (minTreeSize > maxTreeSize)
    8383        maxTreeSize = minTreeSize;
     
    8686      int treeSize = random.Next(minTreeSize, maxTreeSize + 1);
    8787
    88       IOperator[] possibleOperators = allowedOperators.Where(op => ((IntData)op.GetVariable(GPOperatorLibrary.MIN_TREE_HEIGHT).Value).Data <= treeHeight &&
    89         ((IntData)op.GetVariable(GPOperatorLibrary.MIN_TREE_SIZE).Value).Data <= treeSize).ToArray();
    90       IOperator selectedOperator = possibleOperators[random.Next(possibleOperators.Length)];
    91 
    92       return CreateRandomTree(selectedOperator, treeSize, treeHeight, balanceTrees);
     88      IFunction[] possibleFunctions = allowedFunctions.Where(f => ((IntData)f.GetVariable(GPOperatorLibrary.MIN_TREE_HEIGHT).Value).Data <= treeHeight &&
     89        ((IntData)f.GetVariable(GPOperatorLibrary.MIN_TREE_SIZE).Value).Data <= treeSize).ToArray();
     90      IFunction selectedFunction = possibleFunctions[random.Next(possibleFunctions.Length)];
     91
     92      return CreateRandomTree(selectedFunction, treeSize, treeHeight, balanceTrees);
    9393    }
    9494
     
    9696      if (balanceTrees) {
    9797        if (maxTreeHeight == 1 || maxTreeSize==1) {
    98           IOperator selectedTerminal = terminals[random.Next(terminals.Count())];
     98          IFunction selectedTerminal = terminals[random.Next(terminals.Count())];
    9999          return new FunctionTree(selectedTerminal);
    100100        } else {
    101           IOperator[] possibleFunctions = functions.Where(f => GetMinimalTreeHeight(f) <= maxTreeHeight &&
     101          IFunction[] possibleFunctions = functions.Where(f => GetMinimalTreeHeight(f) <= maxTreeHeight &&
    102102            GetMinimalTreeSize(f) <= maxTreeSize).ToArray();
    103           IOperator selectedFunction = possibleFunctions[random.Next(possibleFunctions.Length)];
     103          IFunction selectedFunction = possibleFunctions[random.Next(possibleFunctions.Length)];
    104104          FunctionTree root = new FunctionTree(selectedFunction);
    105105          MakeBalancedTree(root, maxTreeSize - 1, maxTreeHeight - 1);
     
    108108
    109109      } else {
    110         IOperator[] possibleOperators = allOperators.Where(op => GetMinimalTreeHeight(op) <= maxTreeHeight &&
    111           GetMinimalTreeSize(op) <= maxTreeSize).ToArray();
    112         IOperator selectedOperator = possibleOperators[random.Next(possibleOperators.Length)];
    113         FunctionTree root = new FunctionTree(selectedOperator);
     110        IFunction[] possibleFunctions = allFunctions.Where(f => GetMinimalTreeHeight(f) <= maxTreeHeight &&
     111          GetMinimalTreeSize(f) <= maxTreeSize).ToArray();
     112        IFunction selectedFunction = possibleFunctions[random.Next(possibleFunctions.Length)];
     113        FunctionTree root = new FunctionTree(selectedFunction);
    114114        MakeUnbalancedTree(root, maxTreeSize - 1, maxTreeHeight - 1);
    115115        return root;
     
    117117    }
    118118
    119     internal IFunctionTree CreateRandomTree(IOperator rootOp, int maxTreeSize, int maxTreeHeight, bool balanceTrees) {
    120       IFunctionTree root = new FunctionTree(rootOp);
     119    internal IFunctionTree CreateRandomTree(IFunction rootFunction, int maxTreeSize, int maxTreeHeight, bool balanceTrees) {
     120      IFunctionTree root = new FunctionTree(rootFunction);
    121121      if (balanceTrees) {
    122122        MakeBalancedTree(root, maxTreeSize - 1, maxTreeHeight - 1);
     
    144144        int maxSubTreeSize = maxTreeSize / actualArity;
    145145        for (int i = 0; i < actualArity; i++) {
    146           IOperator[] possibleOperators = GetAllowedSubOperators(parent.Function, i).Where(op => GetMinimalTreeHeight(op) <= maxTreeHeight &&
    147             GetMinimalTreeSize(op) <= maxSubTreeSize).ToArray();
    148           IOperator selectedOperator = possibleOperators[random.Next(possibleOperators.Length)];
    149           FunctionTree newSubTree = new FunctionTree(selectedOperator);
     146          IFunction[] possibleFunctions = GetAllowedSubFunctions(parent.Function, i).Where(f => GetMinimalTreeHeight(f) <= maxTreeHeight &&
     147            GetMinimalTreeSize(f) <= maxSubTreeSize).ToArray();
     148          IFunction selectedFunction = possibleFunctions[random.Next(possibleFunctions.Length)];
     149          FunctionTree newSubTree = new FunctionTree(selectedFunction);
    150150          MakeUnbalancedTree(newSubTree, maxSubTreeSize - 1, maxTreeHeight - 1);
    151151          parent.InsertSubTree(i, newSubTree);
     
    155155
    156156    // NOTE: this method doesn't build fully balanced trees because we have constraints on the
    157     // types of possible suboperators which can indirectly impose a limit for the depth of a given suboperator
     157    // types of possible sub-functions which can indirectly impose a limit for the depth of a given sub-tree
    158158    private void MakeBalancedTree(IFunctionTree parent, int maxTreeSize, int maxTreeHeight) {
    159159      if (maxTreeHeight == 0 || maxTreeSize == 0) return; // should never happen anyway
     
    169169        for (int i = 0; i < actualArity; i++) {
    170170          if (maxTreeHeight == 1 || maxSubTreeSize == 1) {
    171             IOperator[] possibleTerminals = GetAllowedSubOperators(parent.Function, i).Where(
    172               op => GetMinimalTreeHeight(op) <= maxTreeHeight &&
    173               GetMinimalTreeSize(op) <= maxSubTreeSize &&
    174               IsTerminal(op)).ToArray();
    175             IOperator selectedTerminal = possibleTerminals[random.Next(possibleTerminals.Length)];
     171            IFunction[] possibleTerminals = GetAllowedSubFunctions(parent.Function, i).Where(
     172              f => GetMinimalTreeHeight(f) <= maxTreeHeight &&
     173              GetMinimalTreeSize(f) <= maxSubTreeSize &&
     174              IsTerminal(f)).ToArray();
     175            IFunction selectedTerminal = possibleTerminals[random.Next(possibleTerminals.Length)];
    176176            IFunctionTree newTree = new FunctionTree(selectedTerminal);
    177177            parent.InsertSubTree(i, newTree);
    178178          } else {
    179             IOperator[] possibleFunctions = GetAllowedSubOperators(parent.Function, i).Where(
    180               op => GetMinimalTreeHeight(op) <= maxTreeHeight &&
    181               GetMinimalTreeSize(op) <= maxSubTreeSize &&
    182               !IsTerminal(op)).ToArray();
    183             IOperator selectedFunction = possibleFunctions[random.Next(possibleFunctions.Length)];
     179            IFunction[] possibleFunctions = GetAllowedSubFunctions(parent.Function, i).Where(
     180              f => GetMinimalTreeHeight(f) <= maxTreeHeight &&
     181              GetMinimalTreeSize(f) <= maxSubTreeSize &&
     182              !IsTerminal(f)).ToArray();
     183            IFunction selectedFunction = possibleFunctions[random.Next(possibleFunctions.Length)];
    184184            FunctionTree newTree = new FunctionTree(selectedFunction);
    185185            parent.InsertSubTree(i, newTree);
     
    195195      Scope tempScope = new Scope("Temp. initialization scope");
    196196
    197       var parametricTrees = trees.Where(o => o.Function.GetVariable(GPOperatorLibrary.INITIALIZATION) != null);
     197      var parametricTrees = trees.Where(t => t.Function.GetVariable(GPOperatorLibrary.INITIALIZATION) != null);
    198198
    199199      foreach (IFunctionTree tree in parametricTrees) {
     
    250250    }
    251251
    252     internal IList<IOperator> GetAllowedSubOperators(IOperator op, int index) {
    253       if (op == null) {
    254         return allOperators;
     252    internal IList<IFunction> GetAllowedSubFunctions(IFunction f, int index) {
     253      if (f == null) {
     254        return allFunctions;
    255255      } else {
    256256
    257257        SubOperatorsConstraintAnalyser analyser = new SubOperatorsConstraintAnalyser();
    258         analyser.AllPossibleOperators = allOperators;
    259 
    260         return analyser.GetAllowedOperators(op, index);
    261       }
    262     }
    263     internal void GetMinMaxArity(IOperator root, out int minArity, out int maxArity) {
    264       foreach (IConstraint constraint in root.Constraints) {
     258        analyser.AllPossibleOperators = allFunctions.Cast<IOperator>().ToArray<IOperator>();
     259
     260        return analyser.GetAllowedOperators(f, index).Cast<IFunction>().ToList<IFunction>();
     261      }
     262    }
     263    internal void GetMinMaxArity(IFunction f, out int minArity, out int maxArity) {
     264      foreach (IConstraint constraint in f.Constraints) {
    265265        NumberOfSubOperatorsConstraint theConstraint = constraint as NumberOfSubOperatorsConstraint;
    266266        if (theConstraint != null) {
     
    274274      maxArity = 2;
    275275    }
    276     internal bool IsTerminal(IOperator f) {
     276    internal bool IsTerminal(IFunction f) {
    277277      int minArity;
    278278      int maxArity;
     
    281281    }
    282282
    283     internal IList<IOperator> GetAllowedParents(IOperator child, int childIndex) {
    284       List<IOperator> parents = new List<IOperator>();
    285       foreach (IOperator function in functions) {
    286         IList<IOperator> allowedSubOperators = GetAllowedSubOperators(function, childIndex);
    287         if (allowedSubOperators.Contains(child, new OperatorEqualityComparer())) {
     283    internal IList<IFunction> GetAllowedParents(IFunction child, int childIndex) {
     284      List<IFunction> parents = new List<IFunction>();
     285      foreach (IFunction function in functions) {
     286        IList<IFunction> allowedSubFunctions = GetAllowedSubFunctions(function, childIndex);
     287        if (allowedSubFunctions.Contains(child, new FunctionEqualityComparer())) {
    288288          parents.Add(function);
    289289        }
     
    292292    }
    293293
    294     internal ICollection<IFunctionTree> GetAllOperators(IFunctionTree root) {
    295       List<IFunctionTree> allOps = new List<IFunctionTree>();
    296       TreeForEach(root, t => { allOps.Add(t); });
    297       return allOps;
     294    internal ICollection<IFunctionTree> GetAllSubTrees(IFunctionTree root) {
     295      List<IFunctionTree> allTrees = new List<IFunctionTree>();
     296      TreeForEach(root, t => { allTrees.Add(t); });
     297      return allTrees;
    298298    }
    299299
    300300    /// <summary>
    301     /// returns the height level of op in the tree
    302     /// if the op == tree => 1
    303     /// if op is in the suboperators of tree => 2
     301    /// returns the height level of branch in the tree
     302    /// if the branch == tree => 1
     303    /// if branch is in the sub-trees of tree => 2
    304304    /// ...
    305     /// if op is not found => -1
     305    /// if branch is not found => -1
    306306    /// </summary>
    307     /// <param name="tree">operator tree to process</param>
    308     /// <param name="op">operater that is searched in the tree</param>
     307    /// <param name="tree">root of the function tree to process</param>
     308    /// <param name="branch">branch that is searched in the tree</param>
    309309    /// <returns></returns>
    310     internal int GetNodeLevel(IFunctionTree tree, IFunctionTree op) {
    311       return GetNodeLevelHelper(tree, op, 1);
    312     }
    313 
    314     private int GetNodeLevelHelper(IFunctionTree tree, IFunctionTree op, int level) {
    315       if (op == tree) return level;
     310    internal int GetBranchLevel(IFunctionTree tree, IFunctionTree branch) {
     311      return GetBranchLevelHelper(tree, branch, 1);
     312    }
     313
     314    // 'tail-recursive' helper
     315    private int GetBranchLevelHelper(IFunctionTree tree, IFunctionTree branch, int level) {
     316      if (branch == tree) return level;
    316317
    317318      foreach (IFunctionTree subTree in tree.SubTrees) {
    318         int result = GetNodeLevelHelper(subTree, op, level + 1);
     319        int result = GetBranchLevelHelper(subTree, branch, level + 1);
    319320        if (result != -1) return result;
    320321      }
     
    334335    }
    335336
    336     // returns a random node from the specified level in the tree
    337     internal IFunctionTree GetRandomNode(IFunctionTree tree, int level) {
     337    // returns a random branch from the specified level in the tree
     338    internal IFunctionTree GetRandomBranch(IFunctionTree tree, int level) {
    338339      if (level == 0) return tree;
    339       List<IFunctionTree> nodes = GetOperatorsAtLevel(tree, level);
    340       return nodes[random.Next(nodes.Count)];
     340      List<IFunctionTree> branches = GetBranchesAtLevel(tree, level);
     341      return branches[random.Next(branches.Count)];
    341342    }
    342343    #endregion
     
    359360    }
    360361
    361     private List<IFunctionTree> GetOperatorsAtLevel(IFunctionTree tree, int level) {
     362    private List<IFunctionTree> GetBranchesAtLevel(IFunctionTree tree, int level) {
    362363      if (level == 1) return new List<IFunctionTree>(tree.SubTrees);
    363364
    364       List<IFunctionTree> result = new List<IFunctionTree>();
     365      List<IFunctionTree> branches = new List<IFunctionTree>();
    365366      foreach (IFunctionTree subTree in tree.SubTrees) {
    366         result.AddRange(GetOperatorsAtLevel(subTree, level - 1));
    367       }
    368       return result;
     367        branches.AddRange(GetBranchesAtLevel(subTree, level - 1));
     368      }
     369      return branches;
    369370    }
    370371
     
    372373    #endregion
    373374
    374     internal class OperatorEqualityComparer : IEqualityComparer<IOperator> {
    375       #region IEqualityComparer<IOperator> Members
    376       public bool Equals(IOperator x, IOperator y) {
     375    internal class FunctionEqualityComparer : IEqualityComparer<IFunction> {
     376      #region IEqualityComparer<IFunction> Members
     377      public bool Equals(IFunction x, IFunction y) {
    377378        return  x==y ||
    378379          ((StringData)x.GetVariable(GPOperatorLibrary.TYPE_ID).Value).Data ==
     
    380381      }
    381382
    382       public int GetHashCode(IOperator obj) {
     383      public int GetHashCode(IFunction obj) {
    383384        return ((StringData)obj.GetVariable(GPOperatorLibrary.TYPE_ID).Value).Data.GetHashCode();
    384385      }
     
    386387    }
    387388
    388     internal ICollection<IOperator> GetPossibleParents(List<IOperator> list) {
    389       List<IOperator> result = new List<IOperator>();
    390       foreach (IOperator op in functions) {
    391         if (IsPossibleParent(op, list)) {
    392           result.Add(op);
     389    internal ICollection<IFunction> GetPossibleParents(List<IFunction> list) {
     390      List<IFunction> result = new List<IFunction>();
     391      foreach (IFunction f in functions) {
     392        if (IsPossibleParent(f, list)) {
     393          result.Add(f);
    393394        }
    394395      }
     
    396397    }
    397398
    398     private bool IsPossibleParent(IOperator op, List<IOperator> children) {
     399    private bool IsPossibleParent(IFunction f, List<IFunction> children) {
    399400      int minArity;
    400401      int maxArity;
    401       GetMinMaxArity(op, out minArity, out maxArity);
     402      GetMinMaxArity(f, out minArity, out maxArity);
    402403
    403404      // note: we can't assume that the operators in the children list have different types!
     
    411412
    412413      SubOperatorsConstraintAnalyser analyzer = new SubOperatorsConstraintAnalyser();
    413       analyzer.AllPossibleOperators = children;
    414 
    415       List<HashSet<IOperator>> slotSets = new List<HashSet<IOperator>>();
    416 
    417       // we iterate through all slots for sub-operators and calculate the set of
    418       // allowed sub-operators for this slot.
     414      analyzer.AllPossibleOperators = children.Cast<IOperator>().ToArray<IOperator>();
     415
     416      List<HashSet<IFunction>> slotSets = new List<HashSet<IFunction>>();
     417
     418      // we iterate through all slots for sub-trees and calculate the set of
     419      // allowed functions for this slot.
    419420      // we only count those slots that can hold at least one of the children that we should combine
    420421      for (int slot = 0; slot < nSlots; slot++) {
    421         HashSet<IOperator> operatorSet = new HashSet<IOperator>(analyzer.GetAllowedOperators(op, slot));
    422         if (operatorSet.Count() > 0) {
    423           slotSets.Add(operatorSet);
     422        HashSet<IFunction> functionSet = new HashSet<IFunction>(analyzer.GetAllowedOperators(f, slot).Cast<IFunction>());
     423        if (functionSet.Count() > 0) {
     424          slotSets.Add(functionSet);
    424425        }
    425426      }
     
    428429      // hold one of our children.
    429430      // if the number of slots is smaller than the number of children we can be sure that
    430       // we can never combine all children as sub-operators of the operator and thus the operator
     431      // we can never combine all children as sub-trees of the function and thus the function
    431432      // can't be a parent.
    432433      if (slotSets.Count() < children.Count()) {
     
    435436
    436437      // finally we sort the sets by size and beginning from the first set select one
    437       // operator for the slot and thus remove it as possible sub-operator from the remaining sets.
    438       // when we can successfully assign all available children to a slot the operator is a valid parent
    439       // when only a subset of all children can be assigned to slots the operator is no valid parent
     438      // function for the slot and thus remove it as possible sub-tree from the remaining sets.
     439      // when we can successfully assign all available children to a slot the function is a valid parent
     440      // when only a subset of all children can be assigned to slots the function is no valid parent
    440441      slotSets.Sort((p, q) => p.Count() - q.Count());
    441442
     
    443444      for (int i = 0; i < slotSets.Count() - 1; i++) {
    444445        if (slotSets[i].Count > 0) {
    445           IOperator selected = slotSets[i].ElementAt(0);
     446          IFunction selected = slotSets[i].ElementAt(0);
    446447          assignments++;
    447448          for (int j = i + 1; j < slotSets.Count(); j++) {
  • branches/FunctionsAndStructIdRefactoring/HeuristicLab/UpdateLocalInstallation.cmd

    r142 r143  
    1 set target=G:\Program Files\HeuristicLab 3.0
     1set target=C:\Program Files\HeuristicLab 3.0
    22
    33copy "HeuristicLab.exe" "%target%"
Note: See TracChangeset for help on using the changeset viewer.