Free cookie consent management tool by TermsFeed Policy Generator

Changeset 5916


Ignore:
Timestamp:
03/31/11 19:20:29 (13 years ago)
Author:
gkronber
Message:

#1418 changed crossover operator for symbolic expression trees to allow extensions and reductions of the number of subtrees for variable-arity symbols.

Location:
trunk/sources/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/sources/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Crossovers/SubtreeCrossover.cs

    r5809 r5916  
    8888      double internalCrossoverPointProbability, int maxTreeLength, int maxTreeDepth) {
    8989      // select a random crossover point in the first parent
    90       ISymbolicExpressionTreeNode crossoverPoint0;
    91       int replacedSubtreeIndex;
    92       SelectCrossoverPoint(random, parent0, internalCrossoverPointProbability, maxTreeLength, maxTreeDepth, out crossoverPoint0, out replacedSubtreeIndex);
    93 
     90      CutPoint crossoverPoint0;
     91      SelectCrossoverPoint(random, parent0, internalCrossoverPointProbability, maxTreeLength, maxTreeDepth, out crossoverPoint0);
     92
     93      int childLength = crossoverPoint0.Child != null ? crossoverPoint0.Child.GetLength() : 0;
    9494      // calculate the max length and depth that the inserted branch can have
    95       int maxInsertedBranchLength = maxTreeLength - (parent0.Length - crossoverPoint0.GetSubtree(replacedSubtreeIndex).GetLength());
    96       int maxInsertedBranchDepth = maxTreeDepth - GetBranchLevel(parent0.Root, crossoverPoint0);
     95      int maxInsertedBranchLength = maxTreeLength - (parent0.Length - childLength);
     96      int maxInsertedBranchDepth = maxTreeDepth - GetBranchLevel(parent0.Root, crossoverPoint0.Parent);
     97
    9798
    9899      List<ISymbolicExpressionTreeNode> allowedBranches = new List<ISymbolicExpressionTreeNode>();
     
    100101        if (n.GetLength() <= maxInsertedBranchLength &&
    101102          n.GetDepth() <= maxInsertedBranchDepth &&
    102           IsMatchingPointType(crossoverPoint0, replacedSubtreeIndex, n))
     103          IsMatchingPointType(crossoverPoint0, n))
    103104          allowedBranches.Add(n);
    104105      });
     106      // empty branch
     107      if (IsMatchingPointType(crossoverPoint0, null)) allowedBranches.Add(null);
    105108
    106109      if (allowedBranches.Count == 0) {
     
    109112        var selectedBranch = SelectRandomBranch(random, allowedBranches, internalCrossoverPointProbability);
    110113
    111         // manipulate the tree of parent0 in place
    112         // replace the branch in tree0 with the selected branch from tree1
    113         crossoverPoint0.RemoveSubtree(replacedSubtreeIndex);
    114         crossoverPoint0.InsertSubtree(replacedSubtreeIndex, selectedBranch);
     114        if (crossoverPoint0.Child != null) {
     115          // manipulate the tree of parent0 in place
     116          // replace the branch in tree0 with the selected branch from tree1
     117          crossoverPoint0.Parent.RemoveSubtree(crossoverPoint0.ChildIndex);
     118          if (selectedBranch != null) {
     119            crossoverPoint0.Parent.InsertSubtree(crossoverPoint0.ChildIndex, selectedBranch);
     120          }
     121        } else {
     122          // child is null (additional child should be added under the parent)
     123          if (selectedBranch != null) {
     124            crossoverPoint0.Parent.AddSubtree(selectedBranch);
     125          }
     126        }
    115127        return parent0;
    116128      }
    117129    }
    118130
    119     private static bool IsMatchingPointType(ISymbolicExpressionTreeNode parent, int replacedSubtreeIndex, ISymbolicExpressionTreeNode branch) {
    120       // check syntax constraints of direct parent - child relation
    121       if (!parent.Grammar.ContainsSymbol(branch.Symbol) ||
    122           !parent.Grammar.IsAllowedChildSymbol(parent.Symbol, branch.Symbol, replacedSubtreeIndex)) return false;
    123 
    124       bool result = true;
    125       // check point type for the whole branch
    126       branch.ForEachNodePostfix((n) => {
    127         result =
    128           result &&
    129           parent.Grammar.ContainsSymbol(n.Symbol) &&
    130           n.SubtreesCount >= parent.Grammar.GetMinimumSubtreeCount(n.Symbol) &&
    131           n.SubtreesCount <= parent.Grammar.GetMaximumSubtreeCount(n.Symbol);
    132       });
    133       return result;
    134     }
    135 
    136     private static void SelectCrossoverPoint(IRandom random, ISymbolicExpressionTree parent0, double internalNodeProbability, int maxBranchLength, int maxBranchDepth, out ISymbolicExpressionTreeNode crossoverPoint, out int subtreeIndex) {
     131    private static bool IsMatchingPointType(CutPoint cutPoint, ISymbolicExpressionTreeNode newChild) {
     132      var parent = cutPoint.Parent;
     133      if (newChild == null) {
     134        // make sure that one subtree can be removed and that only the last subtree is removed
     135        return parent.Grammar.GetMinimumSubtreeCount(parent.Symbol) < parent.SubtreesCount &&
     136          cutPoint.ChildIndex == parent.SubtreesCount - 1;
     137      } else {
     138        // check syntax constraints of direct parent - child relation
     139        if (!parent.Grammar.ContainsSymbol(newChild.Symbol) ||
     140            !parent.Grammar.IsAllowedChildSymbol(parent.Symbol, newChild.Symbol, cutPoint.ChildIndex)) return false;
     141
     142        bool result = true;
     143        // check point type for the whole branch
     144        newChild.ForEachNodePostfix((n) => {
     145          result =
     146            result &&
     147            parent.Grammar.ContainsSymbol(n.Symbol) &&
     148            n.SubtreesCount >= parent.Grammar.GetMinimumSubtreeCount(n.Symbol) &&
     149            n.SubtreesCount <= parent.Grammar.GetMaximumSubtreeCount(n.Symbol);
     150        });
     151        return result;
     152      }
     153    }
     154
     155    private static void SelectCrossoverPoint(IRandom random, ISymbolicExpressionTree parent0, double internalNodeProbability, int maxBranchLength, int maxBranchDepth, out CutPoint crossoverPoint) {
    137156      if (internalNodeProbability < 0.0 || internalNodeProbability > 1.0) throw new ArgumentException("internalNodeProbability");
    138157      List<CutPoint> internalCrossoverPoints = new List<CutPoint>();
     
    149168            }
    150169          }
     170          // add one additional extension point if the number of sub trees for the symbol is not full
     171          if (n.SubtreesCount < n.Grammar.GetMaximumSubtreeCount(n.Symbol)) {
     172            // empty extension point
     173            internalCrossoverPoints.Add(new CutPoint(n, n.SubtreesCount));
     174          }
    151175        }
    152176      });
     
    156180        if (internalCrossoverPoints.Count > 0) {
    157181          // select internal crossover point or leaf
    158           var selectedCrossoverPoint = internalCrossoverPoints[random.Next(internalCrossoverPoints.Count)];
    159           crossoverPoint = selectedCrossoverPoint.Parent;
    160           subtreeIndex = selectedCrossoverPoint.ChildIndex;
     182          crossoverPoint = internalCrossoverPoints[random.Next(internalCrossoverPoints.Count)];
    161183        } else {
    162184          // otherwise select external node
    163           var selectedCrossoverPoint = leafCrossoverPoints[random.Next(leafCrossoverPoints.Count)];
    164           crossoverPoint = selectedCrossoverPoint.Parent;
    165           subtreeIndex = selectedCrossoverPoint.ChildIndex;
     185          crossoverPoint = leafCrossoverPoints[random.Next(leafCrossoverPoints.Count)];
    166186        }
    167187      } else if (leafCrossoverPoints.Count > 0) {
    168188        // select from leaf crossover point if possible
    169         var selectedCrossoverPoint = leafCrossoverPoints[random.Next(leafCrossoverPoints.Count)];
    170         crossoverPoint = selectedCrossoverPoint.Parent;
    171         subtreeIndex = selectedCrossoverPoint.ChildIndex;
     189        crossoverPoint = leafCrossoverPoints[random.Next(leafCrossoverPoints.Count)];
    172190      } else {
    173191        // otherwise select internal crossover point
    174         var selectedCrossoverPoint = internalCrossoverPoints[random.Next(internalCrossoverPoints.Count)];
    175         crossoverPoint = selectedCrossoverPoint.Parent;
    176         subtreeIndex = selectedCrossoverPoint.ChildIndex;
     192        crossoverPoint = internalCrossoverPoints[random.Next(internalCrossoverPoints.Count)];
    177193      }
    178194    }
     
    185201        // select internal node if possible
    186202        allowedInternalBranches = (from branch in branches
    187                                    where branch.Subtrees.Any()
     203                                   where branch != null && branch.Subtrees.Any()
    188204                                   select branch).ToList();
    189205        if (allowedInternalBranches.Count > 0) {
     
    192208          // no internal nodes allowed => select leaf nodes
    193209          allowedLeafBranches = (from branch in branches
    194                                  where !branch.Subtrees.Any()
     210                                 where branch == null || !branch.Subtrees.Any()
    195211                                 select branch).ToList();
    196212          return allowedLeafBranches.SelectRandom(random);
     
    199215        // select leaf node if possible
    200216        allowedLeafBranches = (from branch in branches
    201                                where !branch.Subtrees.Any()
     217                               where branch == null || !branch.Subtrees.Any()
    202218                               select branch).ToList();
    203219        if (allowedLeafBranches.Count > 0) {
     
    205221        } else {
    206222          allowedInternalBranches = (from branch in branches
    207                                      where branch.Subtrees.Any()
     223                                     where branch != null && branch.Subtrees.Any()
    208224                                     select branch).ToList();
    209225          return allowedInternalBranches.SelectRandom(random);
  • trunk/sources/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/CutPoint.cs

    r5809 r5916  
    3434      this.childIndex = parent.IndexOfSubtree(child);
    3535    }
     36    public CutPoint(ISymbolicExpressionTreeNode parent, int childIndex) {
     37      this.Parent = parent;
     38      this.childIndex = childIndex;
     39      this.Child = null;
     40    }
    3641  }
    3742}
Note: See TracChangeset for help on using the changeset viewer.