Free cookie consent management tool by TermsFeed Policy Generator

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

Last change on this file since 8557 was 8557, checked in by bburlacu, 12 years ago

#1772: Introduced base class and interface for tracing operators. Introduced SymbolicExpressionTreeNodeComparer interface to be implemented by node matching operators. Fixed bug in the TracingSymbolicExpressionTreeManipulator where nodes modified by the Full- and OnePoint tree shakers were not correctly detected. The SymbolicExpressionTreeNodeSimilarityComparer is now injected in the tracing genetic operators as a parameter.

File size: 5.6 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.EvolutionaryTracking;
28using HeuristicLab.Parameters;
29using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
30
31namespace HeuristicLab.Encodings.SymbolicExpressionTreeEncoding {
32  /// <summary>
33  /// A base class for operators that manipulate real-valued vectors.
34  /// </summary>
35  [Item("TracingSymbolicExpressionTreeManipulator", "A base class for operators that manipulate symbolic expression trees.")]
36  [StorableClass]
37  public abstract class TracingSymbolicExpressionTreeManipulator : TracingSymbolicExpressionTreeOperator, ISymbolicExpressionTreeManipulator {
38    private const string SymbolicExpressionTreeParameterName = "SymbolicExpressionTree";
39
40    #region Parameter Properties
41    public ILookupParameter<ISymbolicExpressionTree> SymbolicExpressionTreeParameter {
42      get { return (ILookupParameter<ISymbolicExpressionTree>)Parameters[SymbolicExpressionTreeParameterName]; }
43    }
44    #endregion
45
46    #region Properties
47    public ISymbolicExpressionTree SymbolicExpressionTree {
48      get { return SymbolicExpressionTreeParameter.ActualValue; }
49    }
50    #endregion
51
52    [StorableConstructor]
53    protected TracingSymbolicExpressionTreeManipulator(bool deserializing) : base(deserializing) { }
54    protected TracingSymbolicExpressionTreeManipulator(TracingSymbolicExpressionTreeManipulator original, Cloner cloner) : base(original, cloner) { }
55    public TracingSymbolicExpressionTreeManipulator()
56      : base() {
57      Parameters.Add(new LookupParameter<ISymbolicExpressionTree>(SymbolicExpressionTreeParameterName, "The symbolic expression tree on which the operator should be applied."));
58    }
59
60    public sealed override IOperation Apply() {
61      ISymbolicExpressionTree tree = SymbolicExpressionTreeParameter.ActualValue;
62
63      AddTracingVariablesToGlobalScope();
64
65      /* The following block needs to be explained in more detail;
66       * If the tree was already affected by crossover (before mutation), then:
67       * - it will already be contained in the GlobalTraceMap
68       * - In order to preserve information, a clone of the tree is created
69       * - The clone represents the intermediate stage of the tree, before mutation is applied
70       * - The clone therefore represents the child after crossover so GlobalTraceMap[clone] will get tree's parents
71       *   and GlobalFragmentMap[clone] will get the subtree from clone that represents the cloned fragment
72       * - After tree is mutated, we set GlobalTraceMap[tree] = clone and GlobalFragmentMap[tree] = modified node from tree
73       */
74      ISymbolicExpressionTreeNode fragment;
75      if (GlobalTraceMap.ContainsKey(tree)) {
76        var clone = (IItem)tree.Clone(); // create clone of tree
77        GlobalTraceMap[clone] = GlobalTraceMap[tree]; // clone gets parents of tree
78        GlobalTraceMap[tree] = new ItemList<IItem> { clone }; // tree gets clone as parent
79        fragment = ((GenericWrapper<ISymbolicExpressionTreeNode>)GlobalFragmentMap[tree]).Content;
80        int index = tree.IterateNodesBreadth().ToList().IndexOf(fragment); // returns -1 if fragment is not present in tree
81        GlobalFragmentMap[clone] = new GenericWrapper<ISymbolicExpressionTreeNode>(index == -1 ? null : ((ISymbolicExpressionTree)clone).IterateNodesBreadth().ElementAt(index));
82      } else {
83        GlobalTraceMap[tree] = new ItemList<IItem> { GlobalCloneMap[tree] };
84      }
85
86      var original = GlobalCloneMap[tree];
87      var nodes0 = ((ISymbolicExpressionTree)original).IterateNodesBreadth().ToList();
88
89      // perform mutation
90      Manipulate(RandomParameter.ActualValue, tree);
91
92      var nodes1 = tree.IterateNodesBreadth().ToList();
93
94      int min = Math.Min(nodes0.Count, nodes1.Count);
95      // some tree manipulators only change local parameters while the actual node stays the same
96      // consequently, we need a stronger comparison than ReferenceEquals
97      var comp = SymbolicExpressionTreeNodeComparer;
98      if (comp == null)
99        throw new Exception(Name + ": Could not get SymbolicExpressionTreeNodeComparerParameter!");
100      var mismatches = new List<int>();
101      for (int i = 0; i != min; ++i) {
102        if (!comp.Equals(nodes0[i], nodes1[i])) {
103          mismatches.Add(i);
104        }
105      }
106      if (mismatches.Count == 0) // should never happen
107        fragment = null;
108      else
109        fragment = mismatches.Count > 1 ? nodes1[mismatches[0]].Parent : nodes1[mismatches[0]];
110      GlobalFragmentMap[tree] = new GenericWrapper<ISymbolicExpressionTreeNode>(fragment);
111      return base.Apply();
112    }
113
114    protected abstract void Manipulate(IRandom random, ISymbolicExpressionTree symbolicExpressionTree);
115  }
116}
Note: See TracBrowser for help on using the repository browser.