Free cookie consent management tool by TermsFeed Policy Generator

source: branches/3040_VectorBasedGP/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/SymbolicExpressionTreeNode.cs @ 17604

Last change on this file since 17604 was 17604, checked in by pfleck, 4 years ago

#3040 Stores the datatype of a tree node (e.g. variable nodes) in the tree itself for the interpreter to derive the datatypes for subtrees. This way, the interpreter (and simplifier) do not need an actual dataset to figure out datatypes for subtrees.

File size: 7.4 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 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.Common;
25using HeuristicLab.Core;
26using HEAL.Attic;
27
28namespace HeuristicLab.Encodings.SymbolicExpressionTreeEncoding {
29  [StorableType("E3549A82-D4C5-4AEC-A44C-D3205A618A21")]
30  public class SymbolicExpressionTreeNode : DeepCloneable, ISymbolicExpressionTreeNode {
31    [Storable]
32    private IList<ISymbolicExpressionTreeNode> subtrees;
33    [Storable]
34    private ISymbol symbol;
35
36    // cached values to prevent unnecessary tree iterations
37    private ushort length;
38    private ushort depth;
39
40    public ISymbol Symbol {
41      get { return symbol; }
42      protected set { symbol = value; }
43    }
44
45    [Storable]
46    private ISymbolicExpressionTreeNode parent;
47    public ISymbolicExpressionTreeNode Parent {
48      get { return parent; }
49      set { parent = value; }
50    }
51
52    [StorableConstructor]
53    protected SymbolicExpressionTreeNode(StorableConstructorFlag _) { }
54    protected SymbolicExpressionTreeNode(SymbolicExpressionTreeNode original, Cloner cloner)
55      : base(original, cloner) {
56      symbol = original.symbol; // symbols are reused
57      length = original.length;
58      depth = original.depth;
59      if (original.subtrees != null) {
60        subtrees = new List<ISymbolicExpressionTreeNode>(original.subtrees.Count);
61        foreach (var subtree in original.subtrees) {
62          var clonedSubtree = cloner.Clone(subtree);
63          subtrees.Add(clonedSubtree);
64          clonedSubtree.Parent = this;
65        }
66      }
67    }
68    public override IDeepCloneable Clone(Cloner cloner) {
69      return new SymbolicExpressionTreeNode(this, cloner);
70    }
71
72    internal SymbolicExpressionTreeNode()
73      : base() {
74      // don't allocate subtrees list here!
75      // because we don't want to allocate it in terminal nodes
76    }
77
78    public SymbolicExpressionTreeNode(ISymbol symbol)
79      : base() {
80      subtrees = new List<ISymbolicExpressionTreeNode>(3);
81      this.symbol = symbol;
82    }
83
84
85    [StorableHook(HookType.AfterDeserialization)]
86    private void AfterDeserialization() {
87      if (subtrees != null) {
88        foreach (var subtree in subtrees)
89          if (subtree.Parent == null)
90            subtree.Parent = this;
91      }
92    }
93
94    public virtual bool HasLocalParameters {
95      get { return false; }
96    }
97
98    public virtual Type DataType {
99      get { return null; }
100    }
101
102    public virtual IEnumerable<ISymbolicExpressionTreeNode> Subtrees {
103      get { return subtrees; }
104    }
105
106    public virtual ISymbolicExpressionTreeGrammar Grammar {
107      get { return parent.Grammar; }
108    }
109
110    public int GetLength() {
111      if (length > 0) return length;
112      else {
113        ushort l = 1;
114        if (subtrees != null) {
115          for (int i = 0; i < subtrees.Count; i++) {
116            checked { l += (ushort)subtrees[i].GetLength(); }
117          }
118        }
119        length = l;
120        return length;
121      }
122    }
123
124    public int GetDepth() {
125      if (depth > 0) return depth;
126      else {
127        ushort d = 0;
128        if (subtrees != null) {
129          for (int i = 0; i < subtrees.Count; i++) d = Math.Max(d, (ushort)subtrees[i].GetDepth());
130        }
131        d++;
132        depth = d;
133        return depth;
134      }
135    }
136
137    public int GetBranchLevel(ISymbolicExpressionTreeNode child) {
138      return GetBranchLevel(this, child);
139    }
140
141    private static int GetBranchLevel(ISymbolicExpressionTreeNode root, ISymbolicExpressionTreeNode point) {
142      if (root == point)
143        return 0;
144      foreach (var subtree in root.Subtrees) {
145        int branchLevel = GetBranchLevel(subtree, point);
146        if (branchLevel < int.MaxValue)
147          return 1 + branchLevel;
148      }
149      return int.MaxValue;
150    }
151
152    public virtual void ResetLocalParameters(IRandom random) { }
153    public virtual void ShakeLocalParameters(IRandom random, double shakingFactor) { }
154
155    public int SubtreeCount {
156      get {
157        if (subtrees == null) return 0;
158        return subtrees.Count;
159      }
160    }
161
162    public virtual ISymbolicExpressionTreeNode GetSubtree(int index) {
163      return subtrees[index];
164    }
165    public virtual int IndexOfSubtree(ISymbolicExpressionTreeNode tree) {
166      return subtrees.IndexOf(tree);
167    }
168    public virtual void AddSubtree(ISymbolicExpressionTreeNode tree) {
169      subtrees.Add(tree);
170      tree.Parent = this;
171      ResetCachedValues();
172    }
173    public virtual void InsertSubtree(int index, ISymbolicExpressionTreeNode tree) {
174      subtrees.Insert(index, tree);
175      tree.Parent = this;
176      ResetCachedValues();
177    }
178    public virtual void RemoveSubtree(int index) {
179      subtrees[index].Parent = null;
180      subtrees.RemoveAt(index);
181      ResetCachedValues();
182    }
183
184    public IEnumerable<ISymbolicExpressionTreeNode> IterateNodesBreadth() {
185      var list = new List<ISymbolicExpressionTreeNode>(GetLength()) { this };
186      int i = 0;
187      while (i != list.Count) {
188        for (int j = 0; j != list[i].SubtreeCount; ++j)
189          list.Add(list[i].GetSubtree(j));
190        ++i;
191      }
192      return list;
193    }
194
195    public IEnumerable<ISymbolicExpressionTreeNode> IterateNodesPrefix() {
196      List<ISymbolicExpressionTreeNode> list = new List<ISymbolicExpressionTreeNode>();
197      ForEachNodePrefix((n) => list.Add(n));
198      return list;
199    }
200
201    public void ForEachNodePrefix(Action<ISymbolicExpressionTreeNode> a) {
202      a(this);
203      if (subtrees != null) {
204        //avoid linq to reduce memory pressure
205        for (int i = 0; i < subtrees.Count; i++) {
206          subtrees[i].ForEachNodePrefix(a);
207        }
208      }
209    }
210
211    public IEnumerable<ISymbolicExpressionTreeNode> IterateNodesPostfix() {
212      List<ISymbolicExpressionTreeNode> list = new List<ISymbolicExpressionTreeNode>();
213      ForEachNodePostfix((n) => list.Add(n));
214      return list;
215    }
216
217    public void ForEachNodePostfix(Action<ISymbolicExpressionTreeNode> a) {
218      if (subtrees != null) {
219        //avoid linq to reduce memory pressure
220        for (int i = 0; i < subtrees.Count; i++) {
221          subtrees[i].ForEachNodePostfix(a);
222        }
223      }
224      a(this);
225    }
226
227    public override string ToString() {
228      if (Symbol != null) return Symbol.Name;
229      return "SymbolicExpressionTreeNode";
230    }
231
232    private void ResetCachedValues() {
233      length = 0; depth = 0;
234      SymbolicExpressionTreeNode parentNode = parent as SymbolicExpressionTreeNode;
235      if (parentNode != null) parentNode.ResetCachedValues();
236    }
237  }
238}
Note: See TracBrowser for help on using the repository browser.