Free cookie consent management tool by TermsFeed Policy Generator

Ignore:
Timestamp:
04/09/10 17:28:32 (14 years ago)
Author:
gkronber
Message:

Added first version of architecture altering operators for ADFs. #290 (Implement ADFs)

File:
1 edited

Legend:

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

    r3237 r3294  
    2727using System;
    2828using HeuristicLab.Parameters;
     29using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.GeneralSymbols;
    2930namespace HeuristicLab.Encodings.SymbolicExpressionTreeEncoding {
    3031
     
    3940  [StorableClass]
    4041  public class SubtreeCrossover : SymbolicExpressionTreeCrossover {
    41     private const int MAX_TRIES = 100;
    42 
    4342    public IValueLookupParameter<PercentValue> InternalCrossoverPointProbabilityParameter {
    4443      get { return (IValueLookupParameter<PercentValue>)Parameters["InternalCrossoverPointProbability"]; }
     
    5251    protected override SymbolicExpressionTree Cross(IRandom random, ISymbolicExpressionGrammar grammar,
    5352      SymbolicExpressionTree parent0, SymbolicExpressionTree parent1,
    54       IntValue maxTreeSize, IntValue maxTreeHeight) {
    55       return Apply(random, grammar, parent0, parent1, InternalCrossoverPointProbabilityParameter.ActualValue.Value, maxTreeSize.Value, maxTreeHeight.Value);
     53      IntValue maxTreeSize, IntValue maxTreeHeight, out bool success) {
     54      return Cross(random, grammar, parent0, parent1, InternalCrossoverPointProbabilityParameter.ActualValue.Value, maxTreeSize.Value, maxTreeHeight.Value, out success);
    5655    }
    5756
    58     public static SymbolicExpressionTree Apply(IRandom random, ISymbolicExpressionGrammar grammar,
     57    public static SymbolicExpressionTree Cross(IRandom random, ISymbolicExpressionGrammar grammar,
    5958      SymbolicExpressionTree parent0, SymbolicExpressionTree parent1,
    60       double internalCrossoverPointProbability, int maxTreeSize, int maxTreeHeight) {
    61       int tries = 0;
    62       while (tries++ < MAX_TRIES) {
    63         // select a random crossover point in the first parent
    64         SymbolicExpressionTreeNode crossoverPoint0;
    65         int replacedSubtreeIndex;
    66         SelectCrossoverPoint(random, parent0, internalCrossoverPointProbability, out crossoverPoint0, out replacedSubtreeIndex);
     59      double internalCrossoverPointProbability, int maxTreeSize, int maxTreeHeight, out bool success) {
     60      // select a random crossover point in the first parent
     61      SymbolicExpressionTreeNode crossoverPoint0;
     62      int replacedSubtreeIndex;
     63      SelectCrossoverPoint(random, parent0, internalCrossoverPointProbability, out crossoverPoint0, out replacedSubtreeIndex);
    6764
    68         // calculate the max size and height that the inserted branch can have
    69         int maxInsertedBranchSize = maxTreeSize - (parent0.Size - crossoverPoint0.SubTrees[replacedSubtreeIndex].GetSize());
    70         int maxInsertedBranchHeight = maxTreeHeight - GetBranchLevel(parent0.Root, crossoverPoint0);
     65      // calculate the max size and height that the inserted branch can have
     66      int maxInsertedBranchSize = maxTreeSize - (parent0.Size - crossoverPoint0.SubTrees[replacedSubtreeIndex].GetSize());
     67      int maxInsertedBranchHeight = maxTreeHeight - GetBranchLevel(parent0.Root, crossoverPoint0);
    7168
    72         var allowedBranches = from branch in IterateNodes(parent1.Root)
    73                               where branch.GetSize() < maxInsertedBranchSize
    74                               where branch.GetHeight() < maxInsertedBranchHeight
    75                               where grammar.AllowedSymbols(crossoverPoint0.Symbol, replacedSubtreeIndex).Contains(branch.Symbol)
    76                               select branch;
     69      var allowedBranches = from branch in IterateNodes(parent1.Root)
     70                            where branch.GetSize() < maxInsertedBranchSize
     71                            where branch.GetHeight() < maxInsertedBranchHeight
     72                            where grammar.GetAllowedSymbols(crossoverPoint0.Symbol, replacedSubtreeIndex).Contains(branch.Symbol)
     73                            where IsMatchingPointType(parent0, crossoverPoint0, branch)
     74                            select branch;
    7775
    78         if (allowedBranches.Count() > 0) {
    79           var selectedBranch = SelectRandomBranch(random, allowedBranches, internalCrossoverPointProbability);
     76      if (allowedBranches.Count() > 0) {
     77        var selectedBranch = SelectRandomBranch(random, allowedBranches, internalCrossoverPointProbability);
    8078
    81           // manipulate the tree of parent0 in place
    82           // replace the branch in tree0 with the selected branch from tree1
    83           crossoverPoint0.RemoveSubTree(replacedSubtreeIndex);
    84           crossoverPoint0.InsertSubTree(replacedSubtreeIndex, selectedBranch);
    85           return parent0;
    86         }
     79        // manipulate the tree of parent0 in place
     80        // replace the branch in tree0 with the selected branch from tree1
     81        crossoverPoint0.RemoveSubTree(replacedSubtreeIndex);
     82        crossoverPoint0.InsertSubTree(replacedSubtreeIndex, selectedBranch);
     83        success = true;
     84        return parent0;
    8785      }
    8886
    89       // TODO: we should have a way to track the number of failed crossover attempts
    90       // for now just return the first parent unchanged
     87      success = false;
    9188      return parent0;
     89    }
     90
     91    private static bool IsMatchingPointType(SymbolicExpressionTree tree, SymbolicExpressionTreeNode parent, SymbolicExpressionTreeNode newBranch) {
     92      var functionCalls = (from node in IterateNodes(newBranch)
     93                           let invokeNode = node as InvokeFunctionTreeNode
     94                           let argNode = node as ArgumentTreeNode
     95                           where invokeNode != null || argNode != null
     96                           let name = invokeNode != null ? invokeNode.InvokedFunctionName : "ARG" + argNode.ArgumentIndex
     97                           let argCount = invokeNode != null ? invokeNode.SubTrees.Count : 0
     98                           select new { FunctionName = name, FunctionArgumentCount = argCount }).Distinct();
     99      var definingBranch = GetDefiningBranch(tree, parent);
     100      if (definingBranch == null) return false;
     101      foreach (var functionCall in functionCalls) {
     102        if (!definingBranch.DynamicSymbols.Contains(functionCall.FunctionName) ||
     103          definingBranch.GetDynamicSymbolArgumentCount(functionCall.FunctionName) != functionCall.FunctionArgumentCount)
     104          return false;
     105      }
     106      return true;
     107    }
     108
     109    private static SymbolicExpressionTreeNode GetDefiningBranch(SymbolicExpressionTree tree, SymbolicExpressionTreeNode parent) {
     110      foreach (var treeNode in tree.Root.SubTrees) {
     111        if (IterateNodes(treeNode).Contains(parent)) return treeNode;
     112      }
     113      return null;
    92114    }
    93115
     
    95117      var crossoverPoints = from branch in IterateNodes(parent0.Root)
    96118                            where branch.SubTrees.Count > 0
     119                            where !(branch.Symbol is ProgramRootSymbol)
    97120                            from index in Enumerable.Range(0, branch.SubTrees.Count)
    98121                            let p = new { CrossoverPoint = branch, SubtreeIndex = index, IsLeaf = branch.SubTrees[index].SubTrees.Count == 0 }
     
    101124                                     where !p.IsLeaf
    102125                                     select p).ToList();
    103       // select internal crossover point or leaf
    104       if (random.NextDouble() < internalNodeProbability && internalCrossoverPoints.Count > 0) {
     126      var leafCrossoverPoints = (from p in crossoverPoints
     127                                 where p.IsLeaf
     128                                 select p).ToList();
     129      if (internalCrossoverPoints.Count == 0) {
     130        var selectedCrossoverPoint = leafCrossoverPoints[random.Next(leafCrossoverPoints.Count)];
     131        crossoverPoint = selectedCrossoverPoint.CrossoverPoint;
     132        subtreeIndex = selectedCrossoverPoint.SubtreeIndex;
     133      } else if (leafCrossoverPoints.Count == 0) {
     134        var selectedCrossoverPoint = internalCrossoverPoints[random.Next(internalCrossoverPoints.Count)];
     135        crossoverPoint = selectedCrossoverPoint.CrossoverPoint;
     136        subtreeIndex = selectedCrossoverPoint.SubtreeIndex;
     137      } else if (random.NextDouble() < internalNodeProbability && internalCrossoverPoints.Count > 0) {
     138        // select internal crossover point or leaf
    105139        var selectedCrossoverPoint = internalCrossoverPoints[random.Next(internalCrossoverPoints.Count)];
    106140        crossoverPoint = selectedCrossoverPoint.CrossoverPoint;
    107141        subtreeIndex = selectedCrossoverPoint.SubtreeIndex;
    108142      } else {
    109         var leafCrossoverPoints = (from p in crossoverPoints
    110                                    where p.IsLeaf
    111                                    select p).ToList();
    112143        var selectedCrossoverPoint = leafCrossoverPoints[random.Next(leafCrossoverPoints.Count)];
    113144        crossoverPoint = selectedCrossoverPoint.CrossoverPoint;
     
    125156                                     from branch in g
    126157                                     select branch).ToList();
    127       if (random.NextDouble() < internalNodeProbability && allowedInternalBranches.Count > 0) {
     158      var allowedLeafBranches = (from g in groupedBranches
     159                                 where g.Key == 0
     160                                 from leaf in g
     161                                 select leaf).ToList();
     162      if (allowedInternalBranches.Count == 0) {
     163        return allowedLeafBranches[random.Next(allowedLeafBranches.Count)];
     164      } else if (allowedLeafBranches.Count == 0) {
     165        return allowedInternalBranches[random.Next(allowedInternalBranches.Count)];
     166      } else if (random.NextDouble() < internalNodeProbability) {
     167        // when leaf and internal nodes are possible then choose either a leaf or internal node with internalNodeProbability
    128168        return allowedInternalBranches[random.Next(allowedInternalBranches.Count)];
    129169      } else {
    130         var allowedLeafBranches = (from g in groupedBranches
    131                                    where g.Key == 0
    132                                    from leaf in g
    133                                    select leaf).ToList();
    134170        return allowedLeafBranches[random.Next(allowedLeafBranches.Count)];
    135171      }
Note: See TracChangeset for help on using the changeset viewer.