Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.3/SymbolicExpressionTreeNode.cs @ 3988

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

Added caching of tree size and height values and changed postfix and prefix iteration methods in SymbolicExpressionTreeNodes. #938

File size: 6.1 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2010 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.Linq;
24using System.Collections.Generic;
25using System.Text;
26using HeuristicLab.Common;
27using HeuristicLab.Core;
28using System.Xml;
29using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
30using HeuristicLab.Data;
31using System.Diagnostics;
32using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.Symbols;
33
34namespace HeuristicLab.Encodings.SymbolicExpressionTreeEncoding {
35  [StorableClass]
36  public class SymbolicExpressionTreeNode : ICloneable {
37    [Storable]
38    private IList<SymbolicExpressionTreeNode> subTrees;
39    [Storable]
40    private Symbol symbol;
41
42    // cached values to prevent unnecessary tree iterations
43    private short size;
44    private short height;
45    private List<SymbolicExpressionTreeNode> prefixForm;
46    private List<SymbolicExpressionTreeNode> postfixForm;
47
48    public Symbol Symbol {
49      get { return symbol; }
50      protected set { symbol = value; }
51    }
52
53    // parent relation is not persisted or cloned (will be set on AddSubtree or RemoveSubtree)
54    private SymbolicExpressionTreeNode parent;
55    internal SymbolicExpressionTreeNode Parent {
56      get { return parent; }
57      set { parent = value; }
58    }
59
60    public SymbolicExpressionTreeNode() {
61      // don't allocate subtrees list here!
62      // because we don't want to allocate it in terminal nodes
63    }
64
65    public SymbolicExpressionTreeNode(Symbol symbol) {
66      subTrees = new List<SymbolicExpressionTreeNode>();
67      this.symbol = symbol;
68    }
69
70    // copy constructor
71    protected SymbolicExpressionTreeNode(SymbolicExpressionTreeNode original) {
72      symbol = original.symbol;
73      subTrees = new List<SymbolicExpressionTreeNode>(original.SubTrees.Count);
74      foreach (var subtree in original.SubTrees) {
75        AddSubTree((SymbolicExpressionTreeNode)subtree.Clone());
76      }
77    }
78
79    [StorableHook(HookType.AfterDeserialization)]
80    private void AfterDeserializationHook() {
81      foreach (var subtree in SubTrees) {
82        subtree.Parent = this;
83      }
84    }
85
86    public virtual bool HasLocalParameters {
87      get { return false; }
88    }
89
90    public virtual IList<SymbolicExpressionTreeNode> SubTrees {
91      get { return subTrees; }
92    }
93
94    internal virtual ISymbolicExpressionGrammar Grammar {
95      get { return parent.Grammar; }
96      set { throw new NotSupportedException("Grammar can be set only for SymbolicExpressionTreeTopLevelNodes."); }
97    }
98
99    public int GetSize() {
100      if (size > 0) return size;
101      else {
102        size = 1;
103        for (int i = 0; i < SubTrees.Count; i++) size += (short)SubTrees[i].GetSize();
104        return size;
105      }
106    }
107
108    public int GetHeight() {
109      if (height > 0) return height;
110      else {
111        for (int i = 0; i < SubTrees.Count; i++) height = Math.Max(height, (short)SubTrees[i].GetHeight());
112        height++;
113        return height;
114      }
115    }
116
117    public virtual void ResetLocalParameters(IRandom random) { }
118    public virtual void ShakeLocalParameters(IRandom random, double shakingFactor) { }
119
120    public virtual void AddSubTree(SymbolicExpressionTreeNode tree) {
121      subTrees.Add(tree);
122      tree.Parent = this;
123      ResetCachedValues();
124    }
125
126    public virtual void InsertSubTree(int index, SymbolicExpressionTreeNode tree) {
127      subTrees.Insert(index, tree);
128      tree.Parent = this;
129      ResetCachedValues();
130    }
131
132    public virtual void RemoveSubTree(int index) {
133      subTrees[index].Parent = null;
134      subTrees.RemoveAt(index);
135      ResetCachedValues();
136    }
137
138    public IEnumerable<SymbolicExpressionTreeNode> IterateNodesPrefix() {
139      if (prefixForm == null) {
140        prefixForm = new List<SymbolicExpressionTreeNode>(200);
141        ForEachNodePrefix(x => prefixForm.Add(x));
142      }
143      return prefixForm;
144    }
145
146    private void ForEachNodePrefix(Action<SymbolicExpressionTreeNode> a) {
147      a(this);
148      for (int i = 0; i < SubTrees.Count; i++) {
149        SubTrees[i].ForEachNodePrefix(a);
150      }
151    }
152
153    public IEnumerable<SymbolicExpressionTreeNode> IterateNodesPostfix() {
154      if (postfixForm == null) {
155        postfixForm = new List<SymbolicExpressionTreeNode>(200);
156        ForEachNodePostfix(x => postfixForm.Add(x));
157      }
158      return postfixForm;
159    }
160
161    private void ForEachNodePostfix(Action<SymbolicExpressionTreeNode> a) {
162      for (int i = 0; i < SubTrees.Count; i++) {
163        SubTrees[i].ForEachNodePrefix(a);
164      }
165      a(this);
166    }
167
168    public IEnumerable<Symbol> GetAllowedSymbols(int argumentIndex) {
169      return Grammar.Symbols.Where(s => Grammar.IsAllowedChild(Symbol, s, argumentIndex));
170    }
171    public int GetMinSubtreeCount() {
172      return Grammar.GetMinSubtreeCount(Symbol);
173    }
174    public int GetMaxSubtreeCount() {
175      return Grammar.GetMaxSubtreeCount(Symbol);
176    }
177
178    #region ICloneable Members
179
180    public virtual object Clone() {
181      return new SymbolicExpressionTreeNode(this);
182    }
183
184    #endregion
185
186    public override string ToString() {
187      return Symbol.Name;
188    }
189
190    private void ResetCachedValues() {
191      size = 0; height = 0;
192      prefixForm = null; postfixForm = null;
193      if (parent != null) parent.ResetCachedValues();
194    }
195  }
196}
Note: See TracBrowser for help on using the repository browser.