Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.GP.Operators/3.3/Manipulation/SubstituteSubTreeManipulation.cs @ 2222

Last change on this file since 2222 was 2222, checked in by gkronber, 15 years ago

Merged changes from GP-refactoring branch back into the trunk #713.

File size: 3.8 KB
Line 
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;
23using System.Collections.Generic;
24using HeuristicLab.Core;
25using HeuristicLab.Random;
26using System.Diagnostics;
27using HeuristicLab.GP.Interfaces;
28
29namespace HeuristicLab.GP.Operators {
30  public class SubstituteSubTreeManipulation : GPManipulatorBase {
31
32    public override string Description {
33      get { return "Selects a random node of the tree and replaces it with randomly initialized subtree."; }
34    }
35
36    public SubstituteSubTreeManipulation()
37      : base() {
38    }
39
40    internal override IOperation Manipulate(MersenneTwister random, IGeneticProgrammingModel gpModel, FunctionLibrary library, int maxTreeSize, int maxTreeHeight, IScope scope) {
41      TreeGardener gardener = new TreeGardener(random, library);
42      IFunctionTree parent = gardener.GetRandomParentNode(gpModel.FunctionTree);
43      if (parent == null) {
44        // parent == null means we should subsitute the whole tree
45        // => create a new random tree
46        IFunctionTree newTree = gardener.CreateRandomTree(gardener.AllFunctions, maxTreeSize, maxTreeHeight);
47        Debug.Assert(gardener.IsValidTree(newTree));
48
49        gpModel.FunctionTree = newTree;
50        // return a CompositeOperation that randomly initializes the new tree
51        return Util.CreateInitializationOperation(TreeGardener.GetAllSubTrees(newTree), scope);
52      } else {
53        // determine a random child of the parent to be replaced
54        int childIndex = random.Next(parent.SubTrees.Count);
55        // get the list of allowed functions for the new sub-tree
56        ICollection<IFunction> allowedFunctions = gardener.GetAllowedSubFunctions(parent.Function, childIndex);
57        if (allowedFunctions.Count == 0) {
58          // don't change anything
59          // this shouldn't happen
60          throw new InvalidProgramException();
61        }
62
63        // calculate the maximum size and height of the new sub-tree based on the location where
64        // it will be inserted
65        int parentLevel = gardener.GetBranchLevel(gpModel.FunctionTree, parent);
66        int maxSubTreeHeight = maxTreeHeight - parentLevel;
67        int maxSubTreeSize = maxTreeSize - (gpModel.Size - parent.SubTrees[childIndex].GetSize());
68
69        // create a random function tree
70        IFunctionTree newTree = gardener.CreateRandomTree(allowedFunctions, maxSubTreeSize, maxSubTreeHeight);
71        parent.RemoveSubTree(childIndex);
72        parent.InsertSubTree(childIndex, newTree);
73
74        Debug.Assert(gardener.IsValidTree(gpModel.FunctionTree));
75        // update the values of treeSize and treeHeight
76        gpModel.Size = gpModel.FunctionTree.GetSize();
77        gpModel.Height = gpModel.FunctionTree.GetHeight();
78        // the root hasn't changed so we don't need to update
79        // return a CompositeOperation that randomly initializes all nodes of the new subtree
80        return Util.CreateInitializationOperation(TreeGardener.GetAllSubTrees(newTree), scope);
81      }
82    }
83  }
84}
Note: See TracBrowser for help on using the repository browser.