Free cookie consent management tool by TermsFeed Policy Generator

source: branches/HeuristicLab.EvolutionaryTracking/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Manipulators/TracingSymbolicExpressionTreeManipulator.cs @ 13475

Last change on this file since 13475 was 9835, checked in by bburlacu, 11 years ago

#1772: Merged remaining trunk changes into the EvolutionaryTracking branch.

File size: 6.2 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2012 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 System.Linq;
25using HeuristicLab.Common;
26using HeuristicLab.Core;
27using HeuristicLab.Parameters;
28using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
29
30namespace HeuristicLab.Encodings.SymbolicExpressionTreeEncoding {
31  /// <summary>
32  /// A base class for operators that manipulate real-valued vectors.
33  /// </summary>
34  [Item("TracingSymbolicExpressionTreeManipulator", "A base class for operators that manipulate symbolic expression trees.")]
35  [StorableClass]
36  public abstract class TracingSymbolicExpressionTreeManipulator : TracingSymbolicExpressionTreeOperator, ISymbolicExpressionTreeManipulator {
37    private const string SymbolicExpressionTreeParameterName = "SymbolicExpressionTree";
38    [Storable]
39    private readonly Dictionary<Type, byte> manipulationTypes = new Dictionary<Type, byte>();
40
41    #region Parameter Properties
42    public ILookupParameter<ISymbolicExpressionTree> SymbolicExpressionTreeParameter {
43      get { return (ILookupParameter<ISymbolicExpressionTree>)Parameters[SymbolicExpressionTreeParameterName]; }
44    }
45    #endregion
46
47    #region Properties
48    public ISymbolicExpressionTree SymbolicExpressionTree {
49      get { return SymbolicExpressionTreeParameter.ActualValue; }
50    }
51    #endregion
52
53    [StorableHook(HookType.AfterDeserialization)]
54    private void AfterDeserialization() {
55
56    }
57
58    [StorableConstructor]
59    protected TracingSymbolicExpressionTreeManipulator(bool deserializing) : base(deserializing) { }
60    protected TracingSymbolicExpressionTreeManipulator(TracingSymbolicExpressionTreeManipulator original, Cloner cloner)
61      : base(original, cloner) {
62      this.manipulationTypes = new Dictionary<Type, byte>(original.manipulationTypes);
63    }
64    public TracingSymbolicExpressionTreeManipulator()
65      : base() {
66      Parameters.Add(new LookupParameter<ISymbolicExpressionTree>(SymbolicExpressionTreeParameterName, "The symbolic expression tree on which the operator should be applied."));
67
68      manipulationTypes.Add(typeof(FullTreeShaker), ManipulationType.FullTreeShaker);
69      manipulationTypes.Add(typeof(OnePointShaker), ManipulationType.OnePointShaker);
70      manipulationTypes.Add(typeof(ChangeNodeTypeManipulation), ManipulationType.ChangeNodeTypeManipulation);
71      manipulationTypes.Add(typeof(ReplaceBranchManipulation), ManipulationType.ReplaceBranchManipulation);
72      manipulationTypes.Add(typeof(RemoveBranchManipulation), ManipulationType.RemoveBranchManipulation);
73    }
74
75    public sealed override IOperation Apply() {
76      ISymbolicExpressionTree tree = SymbolicExpressionTreeParameter.ActualValue;
77      AddTracingVariablesToGlobalScope();
78
79      /* The following block needs to be explained in more detail;
80       * If the tree was already affected by crossover (before mutation), then:
81       * - it will already be contained in the GlobalTraceMap
82       * - In order to preserve information, a clone of the tree is created
83       * - The clone represents the intermediate stage of the tree, before mutation is applied
84       * - The clone therefore represents the child after crossover so GlobalTraceMap[clone] will get tree's parents
85       *   and GlobalFragmentMap[clone] will get the subtree from clone that represents the cloned fragment
86       * - After tree is mutated, we set GlobalTraceMap[tree] = clone and GlobalFragmentMap[tree] = modified node from tree
87       */
88      Fragment fragment = null;
89      if (GlobalTraceMap.ContainsKey(tree)) {
90        var clone = (IItem)tree.Clone();
91        GlobalCloneMap[clone] = GlobalCloneMap[tree];
92        GlobalCloneMap[tree] = clone;
93        GlobalTraceMap[clone] = GlobalTraceMap[tree]; // clone gets parents of tree
94        GlobalTraceMap[tree] = new ItemList<IItem> { clone }; // tree gets clone as parent
95        fragment = (Fragment)GlobalFragmentMap[tree];
96        int index = tree.IterateNodesBreadth().ToList().IndexOf(fragment.Root); // returns -1 if fragment is not present in tree (can happen if fragment is null)
97        ISymbolicExpressionTreeNode fragmentRoot = index == -1 ? null : ((ISymbolicExpressionTree)clone).IterateNodesBreadth().ElementAt(index);
98        GlobalFragmentMap[clone] = new Fragment { Root = fragmentRoot };
99      } else {
100        GlobalTraceMap[tree] = new ItemList<IItem> { GlobalCloneMap[tree] };
101      }
102      var clonedTree = (ISymbolicExpressionTree)tree.Clone();
103      var nodes0 = clonedTree.IterateNodesBreadth().ToList();
104      Manipulate(RandomParameter.ActualValue, tree);
105      var nodes1 = tree.IterateNodesBreadth().ToList();
106
107      var comparer = SymbolicExpressionTreeNodeComparer;
108      int min = Math.Min(nodes0.Count, nodes1.Count);
109      int i = 0; while (i != min && comparer.Equals(nodes0[i], nodes1[i])) ++i;
110      fragment = new Fragment { Root = i == min ? null : nodes1[i], Index = i };
111      GlobalFragmentMap[tree] = fragment;
112      return base.Apply();
113    }
114
115    protected abstract void Manipulate(IRandom random, ISymbolicExpressionTree symbolicExpressionTree);
116
117    private struct ManipulationType {
118      public const byte FullTreeShaker = 1;
119      public const byte OnePointShaker = 2;
120      public const byte ChangeNodeTypeManipulation = 3;
121      public const byte ReplaceBranchManipulation = 4;
122      public const byte RemoveBranchManipulation = 5;
123    }
124  }
125}
Note: See TracBrowser for help on using the repository browser.