Free cookie consent management tool by TermsFeed Policy Generator

Changeset 152


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

bug-fixes and code cleanup in struct-id operators (#112)

Location:
branches/FunctionsAndStructIdRefactoring/HeuristicLab.StructureIdentification
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • branches/FunctionsAndStructIdRefactoring/HeuristicLab.StructureIdentification/GPOperatorGroup.cs

    r2 r152  
    3232namespace HeuristicLab.StructureIdentification {
    3333  public class GPOperatorGroup : OperatorGroup {
    34 
    3534    public GPOperatorGroup()
    3635      : base() {
     
    118117      int maxArity;
    119118      GetMinMaxArity(op, out minArity, out maxArity);
    120       ItemList slotsList = (ItemList)op.GetVariable(GPOperatorLibrary.ALLOWED_SUBOPERATORS).Value;
     119      var slotsList = (ItemList)op.GetVariable(GPOperatorLibrary.ALLOWED_SUBOPERATORS).Value;
    121120      slotsList.Clear();
    122121      for(int i = 0; i < maxArity; i++) {
     
    276275    }
    277276
    278 
    279277    public override void AddSubGroup(IOperatorGroup group) {
    280278      throw new NotSupportedException();
  • branches/FunctionsAndStructIdRefactoring/HeuristicLab.StructureIdentification/Manipulation/ChangeNodeTypeManipulation.cs

    r149 r152  
    8181          // updating the variable is not necessary because it stays the same
    8282        }
     83        if(!gardener.IsValidTree(root)) throw new InvalidProgramException();
    8384
    8485        // size and height stays the same when changing a terminal so no need to update the variables
     
    105106        treeHeight.Data = gardener.GetTreeHeight(root);
    106107
     108        // check if whole tree is ok
    107109        // check if the size of the new tree is still in the allowed bounds
    108         if (treeHeight.Data > maxTreeHeight ||
     110        if (!gardener.IsValidTree(root) ||
     111          treeHeight.Data > maxTreeHeight ||
    109112          treeSize.Data > maxTreeSize) {
    110113          throw new InvalidProgramException();
    111114        }
    112115
    113         // check if whole tree is ok
    114         if (!gardener.IsValidTree(root)) {
    115           throw new InvalidProgramException();
    116         }
    117 
    118116        // return a composite operation that initializes all created sub-trees
    119117        return gardener.CreateInitializationOperation(uninitializedBranches, scope);
    120118      }
    121119    }
    122 
    123120
    124121    private IFunctionTree ChangeTerminalType(IFunctionTree parent, IFunctionTree child, int childIndex, TreeGardener gardener, MersenneTwister random) {
     
    127124        allowedChildren = gardener.Terminals;
    128125      } else {
    129         SubOperatorsConstraintAnalyser analyser = new SubOperatorsConstraintAnalyser();
    130         analyser.AllPossibleOperators = gardener.Terminals.Cast<IOperator>().ToArray();
    131         allowedChildren = analyser.GetAllowedOperators(parent.Function, childIndex).Cast<IFunction>().ToList();
     126        allowedChildren = new List<IFunction>();
     127        var allAllowedChildren = gardener.GetAllowedSubFunctions(parent.Function, childIndex);
     128        foreach(IFunction c in allAllowedChildren) {
     129          if(gardener.IsTerminal(c)) allowedChildren.Add(c);
     130        }
    132131      }
    133132
     
    144143      // let's choose the function we want to use instead of the old child. For this we have to determine the
    145144      // pool of allowed functions based on constraints of the parent if there is one.
    146       IList<IFunction> allowedFunctions;
    147       SubOperatorsConstraintAnalyser analyser = new SubOperatorsConstraintAnalyser();
    148       analyser.AllPossibleOperators = gardener.AllFunctions.Cast<IOperator>().ToArray();
    149       if (parent == null) {
    150         allowedFunctions = gardener.AllFunctions;
    151       } else {
    152         allowedFunctions = analyser.GetAllowedOperators(parent.Function, childIndex).Cast<IFunction>().ToList();
    153       }
     145      IList<IFunction> allowedFunctions = gardener.GetAllowedSubFunctions(parent!=null?parent.Function:null, childIndex);
    154146
    155147      // try to make a tree with the same arity as the old child.
     
    190182        // then use a random existing sub-tree. When there are no existing sub-trees
    191183        // that fit in the given slot then create a new random tree and use it for the slot
    192         IList<IFunction> allowedSubFunctions = analyser.GetAllowedOperators(newTree.Function, i).Cast<IFunction>().ToList();
     184        ICollection<IFunction> allowedSubFunctions = gardener.GetAllowedSubFunctions(newTree.Function, i);
    193185        var matchingSubTrees = availableSubTrees.Where(subTree => allowedSubFunctions.Contains(subTree.Function));
    194186
  • branches/FunctionsAndStructIdRefactoring/HeuristicLab.StructureIdentification/Manipulation/CutOutNodeManipulation.cs

    r149 r152  
    108108
    109109      // match the sub-trees of the child with the allowed sub-trees of the parent
    110       IList<IFunction> allowedFunctions = gardener.GetAllowedSubFunctions(parent.Function, childIndex);
     110      ICollection<IFunction> allowedFunctions = gardener.GetAllowedSubFunctions(parent.Function, childIndex);
    111111      IFunctionTree[] possibleChilds = child.SubTrees.Where(t => allowedFunctions.Contains(t.Function)).ToArray();
    112112
  • branches/FunctionsAndStructIdRefactoring/HeuristicLab.StructureIdentification/Manipulation/DeleteSubTreeManipulation.cs

    r149 r152  
    100100        parent.RemoveSubTree(childIndex);
    101101
    102         IList<IFunction> allowedFunctions = gardener.GetAllowedSubFunctions(parent.Function, childIndex);
     102        ICollection<IFunction> allowedFunctions = gardener.GetAllowedSubFunctions(parent.Function, childIndex);
    103103        IFunctionTree newFunctionTree = gardener.CreateRandomTree(allowedFunctions, 1, 1, true);
    104104
  • branches/FunctionsAndStructIdRefactoring/HeuristicLab.StructureIdentification/Manipulation/SubstituteSubTreeManipulation.cs

    r149 r152  
    8888        int childIndex = random.Next(parent.SubTrees.Count);
    8989        // get the list of allowed functions for the new sub-tree
    90         IList<IFunction> allowedFunctions = gardener.GetAllowedSubFunctions(parent.Function, childIndex);
     90        ICollection<IFunction> allowedFunctions = gardener.GetAllowedSubFunctions(parent.Function, childIndex);
    9191        if(allowedFunctions.Count == 0) {
    9292          // don't change anything
  • branches/FunctionsAndStructIdRefactoring/HeuristicLab.StructureIdentification/Recombination/SinglePointCrossOver.cs

    r143 r152  
    7878    }
    7979
    80 
    8180    private IOperation Cross(TreeGardener gardener, int maxTreeSize, int maxTreeHeight,
    8281      IScope scope, MersenneTwister random, IScope parent1, IScope parent2, IScope child) {
     
    8584        random, maxTreeSize, maxTreeHeight, out newBranches);
    8685
    87       if(!gardener.IsValidTree(newTree)) {
    88         throw new InvalidProgramException();
    89       }
    9086
    9187      int newTreeSize = gardener.GetTreeSize(newTree);
    9288      int newTreeHeight = gardener.GetTreeHeight(newTree);
    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)));
    96 
    97       // check if the size of the new tree is still in the allowed bounds
    98       if (newTreeHeight > maxTreeHeight ||
     89      child.AddVariable(new HeuristicLab.Core.Variable(scope.TranslateName("FunctionTree"), newTree));
     90      child.AddVariable(new HeuristicLab.Core.Variable(scope.TranslateName("TreeSize"), new IntData(newTreeSize)));
     91      child.AddVariable(new HeuristicLab.Core.Variable(scope.TranslateName("TreeHeight"), new IntData(newTreeHeight)));
     92
     93      // check if the new tree is valid and if the size of is still in the allowed bounds
     94      if(!gardener.IsValidTree(newTree) ||
     95        newTreeHeight > maxTreeHeight ||
    9996        newTreeSize > maxTreeSize) {
    10097        throw new InvalidProgramException();
     
    139136
    140137        List<int> possibleChildIndices = new List<int>();
    141         TreeGardener.FunctionEqualityComparer comparer = new TreeGardener.FunctionEqualityComparer();
    142138
    143139        // Now tree0 is supposed to take tree1 as one if its children. If this is not possible,
    144140        // then go down in either of the two trees as far as possible. If even then it is not possible
    145141        // to merge the trees then throw an exception
    146         // find the list of allowed indices (regarding allowed sub-operators, maxTreeSize and maxTreeHeight)
     142        // find the list of allowed indices (regarding allowed sub-trees, maxTreeSize and maxTreeHeight)
    147143        for(int i = 0; i < tree0.SubTrees.Count; i++) {
    148144          int subTreeSize = gardener.GetTreeSize(tree0.SubTrees[i]);
    149145
    150146          // 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) &&
     147          if(gardener.GetAllowedSubFunctions(tree0.Function, i).Contains(tree1.Function) &&
    152148            rootSize - subTreeSize + tree1Size < maxTreeSize &&
    153149            tree0Level + tree1Height < maxTreeHeight) {
     
    157153
    158154        while(possibleChildIndices.Count == 0) {
    159           // ok we couln't find a possible configuration given the current tree0 and tree1
     155          // we couln't find a possible configuration given the current tree0 and tree1
    160156          // possible reasons for this are:
    161157          //  - tree1 is not allowed as sub-tree of tree0
     
    187183            // when the function is allowed as sub-tree and we don't violate the maxSize and maxHeight constraints
    188184            // the index is ok
    189             if(GetAllowedOperators(tree0.Function, i).Contains(tree1.Function, comparer) &&
     185            if(gardener.GetAllowedSubFunctions(tree0.Function, i).Contains(tree1.Function) &&
    190186              rootSize - subTreeSize + tree1Size < maxTreeSize &&
    191187              tree0Level + tree1Height < maxTreeHeight) {
     
    211207    }
    212208
    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();
    216     }
    217 
     209
     210    // take f and g and create a tree that has f and g as sub-trees
     211    // example
     212    //       O
     213    //      /|\
     214    //     g 2 f
     215    //
    218216    private IFunctionTree CombineTerminals(TreeGardener gardener, IFunctionTree f, IFunctionTree g, MersenneTwister random, int maxTreeHeight, out List<IFunctionTree> newBranches) {
    219217      newBranches = new List<IFunctionTree>();
     218      // determine the set of possible parent functions
    220219      ICollection<IFunction> possibleParents = gardener.GetPossibleParents(new List<IFunction>() { f.Function, g.Function });
    221220      if(possibleParents.Count == 0) throw new InvalidProgramException();
    222 
     221      // and select a random one
    223222      IFunctionTree parent = new FunctionTree(possibleParents.ElementAt(random.Next(possibleParents.Count())));
    224223
     
    226225      int maxArity;
    227226      gardener.GetMinMaxArity(parent.Function, out minArity, out maxArity);
    228 
    229227      int nSlots = Math.Max(2, minArity);
    230 
    231       HashSet<IFunction>[] slotSets = new HashSet<IFunction>[nSlots];
    232 
    233       SubOperatorsConstraintAnalyser analyser = new SubOperatorsConstraintAnalyser();
    234       analyser.AllPossibleOperators = new List<IOperator>() { g.Function, f.Function };
     228      // determine which slot can take which sub-trees
     229      List<IFunctionTree>[] slots = new List<IFunctionTree>[nSlots];
    235230      for(int slot = 0; slot < nSlots; slot++) {
    236         HashSet<IFunction> slotSet = new HashSet<IFunction>(analyser.GetAllowedOperators(parent.Function, slot).Cast<IFunction>());
    237         slotSets[slot] = slotSet;
    238       }
    239 
    240       int[] slotSequence = Enumerable.Range(0, slotSets.Count()).OrderBy(slot => slotSets[slot].Count()).ToArray();
    241 
     231        ICollection<IFunction> allowedSubFunctions = gardener.GetAllowedSubFunctions(parent.Function, slot);
     232        List<IFunctionTree> allowedTrees = new List<IFunctionTree>();
     233        if(allowedSubFunctions.Contains(f.Function)) allowedTrees.Add(f);
     234        if(allowedSubFunctions.Contains(g.Function)) allowedTrees.Add(g);
     235        slots[slot] = allowedTrees;
     236      }
     237      // fill the slots in the order of degrees of freedom
     238      int[] slotSequence = Enumerable.Range(0, slots.Count()).OrderBy(slot => slots[slot].Count()).ToArray();
     239
     240      // tmp arry to store the tree for each sub-tree slot of the parent
    242241      IFunctionTree[] selectedFunctionTrees = new IFunctionTree[nSlots];
     242
     243      // fill the sub-tree slots of the parent starting with the slots that can take potentially both functions (f and g)
    243244      for(int i = 0; i < slotSequence.Length; i++) {
    244245        int slot = slotSequence[i];
    245         HashSet<IFunction> slotSet = slotSets[slot];
    246         if(slotSet.Count() == 0) {
    247           var allowedFunctions = GetAllowedOperators(parent.Function, slot);
     246        List<IFunctionTree> allowedTrees = slots[slot];
     247        // when neither f nor g fit into the slot => create a new random tree
     248        if(allowedTrees.Count() == 0) {
     249          var allowedFunctions = gardener.GetAllowedSubFunctions(parent.Function, slot);
    248250          selectedFunctionTrees[slot] = gardener.CreateRandomTree(allowedFunctions, 1, 1, true);
    249251          newBranches.AddRange(gardener.GetAllSubTrees(selectedFunctionTrees[slot]));
    250252        } else {
    251           IFunction selectedFunction = slotSet.ElementAt(random.Next(slotSet.Count()));
    252           selectedFunctionTrees[slot] = new FunctionTree(selectedFunction);
     253          // select randomly which tree to insert into this slot
     254          IFunctionTree selectedTree = allowedTrees[random.Next(allowedTrees.Count())];
     255          selectedFunctionTrees[slot] = selectedTree;
     256          // remove the tree that we used in this slot from following function-sets
    253257          for(int j = i + 1; j < slotSequence.Length; j++) {
    254258            int otherSlot = slotSequence[j];
    255             slotSets[otherSlot].Remove(selectedFunction);
    256           }
    257         }
    258       }
    259 
     259            slots[otherSlot].Remove(selectedTree);
     260          }
     261        }
     262      }
     263      // actually append the sub-trees to the parent tree
    260264      for(int i = 0; i < selectedFunctionTrees.Length; i++) {
    261265        parent.InsertSubTree(i, selectedFunctionTrees[i]);
  • branches/FunctionsAndStructIdRefactoring/HeuristicLab.StructureIdentification/TreeGardener.cs

    r148 r152  
    3232using HeuristicLab.Selection;
    3333using HeuristicLab.Functions;
     34using System.Collections;
    3435
    3536namespace HeuristicLab.StructureIdentification {
    3637  internal class TreeGardener {
    3738    private IRandom random;
    38     private IOperatorLibrary funLibrary;
     39    private GPOperatorLibrary funLibrary;
    3940    private List<IFunction> functions;
    4041    private List<IFunction> terminals;
     
    4950    }
    5051
    51     internal TreeGardener(IRandom random, IOperatorLibrary funLibrary) {
     52    internal TreeGardener(IRandom random, GPOperatorLibrary funLibrary) {
    5253      this.random = random;
    5354      this.funLibrary = funLibrary;
     
    254255        return allFunctions;
    255256      } else {
    256 
    257         SubOperatorsConstraintAnalyser analyser = new SubOperatorsConstraintAnalyser();
    258         analyser.AllPossibleOperators = allFunctions.Cast<IOperator>().ToArray<IOperator>();
    259 
    260         return analyser.GetAllowedOperators(f, index).Cast<IFunction>().ToList<IFunction>();
     257        ItemList slotList = (ItemList)f.GetVariable(GPOperatorLibrary.ALLOWED_SUBOPERATORS).Value;
     258        List<IFunction> result = new List<IFunction>();
     259        foreach(IFunction function in (ItemList)slotList[index]) {
     260          result.Add(function);
     261        }
     262        return result;
    261263      }
    262264    }
     
    284286      List<IFunction> parents = new List<IFunction>();
    285287      foreach (IFunction function in functions) {
    286         IList<IFunction> allowedSubFunctions = GetAllowedSubFunctions(function, childIndex);
    287         if (allowedSubFunctions.Contains(child, new FunctionEqualityComparer())) {
     288        ICollection<IFunction> allowedSubFunctions = GetAllowedSubFunctions(function, childIndex);
     289        if (allowedSubFunctions.Contains(child)) {
    288290          parents.Add(function);
    289291        }
     
    377379    #endregion
    378380
    379     internal class FunctionEqualityComparer : IEqualityComparer<IFunction> {
    380       #region IEqualityComparer<IFunction> Members
    381       public bool Equals(IFunction x, IFunction y) {
    382         return  x==y ||
    383           ((StringData)x.GetVariable(GPOperatorLibrary.TYPE_ID).Value).Data ==
    384           ((StringData)y.GetVariable(GPOperatorLibrary.TYPE_ID).Value).Data;
    385       }
    386 
    387       public int GetHashCode(IFunction obj) {
    388         return ((StringData)obj.GetVariable(GPOperatorLibrary.TYPE_ID).Value).Data.GetHashCode();
    389       }
    390       #endregion
    391     }
    392 
    393381    internal ICollection<IFunction> GetPossibleParents(List<IFunction> list) {
    394382      List<IFunction> result = new List<IFunction>();
Note: See TracChangeset for help on using the changeset viewer.