Free cookie consent management tool by TermsFeed Policy Generator

Ignore:
Timestamp:
11/25/08 23:20:03 (15 years ago)
Author:
gkronber
Message:

fixed #392 (GP uniform- and onepoint crossover should only create one child per crossover event)

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/sources/HeuristicLab.GP/Recombination/OnePointCrossOver.cs

    r812 r815  
    3636  /// W. B. Langdon and R. Poli.  Foundations of Genetic Programming. Springer-Verlag, 2002.
    3737  /// </summary>
    38   public class OnePointCrossOver : OperatorBase {
     38  public class OnePointCrossOver : GPCrossoverBase {
     39    // internal data structure to represent crossover points
     40    private class CrossoverPoint {
     41      public IFunctionTree parent0;
     42      public IFunctionTree parent1;
     43      public int childIndex;
     44    }
    3945    public override string Description {
    4046      get {
     
    4248      }
    4349    }
    44     public OnePointCrossOver()
    45       : base() {
    46       AddVariableInfo(new VariableInfo("Random", "Pseudo random number generator", typeof(MersenneTwister), VariableKind.In));
    47       AddVariableInfo(new VariableInfo("OperatorLibrary", "The operator library containing all available operators", typeof(GPOperatorLibrary), VariableKind.In));
    48       AddVariableInfo(new VariableInfo("FunctionTree", "The tree to mutate", typeof(IFunctionTree), VariableKind.In | VariableKind.New));
    49       AddVariableInfo(new VariableInfo("TreeSize", "The size (number of nodes) of the tree", typeof(IntData), VariableKind.In | VariableKind.New));
    50       AddVariableInfo(new VariableInfo("TreeHeight", "The height of the tree", typeof(IntData), VariableKind.In | VariableKind.New));
    51     }
    5250
    53     public override IOperation Apply(IScope scope) {
    54       MersenneTwister random = GetVariableValue<MersenneTwister>("Random", scope, true);
    55       GPOperatorLibrary opLibrary = GetVariableValue<GPOperatorLibrary>("OperatorLibrary", scope, true);
    56       TreeGardener gardener = new TreeGardener(random, opLibrary);
    57 
    58       if ((scope.SubScopes.Count % 2) != 0)
    59         throw new InvalidOperationException("Number of parents is not even");
    60 
    61       int crossoverEvents = scope.SubScopes.Count / 2;
    62       for (int i = 0; i < crossoverEvents; i++) {
    63         IScope parent1 = scope.SubScopes[0];
    64         scope.RemoveSubScope(parent1);
    65         IScope parent2 = scope.SubScopes[0];
    66         scope.RemoveSubScope(parent2);
    67         IScope child0 = new Scope((i * 2).ToString());
    68         IScope child1 = new Scope((i * 2 + 1).ToString());
    69         Cross(scope, random, gardener, parent1, parent2, child0, child1);
    70         scope.AddSubScope(child0);
    71         scope.AddSubScope(child1);
    72       }
    73       return null;
    74     }
    75 
    76     private void Cross(IScope scope, MersenneTwister random, TreeGardener gardener, IScope parent1, IScope parent2, IScope child0, IScope child1) {
    77       IFunctionTree newTree0;
    78       IFunctionTree newTree1;
    79       Cross(random, gardener, parent1, parent2, out newTree0, out newTree1);
    80 
    81       child0.AddVariable(new HeuristicLab.Core.Variable(scope.TranslateName("FunctionTree"), newTree0));
    82       child0.AddVariable(new HeuristicLab.Core.Variable(scope.TranslateName("TreeSize"), new IntData(newTree0.Size)));
    83       child0.AddVariable(new HeuristicLab.Core.Variable(scope.TranslateName("TreeHeight"), new IntData(newTree0.Height)));
    84       child1.AddVariable(new HeuristicLab.Core.Variable(scope.TranslateName("FunctionTree"), newTree1));
    85       child1.AddVariable(new HeuristicLab.Core.Variable(scope.TranslateName("TreeSize"), new IntData(newTree1.Size)));
    86       child1.AddVariable(new HeuristicLab.Core.Variable(scope.TranslateName("TreeHeight"), new IntData(newTree1.Height)));
    87     }
    88 
    89 
    90     private void Cross(MersenneTwister random, TreeGardener gardener, IScope f, IScope g, out IFunctionTree child0, out IFunctionTree child1) {
    91       IFunctionTree tree0 = f.GetVariableValue<IFunctionTree>("FunctionTree", false);
    92       int tree0Height = f.GetVariableValue<IntData>("TreeHeight", false).Data;
    93       int tree0Size = f.GetVariableValue<IntData>("TreeSize", false).Data;
    94 
    95       IFunctionTree tree1 = g.GetVariableValue<IFunctionTree>("FunctionTree", false);
    96       int tree1Height = g.GetVariableValue<IntData>("TreeHeight", false).Data;
    97       int tree1Size = g.GetVariableValue<IntData>("TreeSize", false).Data;
    98 
    99       List<CrossoverPoint> allowedCrossOverPoints = GetCrossOverPoints(gardener, tree0, tree1);
     51    internal override IFunctionTree Cross(TreeGardener gardener, MersenneTwister random, IFunctionTree tree0, IFunctionTree tree1) {
     52      List<CrossoverPoint> allowedCrossOverPoints = new List<CrossoverPoint>();
     53      GetCrossOverPoints(gardener, tree0, tree1, allowedCrossOverPoints);
    10054      if (allowedCrossOverPoints.Count > 0) {
    10155        CrossoverPoint crossOverPoint = allowedCrossOverPoints[random.Next(allowedCrossOverPoints.Count)];
    10256        IFunctionTree parent0 = crossOverPoint.parent0;
    103         IFunctionTree parent1 = crossOverPoint.parent1;
    104         IFunctionTree branch0 = crossOverPoint.parent0.SubTrees[crossOverPoint.childIndex];
    10557        IFunctionTree branch1 = crossOverPoint.parent1.SubTrees[crossOverPoint.childIndex];
    10658        parent0.RemoveSubTree(crossOverPoint.childIndex);
    107         parent1.RemoveSubTree(crossOverPoint.childIndex);
    10859        parent0.InsertSubTree(crossOverPoint.childIndex, branch1);
    109         parent1.InsertSubTree(crossOverPoint.childIndex, branch0);
    11060      }
    111 
    112       child0 = tree0;
    113       child1 = tree1;
    114     }
    115     class CrossoverPoint {
    116       public IFunctionTree parent0;
    117       public IFunctionTree parent1;
    118       public int childIndex;
     61      return tree0;
    11962    }
    12063
    121     private List<CrossoverPoint> GetCrossOverPoints(TreeGardener gardener, IFunctionTree branch0, IFunctionTree branch1) {
    122       List<CrossoverPoint> results = new List<CrossoverPoint>();
    123       if (branch0.SubTrees.Count != branch1.SubTrees.Count) return results;
     64    private void GetCrossOverPoints(TreeGardener gardener, IFunctionTree branch0, IFunctionTree branch1, List<CrossoverPoint> crossoverPoints) {
     65      if (branch0.SubTrees.Count != branch1.SubTrees.Count) return;
    12466
    12567      for (int i = 0; i < branch0.SubTrees.Count; i++) {
    126         // if the branches fit to the parent
    127         if (gardener.GetAllowedSubFunctions(branch0.Function, i).Contains(branch1.SubTrees[i].Function) &&
    128           gardener.GetAllowedSubFunctions(branch1.Function, i).Contains(branch0.SubTrees[i].Function)) {
     68        // if the current branch can be attached as a sub-tree to branch0
     69        if (gardener.GetAllowedSubFunctions(branch0.Function, i).Contains(branch1.SubTrees[i].Function)) {
    12970          CrossoverPoint p = new CrossoverPoint();
    13071          p.childIndex = i;
    13172          p.parent0 = branch0;
    13273          p.parent1 = branch1;
    133           results.Add(p);
     74          crossoverPoints.Add(p);
    13475        }
    135         results.AddRange(GetCrossOverPoints(gardener, branch0.SubTrees[i], branch1.SubTrees[i]));
     76        GetCrossOverPoints(gardener, branch0.SubTrees[i], branch1.SubTrees[i], crossoverPoints);
    13677      }
    137       return results;
    13878    }
    13979  }
Note: See TracChangeset for help on using the changeset viewer.