Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.Encodings.SymbolicExpressionTree/3.3/Crossovers/SizeFairCrossOver.cs @ 3219

Last change on this file since 3219 was 3219, checked in by gkronber, 14 years ago

Worked on SymbolicTreeEncoding plugin. #937 (Data types and operators for symbolic expression tree encoding)

File size: 6.8 KB
RevLine 
[645]1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2008 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
4 *
5 * This file is part of HeuristicLab.
6 *
7 * HeuristicLab is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * HeuristicLab is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
19 */
20#endregion
21
22using System.Collections.Generic;
23using System.Linq;
24using HeuristicLab.Core;
[2212]25using HeuristicLab.GP.Interfaces;
[645]26using HeuristicLab.Random;
27
[3219]28namespace HeuristicLab.Encodings.SymbolicExpressionTree {
[645]29  /// <summary>
30  /// Implementation of a size fair crossover operator as described in:
31  /// William B. Langdon
32  /// Size Fair and Homologous Tree Genetic Programming Crossovers,
33  /// Genetic Programming and Evolvable Machines, Vol. 1, Number 1/2, pp. 95-119, April 2000
34  /// </summary>
[835]35  public class SizeFairCrossOver : SizeConstrictedGPCrossoverBase {
[1197]36    private int MaxRecombinationTries { get { return 20; } }
[835]37    // private data structure for crossover points
38    protected class CrossoverPoint {
39      public IFunctionTree tree;
40      public int branchSize;
41      public List<int> trail;
[645]42    }
43
[1286]44    internal override IFunctionTree Cross(TreeGardener gardener, IRandom random, IFunctionTree tree0, IFunctionTree tree1, int maxTreeSize, int maxTreeHeight) {
[833]45      int tries = 0;
46      IFunctionTree insertedBranch = null;
[835]47      IFunctionTree parent = null;
[833]48      int removedBranchIndex = 0;
49      do {
50        // select a random suboperator of the 'receiving' tree
[835]51        while (parent == null) parent = gardener.GetRandomParentNode(tree0);
52        removedBranchIndex = random.Next(parent.SubTrees.Count);
[1286]53        insertedBranch = GetReplacementBranch((MersenneTwister)random, gardener, tree0, parent, removedBranchIndex, tree1, maxTreeSize, maxTreeHeight);
[1197]54      } while (insertedBranch == null && tries++ < MaxRecombinationTries);
[645]55
[835]56      if (insertedBranch != null) {
[814]57        // replace the branch below the crossoverpoint with the selected branch from root1
[835]58        parent.RemoveSubTree(removedBranchIndex);
59        parent.InsertSubTree(removedBranchIndex, insertedBranch);
[814]60      }
[833]61      return tree0;
[645]62    }
63
[835]64    private IFunctionTree GetReplacementBranch(MersenneTwister random, TreeGardener gardener, IFunctionTree intoTree, IFunctionTree parent, int replacedBranchIndex, IFunctionTree fromTree, int maxTreeSize, int maxTreeHeight) {
[2202]65      IList<IFunction> allowedFunctions = new List<IFunction>(gardener.GetAllowedSubFunctions(parent.Function, replacedBranchIndex));
[2210]66      int removedBranchSize = parent.SubTrees[replacedBranchIndex].GetSize();
67      int maxBranchSize = maxTreeSize - (intoTree.GetSize() - removedBranchSize);
[835]68      int maxBranchHeight = maxTreeHeight - gardener.GetBranchLevel(intoTree, parent);  // returns 1 if intoTree==parent and 2 if parent is a child of intoTree
69      List<int> replacedTrail = GetTrail(intoTree, parent);
70      replacedTrail.Add(replacedBranchIndex);
[645]71
[835]72      List<CrossoverPoint> shorterBranches = new List<CrossoverPoint>();
73      List<CrossoverPoint> longerBranches = new List<CrossoverPoint>();
74      List<CrossoverPoint> equalLengthBranches = new List<CrossoverPoint>();
[645]75
[835]76      FindPossibleBranches(fromTree, allowedFunctions, maxBranchSize, maxBranchHeight, removedBranchSize, shorterBranches, equalLengthBranches, longerBranches, new List<int>());
77
78      if (shorterBranches.Count > 0 && longerBranches.Count > 0) {
79        double pEqualLength = equalLengthBranches.Count > 0 ? 1.0 / removedBranchSize : 0.0;
[1212]80        double pLonger;
[2210]81        if (parent.GetSize() == maxTreeSize) {
[1212]82          pLonger = 0.0;
83        } else {
84          pLonger = (1.0 - pEqualLength) / (longerBranches.Count * (1.0 + longerBranches.Average(p => p.branchSize) / shorterBranches.Average(p => p.branchSize)));
85        }
[645]86        double pShorter = (1.0 - pEqualLength - pLonger);
87
88        double r = random.NextDouble();
[835]89        if (r < pLonger) {
90          return SelectReplacement(random, replacedTrail, longerBranches);
91        } else if (r < pLonger + pShorter) {
92          return SelectReplacement(random, replacedTrail, shorterBranches);
[645]93        } else {
[835]94          return SelectReplacement(random, replacedTrail, equalLengthBranches);
[645]95        }
[835]96      } else if (equalLengthBranches.Count > 0) {
97        return SelectReplacement(random, replacedTrail, equalLengthBranches);
98      } else {
99        return null;
[645]100      }
101    }
[835]102
103    protected virtual IFunctionTree SelectReplacement(MersenneTwister random, List<int> replacedTrail, List<CrossoverPoint> crossoverPoints) {
104      return crossoverPoints[random.Next(crossoverPoints.Count)].tree;
105    }
106
107    private void FindPossibleBranches(IFunctionTree tree, IList<IFunction> allowedFunctions, int maxBranchSize, int maxBranchHeight, int removedBranchSize,
108      List<CrossoverPoint> shorterBranches, List<CrossoverPoint> equalLengthBranches, List<CrossoverPoint> longerBranches, List<int> trail) {
[2210]109      int treeSize = tree.GetSize();
110      if (allowedFunctions.Contains(tree.Function) && treeSize <= maxBranchSize && tree.GetHeight() <= maxBranchHeight) {
[835]111        CrossoverPoint p = new CrossoverPoint();
112        p.branchSize = treeSize;
113        p.tree = tree;
114        p.trail = new List<int>(trail);
115        if (treeSize < removedBranchSize) shorterBranches.Add(p);
116        else if (treeSize > removedBranchSize) longerBranches.Add(p);
117        else equalLengthBranches.Add(p);
118      }
119      for (int i = 0; i < tree.SubTrees.Count; i++) {
120        trail.Add(i);
121        FindPossibleBranches(tree.SubTrees[i], allowedFunctions, maxBranchSize, maxBranchHeight, removedBranchSize, shorterBranches, equalLengthBranches, longerBranches, trail);
122        trail.RemoveAt(trail.Count - 1);
123      }
124    }
125
126    private List<int> GetTrail(IFunctionTree root, IFunctionTree branch) {
127      List<int> trail = new List<int>();
128      GetTrail(root, branch, trail);
129      trail.Reverse();
130      trail.RemoveAt(trail.Count - 1);
131      return trail;
132    }
133    private void GetTrail(IFunctionTree root, IFunctionTree branch, List<int> trail) {
134      if (root == branch) {
135        trail.Add(-1); // add flag that there was a match
136        return;
137      }
138
139      for (int i = 0; i < root.SubTrees.Count; i++) {
140        GetTrail(root.SubTrees[i], branch, trail);
[1197]141        if (trail.Count > 0) {
[835]142          trail.Add(i);
143          return;
144        }
145      }
146    }
[645]147  }
148}
Note: See TracBrowser for help on using the repository browser.